feat(studio): add DoRA support to studio (#7315)

* feat(studio): add DoRA support to studio

* fix: added use_dora fast encoder LoraConfig and gated use_dora on AdapterMethod

* fix(studio) serverside normalization for use_dora=true - add note documenting use_dora is silently dropped on diffusion

* fix: dora button disabled on mac, add preflight guard on GGUF lora export, mismatch now correctly falls through to existing error instead of silently no-opping

* Studio: add dora to the WizardState LoRA variant union for consistency

* Reject --use_dora on the MLX (Apple Silicon) CLI path

---------

Co-authored-by: danielhanchen <unslothai@gmail.com>
This commit is contained in:
Lionel Arce 2026-07-24 07:24:16 -03:00 committed by GitHub
commit a1907fd4fe
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
113 changed files with 219 additions and 11 deletions

View file

@ -30,6 +30,7 @@ lora:
vision_all_linear: false
use_rslora: false
use_loftq: false
use_dora: false
finetune_vision_layers: true
finetune_language_layers: true
finetune_attention_modules: true

View file

@ -30,6 +30,7 @@ lora:
vision_all_linear: false
use_rslora: false
use_loftq: false
use_dora: false
finetune_vision_layers: true
finetune_language_layers: true
finetune_attention_modules: true

View file

@ -33,6 +33,7 @@ lora:
- "down_proj"
use_rslora: false
use_loftq: false
use_dora: false
finetune_vision_layers: true
finetune_language_layers: true
finetune_attention_modules: true

View file

@ -34,6 +34,7 @@ lora:
- "down_proj"
use_rslora: false
use_loftq: false
use_dora: false
logging:
enable_wandb: false

View file

@ -30,6 +30,7 @@ lora:
- "query"
use_rslora: false
use_loftq: false
use_dora: false
logging:
enable_wandb: false

View file

@ -30,6 +30,7 @@ lora:
- "value"
use_rslora: false
use_loftq: false
use_dora: false
logging:
enable_wandb: false

View file

@ -33,6 +33,7 @@ lora:
- "down_proj"
use_rslora: false
use_loftq: false
use_dora: false
logging:
enable_wandb: false

View file

@ -29,6 +29,7 @@ lora:
- "Wqkv"
use_rslora: false
use_loftq: false
use_dora: false
logging:
enable_wandb: false

View file

@ -34,6 +34,7 @@ lora:
- "down_proj"
use_rslora: false
use_loftq: false
use_dora: false
logging:
enable_wandb: false

View file

@ -35,6 +35,7 @@ lora:
- "down_proj"
use_rslora: false
use_loftq: false
use_dora: false
finetune_vision_layers: true
finetune_language_layers: true
finetune_attention_modules: true

View file

@ -34,6 +34,7 @@ lora:
- "down_proj"
use_rslora: false
use_loftq: false
use_dora: false
logging:
enable_wandb: false

View file

@ -35,6 +35,7 @@ lora:
- "down_proj"
use_rslora: false
use_loftq: false
use_dora: false
logging:
enable_wandb: false

View file

@ -35,6 +35,7 @@ lora:
- "down_proj"
use_rslora: false
use_loftq: false
use_dora: false
logging:
enable_wandb: false

View file

@ -33,6 +33,7 @@ lora:
- "down_proj"
use_rslora: false
use_loftq: false
use_dora: false
logging:
enable_wandb: false

View file

@ -34,6 +34,7 @@ lora:
- "down_proj"
use_rslora: false
use_loftq: false
use_dora: false
logging:
enable_wandb: false

View file

@ -35,6 +35,7 @@ lora:
- "down_proj"
use_rslora: false
use_loftq: false
use_dora: false
logging:
enable_wandb: false

View file

@ -29,6 +29,7 @@ lora:
- "all-linear"
use_rslora: false
use_loftq: false
use_dora: false
finetune_vision_layers: true
finetune_language_layers: true
finetune_attention_modules: true

View file

@ -29,6 +29,7 @@ lora:
- "all-linear"
use_rslora: false
use_loftq: false
use_dora: false
finetune_vision_layers: true
finetune_language_layers: true
finetune_attention_modules: true

View file

@ -29,6 +29,7 @@ lora:
- "all-linear"
use_rslora: false
use_loftq: false
use_dora: false
finetune_vision_layers: true
finetune_language_layers: true
finetune_attention_modules: true

View file

@ -29,6 +29,7 @@ lora:
- "all-linear"
use_rslora: false
use_loftq: false
use_dora: false
finetune_vision_layers: true
finetune_language_layers: true
finetune_attention_modules: true

View file

@ -29,6 +29,7 @@ lora:
- "all-linear"
use_rslora: false
use_loftq: false
use_dora: false
finetune_vision_layers: true
finetune_language_layers: true
finetune_attention_modules: true

View file

@ -26,6 +26,7 @@ lora:
- "all-linear"
use_rslora: false
use_loftq: false
use_dora: false
finetune_vision_layers: true
finetune_language_layers: true
finetune_attention_modules: true

View file

@ -26,6 +26,7 @@ lora:
- "all-linear"
use_rslora: false
use_loftq: false
use_dora: false
finetune_vision_layers: true
finetune_language_layers: true
finetune_attention_modules: true

View file

@ -26,6 +26,7 @@ lora:
- "all-linear"
use_rslora: false
use_loftq: false
use_dora: false
finetune_vision_layers: true
finetune_language_layers: true
finetune_attention_modules: true

View file

@ -26,6 +26,7 @@ lora:
- "all-linear"
use_rslora: false
use_loftq: false
use_dora: false
finetune_vision_layers: true
finetune_language_layers: true
finetune_attention_modules: true

View file

@ -26,6 +26,7 @@ lora:
- "all-linear"
use_rslora: false
use_loftq: false
use_dora: false
finetune_vision_layers: true
finetune_language_layers: true
finetune_attention_modules: true

View file

@ -26,6 +26,7 @@ lora:
- "all-linear"
use_rslora: false
use_loftq: false
use_dora: false
finetune_vision_layers: true
finetune_language_layers: true
finetune_attention_modules: true

View file

@ -26,6 +26,7 @@ lora:
- "all-linear"
use_rslora: false
use_loftq: false
use_dora: false
finetune_vision_layers: true
finetune_language_layers: true
finetune_attention_modules: true

View file

@ -26,6 +26,7 @@ lora:
- "all-linear"
use_rslora: false
use_loftq: false
use_dora: false
finetune_vision_layers: true
finetune_language_layers: true
finetune_attention_modules: true

View file

@ -35,6 +35,7 @@ lora:
- "down_proj"
use_rslora: false
use_loftq: false
use_dora: false
logging:
enable_wandb: false

View file

@ -35,6 +35,7 @@ lora:
- "down_proj"
use_rslora: false
use_loftq: false
use_dora: false
logging:
enable_wandb: false

View file

@ -37,6 +37,7 @@ lora:
- "shared_mlp.output_linear"
use_rslora: false
use_loftq: false
use_dora: false
logging:
enable_wandb: false

View file

@ -37,6 +37,7 @@ lora:
- "shared_mlp.output_linear"
use_rslora: false
use_loftq: false
use_dora: false
logging:
enable_wandb: false

View file

@ -29,6 +29,7 @@ lora:
- "all-linear"
use_rslora: false
use_loftq: false
use_dora: false
finetune_vision_layers: true
finetune_language_layers: true
finetune_attention_modules: true

View file

@ -34,6 +34,7 @@ lora:
- "down_proj"
use_rslora: false
use_loftq: false
use_dora: false
logging:
enable_wandb: false

View file

@ -35,6 +35,7 @@ lora:
- "down_proj"
use_rslora: false
use_loftq: false
use_dora: false
logging:
enable_wandb: false

View file

@ -35,6 +35,7 @@ lora:
- "down_proj"
use_rslora: false
use_loftq: false
use_dora: false
logging:
enable_wandb: false

View file

@ -34,6 +34,7 @@ lora:
- "down_proj"
use_rslora: false
use_loftq: false
use_dora: false
logging:
enable_wandb: false

View file

@ -34,6 +34,7 @@ lora:
- "down_proj"
use_rslora: false
use_loftq: false
use_dora: false
logging:
enable_wandb: false

View file

@ -34,6 +34,7 @@ lora:
- "down_proj"
use_rslora: false
use_loftq: false
use_dora: false
logging:
enable_wandb: false

View file

@ -34,6 +34,7 @@ lora:
- "down_proj"
use_rslora: false
use_loftq: false
use_dora: false
logging:
enable_wandb: false

View file

@ -30,6 +30,7 @@ lora:
- "v_proj"
use_rslora: false
use_loftq: false
use_dora: false
logging:
enable_wandb: false

View file

@ -35,6 +35,7 @@ lora:
- "down_proj"
use_rslora: false
use_loftq: false
use_dora: false
finetune_vision_layers: true
finetune_language_layers: true
finetune_attention_modules: true

View file

@ -35,6 +35,7 @@ lora:
- "down_proj"
use_rslora: false
use_loftq: false
use_dora: false
finetune_vision_layers: true
finetune_language_layers: true
finetune_attention_modules: true

View file

@ -34,6 +34,7 @@ lora:
- "down_proj"
use_rslora: false
use_loftq: false
use_dora: false
logging:
enable_wandb: false

View file

@ -34,6 +34,7 @@ lora:
- "down_proj"
use_rslora: false
use_loftq: false
use_dora: false
logging:
enable_wandb: false

View file

@ -29,6 +29,7 @@ lora:
- "all-linear"
use_rslora: false
use_loftq: false
use_dora: false
finetune_vision_layers: true
finetune_language_layers: true
finetune_attention_modules: false

View file

@ -34,6 +34,7 @@ lora:
- "down_proj"
use_rslora: false
use_loftq: false
use_dora: false
logging:
enable_wandb: false

View file

@ -33,6 +33,7 @@ lora:
- "down_proj"
use_rslora: false
use_loftq: false
use_dora: false
logging:
enable_wandb: false

View file

@ -33,6 +33,7 @@ lora:
- "v_proj"
use_rslora: false
use_loftq: false
use_dora: false
logging:
enable_wandb: false

View file

@ -38,6 +38,7 @@ lora:
- "down_proj"
use_rslora: false
use_loftq: false
use_dora: false
logging:
enable_wandb: false

View file

@ -37,6 +37,7 @@ lora:
- "down_proj"
use_rslora: false
use_loftq: false
use_dora: false
logging:
enable_wandb: false

View file

@ -35,6 +35,7 @@ lora:
- "out_proj"
use_rslora: false
use_loftq: false
use_dora: false
logging:
enable_wandb: false

View file

@ -29,6 +29,7 @@ lora:
- "all-linear"
use_rslora: false
use_loftq: false
use_dora: false
logging:
enable_wandb: false

View file

@ -37,6 +37,7 @@ lora:
- "out_proj"
use_rslora: false
use_loftq: false
use_dora: false
logging:
enable_wandb: false

View file

@ -35,6 +35,7 @@ lora:
- "down_proj"
use_rslora: false
use_loftq: false
use_dora: false
finetune_vision_layers: true
finetune_language_layers: true
finetune_attention_modules: true

View file

@ -33,6 +33,7 @@ lora:
- "down_proj"
use_rslora: false
use_loftq: false
use_dora: false
logging:
enable_wandb: false

View file

@ -38,6 +38,7 @@ lora:
- "down_proj"
use_rslora: false
use_loftq: false
use_dora: false
logging:
enable_wandb: false

View file

@ -34,6 +34,7 @@ lora:
- "down_proj"
use_rslora: false
use_loftq: false
use_dora: false
logging:
enable_wandb: false

View file

@ -33,6 +33,7 @@ lora:
- "v_proj"
use_rslora: false
use_loftq: false
use_dora: false
logging:
enable_wandb: false

View file

@ -34,6 +34,7 @@ lora:
- "down_proj"
use_rslora: false
use_loftq: false
use_dora: false
logging:
enable_wandb: false

View file

@ -34,6 +34,7 @@ lora:
- "down_proj"
use_rslora: false
use_loftq: false
use_dora: false
logging:
enable_wandb: false

View file

@ -35,6 +35,7 @@ lora:
- "down_proj"
use_rslora: false
use_loftq: false
use_dora: false
logging:
enable_wandb: false

View file

@ -36,6 +36,7 @@ lora:
- "gate_up_proj"
use_rslora: false
use_loftq: false
use_dora: false
logging:
enable_wandb: false

View file

@ -34,6 +34,7 @@ lora:
- "down_proj"
use_rslora: false
use_loftq: false
use_dora: false
logging:
enable_wandb: false

View file

@ -29,6 +29,7 @@ lora:
- "all-linear"
use_rslora: false
use_loftq: false
use_dora: false
finetune_vision_layers: true
finetune_language_layers: true
finetune_attention_modules: true

View file

@ -34,6 +34,7 @@ lora:
- "down_proj"
use_rslora: false
use_loftq: false
use_dora: false
logging:
enable_wandb: false

View file

@ -34,6 +34,7 @@ lora:
- "down_proj"
use_rslora: false
use_loftq: false
use_dora: false
logging:
enable_wandb: false

View file

@ -34,6 +34,7 @@ lora:
- "down_proj"
use_rslora: false
use_loftq: false
use_dora: false
logging:
enable_wandb: false

View file

@ -35,6 +35,7 @@ lora:
- "down_proj"
use_rslora: false
use_loftq: false
use_dora: false
logging:
enable_wandb: false

View file

@ -34,6 +34,7 @@ lora:
- "down_proj"
use_rslora: false
use_loftq: false
use_dora: false
logging:
enable_wandb: false

View file

@ -29,6 +29,7 @@ lora:
- "all-linear"
use_rslora: false
use_loftq: false
use_dora: false
finetune_vision_layers: true
finetune_language_layers: true
finetune_attention_modules: true

View file

@ -35,6 +35,7 @@ lora:
- "down_proj"
use_rslora: false
use_loftq: false
use_dora: false
logging:
enable_wandb: false

View file

@ -35,6 +35,7 @@ lora:
- "down_proj"
use_rslora: false
use_loftq: false
use_dora: false
logging:
enable_wandb: false

View file

@ -35,6 +35,7 @@ lora:
- "down_proj"
use_rslora: false
use_loftq: false
use_dora: false
logging:
enable_wandb: false

View file

@ -36,6 +36,7 @@ lora:
- "gate_up_proj"
use_rslora: false
use_loftq: false
use_dora: false
logging:
enable_wandb: false

View file

@ -35,6 +35,7 @@ lora:
- "down_proj"
use_rslora: false
use_loftq: false
use_dora: false
logging:
enable_wandb: false

View file

@ -35,6 +35,7 @@ lora:
- "down_proj"
use_rslora: false
use_loftq: false
use_dora: false
logging:
enable_wandb: false

View file

@ -35,6 +35,7 @@ lora:
- "down_proj"
use_rslora: false
use_loftq: false
use_dora: false
logging:
enable_wandb: false

View file

@ -29,6 +29,7 @@ lora:
- "all-linear"
use_rslora: false
use_loftq: false
use_dora: false
finetune_vision_layers: true
finetune_language_layers: true
finetune_attention_modules: true

View file

@ -30,6 +30,7 @@ lora:
vision_all_linear: true
use_rslora: false
use_loftq: false
use_dora: false
finetune_vision_layers: true
finetune_language_layers: true
finetune_attention_modules: true

View file

@ -1048,6 +1048,21 @@ class ExportBackend:
"Use the safetensors adapter instead.",
None,
)
# llama.cpp's convert_lora_to_gguf.py has no concept of DoRA's
# lora_magnitude_vector tensors: it only reads the standard
# lora_A/lora_B delta, so exporting a DoRA adapter would silently
# drop the magnitude rescaling and produce a GGUF LoRA file that
# loads fine but no longer matches the trained model.
_peft_config = getattr(self.current_model, "peft_config", {}).get("default")
if getattr(_peft_config, "use_dora", False):
return (
False,
"GGUF LoRA export is not supported for DoRA adapters: the GGUF LoRA "
"format has no way to represent DoRA's magnitude vectors, so the "
"exported file would silently lose the DoRA behavior. Use the "
"safetensors adapter instead, or merge to a full GGUF model.",
None,
)
outtype = str(gguf_outtype).lower()
if outtype not in _GGUF_LORA_OUTTYPES:
return (

View file

@ -891,6 +891,7 @@ class UnslothTrainer:
use_gradient_checkpointing: str = "unsloth",
use_rslora: bool = False,
use_loftq: bool = False,
use_dora: bool = False,
modules_to_save: list = None,
) -> bool:
"""
@ -993,6 +994,7 @@ class UnslothTrainer:
use_gradient_checkpointing = use_gradient_checkpointing,
random_state = 3407,
use_rslora = use_rslora,
use_dora = use_dora,
loftq_config = {"loftq_bits": 4, "loftq_iter": 1} if use_loftq else None,
)
# Audio VLM models support VLM-style layer selection
@ -1023,6 +1025,7 @@ class UnslothTrainer:
use_gradient_checkpointing = use_gradient_checkpointing,
random_state = 3407,
use_rslora = use_rslora,
use_dora = use_dora,
loftq_config = {"loftq_bits": 4, "loftq_iter": 1} if use_loftq else None,
task_type = None,
)
@ -1042,6 +1045,7 @@ class UnslothTrainer:
use_gradient_checkpointing = use_gradient_checkpointing,
random_state = 3407,
use_rslora = use_rslora,
use_dora = use_dora,
loftq_config = {"loftq_bits": 4, "loftq_iter": 1} if use_loftq else None,
)
@ -1067,6 +1071,7 @@ class UnslothTrainer:
use_gradient_checkpointing = use_gradient_checkpointing,
random_state = 3407,
use_rslora = use_rslora,
use_dora = use_dora,
loftq_config = {"loftq_bits": 4, "loftq_iter": 1} if use_loftq else None,
modules_to_save = modules_to_save,
)
@ -1087,6 +1092,7 @@ class UnslothTrainer:
use_gradient_checkpointing = use_gradient_checkpointing,
random_state = 3407,
use_rslora = use_rslora,
use_dora = use_dora,
loftq_config = {"loftq_bits": 4, "loftq_iter": 1} if use_loftq else None,
modules_to_save = modules_to_save,
)

View file

@ -196,6 +196,7 @@ def _build_training_worker_config(values: dict[str, Any]) -> dict[str, Any]:
"gradient_checkpointing": values.get("gradient_checkpointing", "unsloth"),
"use_rslora": values.get("use_rslora", False),
"use_loftq": values.get("use_loftq", False),
"use_dora": values.get("use_dora", False),
"train_on_completions": values.get("train_on_completions", False),
"finetune_vision_layers": values.get("finetune_vision_layers", True),
"finetune_language_layers": values.get("finetune_language_layers", True),
@ -455,6 +456,7 @@ class _MLXTrainerAdapter:
use_gradient_checkpointing: Union[str, bool] = "unsloth",
use_rslora: bool = False,
use_loftq: bool = False,
use_dora: bool = False,
) -> bool:
self._peft_config = {
"use_lora": bool(use_lora),
@ -465,6 +467,7 @@ class _MLXTrainerAdapter:
"gradient_checkpointing": use_gradient_checkpointing,
"use_rslora": bool(use_rslora),
"use_loftq": bool(use_loftq),
"use_dora": bool(use_dora),
"finetune_vision_layers": bool(finetune_vision_layers),
"finetune_language_layers": bool(finetune_language_layers),
"finetune_attention_modules": bool(finetune_attention_modules),
@ -572,6 +575,7 @@ class _MLXTrainerAdapter:
"gradient_checkpointing": "unsloth",
"use_rslora": False,
"use_loftq": False,
"use_dora": False,
"finetune_vision_layers": True,
"finetune_language_layers": True,
"finetune_attention_modules": True,

View file

@ -1547,6 +1547,10 @@ def _run_mlx_training(event_queue, stop_queue, config):
message = "LoftQ is not supported for MLX training yet."
_send("error", error = message)
raise NotImplementedError(message)
if config.get("use_dora"):
message = "DoRA is not supported for MLX training yet."
_send("error", error = message)
raise NotImplementedError(message)
if config.get("is_embedding"):
message = "Embedding model training is not supported for MLX training yet."
_send("error", error = message)
@ -3186,6 +3190,7 @@ def run_training_process(*, event_queue: Any, stop_queue: Any, config: dict) ->
use_gradient_checkpointing = config.get("gradient_checkpointing", "unsloth"),
use_rslora = config.get("use_rslora", False),
use_loftq = config.get("use_loftq", False),
use_dora = config.get("use_dora", False),
)
elif use_lora:
_send_status(event_queue, "Configuring LoRA adapters...")
@ -3202,6 +3207,7 @@ def run_training_process(*, event_queue: Any, stop_queue: Any, config: dict) ->
use_gradient_checkpointing = config.get("gradient_checkpointing", "unsloth"),
use_rslora = config.get("use_rslora", False),
use_loftq = config.get("use_loftq", False),
use_dora = config.get("use_dora", False),
)
else:
_send_status(event_queue, "Preparing model for full finetuning...")
@ -3630,6 +3636,7 @@ def _run_embedding_training(event_queue: Any, stop_queue: Any, config: dict) ->
use_gradient_checkpointing = gradient_checkpointing,
random_state = config.get("random_seed", 3407),
use_rslora = config.get("use_rslora", False),
use_dora = config.get("use_dora", False),
loftq_config = {"loftq_bits": 4, "loftq_iter": 1}
if config.get("use_loftq")
else None,

View file

@ -470,6 +470,7 @@ class TrainingStartRequest(BaseModel):
gradient_checkpointing: str = Field("", description = "Gradient checkpointing setting")
use_rslora: bool = Field(False, description = "Use RSLoRA")
use_loftq: bool = Field(False, description = "Use LoftQ")
use_dora: bool = Field(False, description = "Use DoRA")
train_on_completions: bool = Field(False, description = "Train on completions only")
# Vision-specific LoRA parameters
@ -545,6 +546,37 @@ class TrainingStartRequest(BaseModel):
raise ValueError("Either num_epochs or max_steps must be > 0; both cannot be 0.")
return self
@model_validator(mode = "after")
def _validate_lora_variant_flags(self) -> "TrainingStartRequest":
# The frontend only ever sends one of these and never under Full
# Finetuning, but a direct API/YAML/CLI caller can bypass that. Nothing
# downstream breaks (full finetune ignores them, MLX rejects use_dora/
# use_loftq outright), but reject early here for a clear error instead
# of a silently-ignored flag.
active = [
name
for name, enabled in (
("use_rslora", self.use_rslora),
("use_loftq", self.use_loftq),
("use_dora", self.use_dora),
)
if enabled
]
if len(active) > 1:
raise ValueError(
f"Only one LoRA variant may be enabled at a time; got {active}. "
"use_rslora, use_loftq, and use_dora are mutually exclusive."
)
# getattr, not self.training_type: model_construct() (used by tests that
# validate a single field in isolation) leaves required fields unset, and
# this is a mode="after" validator so it still runs on that partial instance.
if getattr(self, "training_type", None) == "Full Finetuning" and active:
raise ValueError(
f"{active[0]} requires an adapter method (LoRA/QLoRA or "
"Continued Pretraining); it has no effect under Full Finetuning."
)
return self
class TrainingJobResponse(BaseModel):
"""Immediate response when training is initiated"""

View file

@ -332,6 +332,7 @@ async def start_training(
else "unsloth",
"use_rslora": request.use_rslora,
"use_loftq": request.use_loftq,
"use_dora": request.use_dora,
"train_on_completions": request.train_on_completions,
"finetune_vision_layers": request.finetune_vision_layers,
"finetune_language_layers": request.finetune_language_layers,

View file

@ -105,5 +105,6 @@ def test_shared_mapper_matches_backend_config_keys():
"lora_dropout",
"use_rslora",
"use_loftq",
"use_dora",
):
assert key in src, f"run-config mapper lost backend key {key}"

View file

@ -217,10 +217,16 @@ export function ParamsSection(): ReactElement {
const selectedOptimizer =
isMac && isCudaAliasOptimizer ? "adamw" : store.optimizerType;
// LoftQ is unsupported on MLX; clear a stale selection to lora on Apple Silicon.
// LoftQ and DoRA are not supported on MLX (the backend rejects both), so
// clear a stale selection to lora on Apple Silicon -- whether persisted,
// applied from a model default, or imported -- so the backend never
// receives it.
const setLoraVariant = store.setLoraVariant;
useEffect(() => {
if (isMac && store.loraVariant === "loftq") {
if (
isMac &&
(store.loraVariant === "loftq" || store.loraVariant === "dora")
) {
setLoraVariant("lora");
}
}, [isMac, store.loraVariant, setLoraVariant]);
@ -712,7 +718,7 @@ export function ParamsSection(): ReactElement {
)}
{/* LoRA variant */}
<div className="flex gap-2">
<div className="grid grid-cols-2 gap-2">
{(
[
{
@ -730,12 +736,20 @@ export function ParamsSection(): ReactElement {
label: "LoftQ",
desc: t("studio.params.memoryEfficient"),
},
{
value: "dora",
label: "DoRA",
desc: t("studio.params.weightDecomposed"),
},
] as const
).map((opt) => (
<button
key={opt.value}
type="button"
disabled={isMac && opt.value === "loftq"}
disabled={
isMac &&
(opt.value === "loftq" || opt.value === "dora")
}
onClick={() => store.setLoraVariant(opt.value)}
className={`flex-1 corner-squircle rounded-xl border px-3 py-2 text-left transition-colors cursor-pointer disabled:cursor-not-allowed disabled:opacity-60 ${
store.loraVariant === opt.value
@ -745,7 +759,7 @@ export function ParamsSection(): ReactElement {
>
<p className="text-xs font-medium">{opt.label}</p>
<p className="text-ui-10 text-muted-foreground">
{isMac && opt.value === "loftq"
{isMac && (opt.value === "loftq" || opt.value === "dora")
? "Not supported on Apple Silicon"
: opt.desc}
</p>

View file

@ -49,6 +49,8 @@ export function mapRunConfigToOverride(
? "rslora"
: config.use_loftq
? "loftq"
: config.use_dora
? "dora"
: "lora",
};
}

View file

@ -125,8 +125,9 @@ export function buildTrainingStartPayload(
lora_dropout: config.loraDropout,
target_modules: adapterMethod ? config.targetModules : [],
gradient_checkpointing: config.gradientCheckpointing,
use_rslora: config.loraVariant === "rslora",
use_loftq: config.loraVariant === "loftq",
use_rslora: adapterMethod && config.loraVariant === "rslora",
use_loftq: adapterMethod && config.loraVariant === "loftq",
use_dora: adapterMethod && config.loraVariant === "dora",
// CPT always trains on full sequences (no chat format masking)
train_on_completions: (isEmbedding || isCpt || isRawText) ? false : config.trainOnCompletions,
finetune_vision_layers: config.finetuneVisionLayers,

View file

@ -42,6 +42,7 @@ interface BackendLoraDefaults {
target_modules?: string[];
use_rslora?: boolean;
use_loftq?: boolean;
use_dora?: boolean;
finetune_vision_layers?: boolean;
finetune_language_layers?: boolean;
finetune_attention_modules?: boolean;

View file

@ -181,6 +181,7 @@ export function mapBackendModelConfigToTrainingPatch(
if (lora?.use_loftq === true) patch.loraVariant = "loftq";
else if (lora?.use_rslora === true) patch.loraVariant = "rslora";
else if (lora?.use_dora === true) patch.loraVariant = "dora";
else if (lora) patch.loraVariant = "lora";
const finetuneVisionLayers = toBoolean(lora?.finetune_vision_layers);

View file

@ -69,6 +69,7 @@ export function serializeConfigToYaml(
target_modules: state.targetModules,
use_rslora: state.loraVariant === "rslora",
use_loftq: state.loraVariant === "loftq",
use_dora: state.loraVariant === "dora",
};
if (includeVisionFields) {

View file

@ -54,6 +54,7 @@ export interface TrainingStartRequest {
gradient_checkpointing: string;
use_rslora: boolean;
use_loftq: boolean;
use_dora: boolean;
train_on_completions: boolean;
finetune_vision_layers: boolean;
finetune_language_layers: boolean;

View file

@ -12,7 +12,7 @@ import type {
} from "@/types/training";
import type { BackendModelConfig } from "../api/models-api";
export type LoraVariant = "lora" | "rslora" | "loftq";
export type LoraVariant = "lora" | "rslora" | "loftq" | "dora";
/** Column-to-role mapping, e.g. { "problem": "user", "solution": "assistant", "context": "system" } */
export type DatasetManualMapping = Record<string, string>;

View file

@ -752,6 +752,7 @@ export const ar = {
trainWithLora: "التدريب باستخدام LoRA",
stableRank: "Rank مستقر",
memoryEfficient: "موفّر للذاكرة",
weightDecomposed: "أوزان مُفكَّكة",
optimization: "التحسين",
schedule: "الجدولة",
memory: "الذاكرة",

View file

@ -781,6 +781,7 @@ export const de = {
trainWithLora: "Mit LoRA trainieren",
stableRank: "Stable Rank",
memoryEfficient: "Speichereffizient",
weightDecomposed: "Gewichtszerlegt",
optimization: "Optimierung",
schedule: "Zeitplan",
memory: "Speicher",

View file

@ -1045,6 +1045,7 @@ export const en = {
trainWithLora: "Train with LoRA",
stableRank: "Stable Rank",
memoryEfficient: "Memory Efficient",
weightDecomposed: "Weight-Decomposed",
optimization: "Optimization",
schedule: "Schedule",
memory: "Memory",

View file

@ -780,6 +780,7 @@ export const es = {
trainWithLora: "Entrenar con LoRA",
stableRank: "Rango estable",
memoryEfficient: "Eficiente en memoria",
weightDecomposed: "Pesos descompuestos",
optimization: "Optimización",
schedule: "Programación",
memory: "Memoria",

Some files were not shown because too many files have changed in this diff Show more