{"record":{"id":"194cc4775debb17d","repo":"unslothai/unsloth","slug":"lora-rank-must-be-1","errorCode":null,"errorMessage":"lora_rank must be >= 1","messagePattern":"lora_rank must be >= 1","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"studio/backend/core/training/diffusion_train_common.py","lineNumber":1016,"sourceCode":"    resolved_family: str = \"sdxl\"\n\n    def normalized(self) -> \"DiffusionLoraConfig\":\n        \"\"\"Return a copy with derived/validated fields filled in. Raises ValueError on a\n        request that cannot train (bad numbers, or an untrainable base model).\n\n        Also coerces values that arrive as strings/blanks through the Studio config path\n        (``learning_rate`` is preserved as a string there; ``hf_token`` defaults to \"\").\"\"\"\n        resolved_family = resolve_trainable_family(self.base_model, self.model_family)\n        if self.train_steps < 1:\n            raise ValueError(\"train_steps must be >= 1\")\n        if not 0 <= int(self.num_epochs) <= 1000:\n            raise ValueError(\"num_epochs must be between 0 and 1000 (0 uses train_steps)\")\n        if self.train_batch_size < 1:\n            raise ValueError(\"train_batch_size must be >= 1\")\n        if self.gradient_accumulation_steps < 1:\n            raise ValueError(\"gradient_accumulation_steps must be >= 1\")\n        if self.lora_rank < 1:\n            raise ValueError(\"lora_rank must be >= 1\")\n        if self.lora_alpha is not None and self.lora_alpha < 1:\n            raise ValueError(\n                \"lora_alpha must be >= 1 (a zero/negative alpha scales the adapter to nothing)\"\n            )\n        if self.resolution < 64 or self.resolution % 8 != 0:\n            raise ValueError(\"resolution must be a multiple of 8 and >= 64\")\n        # A video family's VAE compresses space by 32, so an off-grid resolution changes the\n        # latent geometry silently. Refuse it here, before the GPU models are evicted.\n        if (\n            resolved_family in TRAINABLE_VIDEO_FAMILIES\n            and self.resolution % _VIDEO_RESOLUTION_MULTIPLE != 0\n        ):\n            raise ValueError(\n                f\"'{resolved_family}' trains at a resolution that is a multiple of \"\n                f\"{_VIDEO_RESOLUTION_MULTIPLE} (its VAE compresses space by that factor); \"\n                f\"got {self.resolution}.\"\n            )\n        if self.mixed_precision not in (\"bf16\", \"fp16\", \"no\"):","sourceCodeStart":998,"sourceCodeEnd":1034,"githubUrl":"https://github.com/unslothai/unsloth/blob/203007d19051dcd2ae33876786d117c99f6b0368/studio/backend/core/training/diffusion_train_common.py#L998-L1034","documentation":"The training-config validator rejected lora_rank < 1. LoRA rank determines the dimensionality of the low-rank adapter matrices; rank 0 or negative has no mathematical meaning and would produce empty/negative-shaped tensors deep in the trainer. It is checked up front so the request fails before GPU models are evicted.","triggerScenarios":"A training request with lora_rank = 0, a negative integer, or a coerced string ('0', '', '-4'). Commonly triggered from auto-tuning scripts that sweep ranks and include an invalid bound, or forms defaulting to 0.","commonSituations":"Hyperparameter sweeps that include rank 0 as a 'no LoRA' baseline; hand-edited config files; UI numeric inputs that default to 0; porting configs from tutorials that use rank as a boolean-like switch.","solutions":["Set lora_rank to a positive integer (typical values: 8, 16, 32, 64).","If you meant 'train without LoRA', that is not expressed via rank — use the appropriate full-finetune flag instead of rank 0.","Sanitize sweep grids to exclude non-positive ranks before submitting jobs."],"exampleFix":"# before\nconfig = TrainConfig(lora_rank=0)\n\n# after\nconfig = TrainConfig(lora_rank=16)","handlingStrategy":"validation","validationCode":"def check_lora_rank(v) -> int:\n    n = int(v) if v not in (None, \"\") else 16\n    if n < 1:\n        raise ValueError(f\"lora_rank must be >= 1, got {v!r}\")\n    return n","typeGuard":"def is_valid_lora_rank(v) -> bool:\n    try:\n        return int(v) >= 1\n    except (TypeError, ValueError):\n        return False","tryCatchPattern":"try:\n    session.submit_training(config)\nexcept ValueError as e:\n    if \"lora_rank\" in str(e):\n        config.lora_rank = 16  # safe default\n        session.submit_training(config)\n    else:\n        raise","preventionTips":["Constrain sweep grids to positive integers (8/16/32/64).","Use a dropdown of standard ranks in UIs instead of free numeric input.","Remember rank 0 is not a 'no LoRA' switch in this API."],"tags":["training","lora","configuration","validation"],"backgroundTag":null,"analyzedSha":"203007d19051dcd2ae33876786d117c99f6b0368","analyzedAt":"2026-08-15T02:48:39.846Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}