Skip to content

lora

lora

LoRA adaptation helpers for HuggingFace modules.

LoRAAdaptation dataclass

LoRAAdaptation(enabled=False, rank=8, alpha=16, dropout=0.0, target_modules=value, exclude_modules=None, bias='none', init_lora_weights=DEFAULT_LORA_INIT_WEIGHTS)

Runtime configuration for Low-Rank Adaptation.

Parameters:

Name Type Description Default
enabled bool

Whether to wrap the model with LoRA adapters. Disabled configurations leave the original module unchanged.

False
rank int

Adapter rank r. Higher ranks give the adapter more capacity and increase trainable parameters.

8
alpha int

Adapter scaling factor. PEFT applies the learned update with scale alpha / rank, so this controls how strongly the adapter update is added to the base weights.

16
dropout float

Dropout probability on the adapter path. Larger values add regularization before the low-rank update.

0.0
target_modules str

PEFT target-module preset. auto lets PEFT infer supported module names from the model type, all-linear adapts linear layers, and the language-model presets restrict LoRA to text-model projections inside VLM wrappers.

value
exclude_modules list[str] | None

Optional module names to leave unwrapped even if they match the selected target preset.

None
bias str

PEFT bias handling mode.

'none'
init_lora_weights str

PEFT adapter weight initialization strategy passed to LoraConfig. gaussian matches the OpenVLA-OFT recipe.

DEFAULT_LORA_INIT_WEIGHTS

__post_init__

__post_init__()

Validate LoRA hyperparameters.

Source code in src/versatil/models/adaptation/lora.py
def __post_init__(self) -> None:
    """Validate LoRA hyperparameters."""
    if self.rank <= 0:
        raise ValueError(f"LoRA rank must be positive, got {self.rank}.")
    if self.alpha <= 0:
        raise ValueError(f"LoRA alpha must be positive, got {self.alpha}.")
    if not 0.0 <= self.dropout < 1.0:
        raise ValueError(f"LoRA dropout must be in [0, 1), got {self.dropout}.")
    valid_targets = [preset.value for preset in LoRATargetModulePreset]
    if self.target_modules not in valid_targets:
        raise ValueError(
            f"Invalid LoRA target_modules '{self.target_modules}'. "
            f"Must be one of: {valid_targets}."
        )

is_lora_enabled

is_lora_enabled(lora_config)

Return whether LoRA adaptation should wrap a model.

Source code in src/versatil/models/adaptation/lora.py
def is_lora_enabled(lora_config: LoRAAdaptation | None) -> bool:
    """Return whether LoRA adaptation should wrap a model."""
    return lora_config is not None and lora_config.enabled

to_peft_lora_config

to_peft_lora_config(lora_config)

Convert a VersatIL LoRA config to PEFT's LoRA configuration.

Parameters:

Name Type Description Default
lora_config LoRAAdaptation

VersatIL LoRA configuration.

required

Returns:

Type Description
LoraConfig

PEFT LoRA configuration.

Source code in src/versatil/models/adaptation/lora.py
def to_peft_lora_config(lora_config: LoRAAdaptation) -> PeftLoRAConfig:
    """Convert a VersatIL LoRA config to PEFT's LoRA configuration.

    Args:
        lora_config: VersatIL LoRA configuration.

    Returns:
        PEFT LoRA configuration.
    """
    return PeftLoRAConfig(
        r=lora_config.rank,
        lora_alpha=lora_config.alpha,
        lora_dropout=lora_config.dropout,
        target_modules=_to_peft_target_modules(lora_config.target_modules),
        exclude_modules=lora_config.exclude_modules,
        bias=lora_config.bias,
        init_lora_weights=lora_config.init_lora_weights,
    )

apply_lora_config

apply_lora_config(model, lora_config, frozen)

Wrap a HuggingFace module with LoRA adapters when configured.

Parameters:

Name Type Description Default
model Module

HuggingFace module to adapt.

required
lora_config LoRAAdaptation | None

Optional LoRA configuration.

required
frozen bool

Whether the owning wrapper requests a fully frozen model.

required

Returns:

Type Description
Module

The original model when LoRA is disabled, otherwise a PEFT-wrapped model.

Source code in src/versatil/models/adaptation/lora.py
def apply_lora_config(
    model: nn.Module,
    lora_config: LoRAAdaptation | None,
    frozen: bool,
) -> nn.Module:
    """Wrap a HuggingFace module with LoRA adapters when configured.

    Args:
        model: HuggingFace module to adapt.
        lora_config: Optional LoRA configuration.
        frozen: Whether the owning wrapper requests a fully frozen model.

    Returns:
        The original model when LoRA is disabled, otherwise a PEFT-wrapped model.
    """
    if not is_lora_enabled(lora_config=lora_config):
        return model
    if frozen:
        raise ValueError(
            "LoRA adaptation cannot be enabled when frozen=True because LoRA "
            "adds trainable adapter parameters. Set frozen=False to train "
            "adapters, or disable LoRA for a fully frozen model."
        )
    if isinstance(model, PeftModel):
        raise ValueError(
            "LoRA adaptation is already applied to this model. Re-applying "
            "LoRA would add another adapter; instantiate a fresh base model "
            "or unload the existing adapter first."
        )
    return get_peft_model(model, to_peft_lora_config(lora_config=lora_config))