{"record":{"id":"4ffecc8a09fec0ce","repo":"unslothai/unsloth","slug":"base-precision-base-precision-r-trains-in-bf16-c","errorCode":null,"errorMessage":"base_precision={base_precision!r} trains in bf16 compute; set mixed_precision to bf16.","messagePattern":"base_precision=(.+?) trains in bf16 compute; set mixed_precision to bf16\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"studio/backend/core/training/diffusion_train_common.py","lineNumber":1114,"sourceCode":"        cond_cache_dir = (\n            str(self.cond_cache_dir).strip() if self.cond_cache_dir is not None else \"\"\n        ) or None\n        compile_transformer = str(self.compile_transformer or \"auto\").strip().lower()\n        if compile_transformer not in (\"off\", \"on\", \"auto\"):\n            raise ValueError(\"compile_transformer must be one of off / on / auto\")\n        base_precision = str(self.base_precision or \"nf4\").strip().lower()\n        if base_precision not in (\"nf4\", \"bf16\", \"int8\", \"fp8\", \"mxfp8\", \"auto\"):\n            raise ValueError(\"base_precision must be one of nf4 / bf16 / int8 / fp8 / mxfp8 / auto\")\n        # base_precision is a DiT-only lever, so the dense-mode gates apply only to the DiT families. The mode-name check above still runs for every family.\n        if resolved_family != \"sdxl\" and base_precision in (\"bf16\", \"int8\", \"fp8\", \"mxfp8\"):\n            if repo_is_prequantized(self.base_model):\n                raise ValueError(\n                    f\"base_precision={base_precision!r} needs a dense base repo, but \"\n                    f\"'{self.base_model}' is already bitsandbytes-quantized. Pick the \"\n                    f\"family's dense (bf16) base repo for this mode, or use nf4/auto.\"\n                )\n            if self.mixed_precision != \"bf16\":\n                raise ValueError(\n                    f\"base_precision={base_precision!r} trains in bf16 compute; set \"\n                    f\"mixed_precision to bf16.\"\n                )\n            # Refuse a scheme this family's DiT is known to corrupt, and also one the training bar holds back while\n            # inference allows it: qwen-image fp8 now renders inside the accuracy gate, but no one has measured whether a\n            # LoRA converges against fp8-frozen linears, so it fails fast here rather than silently training on faith.\n            # MiniMax-H3 runs all three modalities through one set of linears, so the\n            # per-family activation range the fp8 module filter was measured against does not\n            # describe it. Refuse the float8 modes rather than train against a clipped forward.\n            if resolved_family == \"minimax-h3\" and base_precision in (\"fp8\", \"mxfp8\"):\n                raise ValueError(\n                    f\"base_precision={base_precision!r} is not supported for minimax-h3: its \"\n                    f\"packed sequence mixes video, audio and text through one set of linears, \"\n                    f\"so the activation range fp8 was measured against does not apply. Use \"\n                    f\"'nf4', 'int8', 'bf16', or 'auto'.\"\n                )\n            # _family_train_denied, not _family_denied: it is the strict superset (every inference\n            # deny plus the training-only ones), so importing the narrower helper here would let a","sourceCodeStart":1096,"sourceCodeEnd":1132,"githubUrl":"https://github.com/unslothai/unsloth/blob/203007d19051dcd2ae33876786d117c99f6b0368/studio/backend/core/training/diffusion_train_common.py#L1096-L1132","documentation":"The LoRA trainer validates base_precision against mixed_precision before building the model. For non-SDXL families, the dense quantization modes (bf16, int8, fp8, mxfp8) train with bf16 compute, so the run refuses to start when mixed_precision is anything other than 'bf16'. This is a preflight guard so the failure happens before resident GPU models are freed and a child trainer process is spawned.","triggerScenarios":"Calling the diffusion training start path with resolved_family != 'sdxl', base_precision set to one of 'bf16'/'int8'/'fp8'/'mxfp8', self.mixed_precision != 'bf16', and a base repo that is not already bitsandbytes-quantized (that earlier check raises a different error). Typical concrete call: DiffusionLoraConfig(base_precision='int8', mixed_precision='fp16') on a qwen-image or flux base.","commonSituations":"Copy-pasting an SDXL-style config (fp16 mixed precision) to a DiT family; switching from nf4 to int8/fp8 to save memory but leaving mixed_precision at its default 'fp16'; Studio UI presets that pair fp8 bases with fp16 compute.","solutions":["Set mixed_precision='bf16' in the training config alongside the dense base_precision mode.","Or keep mixed_precision as-is and fall back to base_precision='nf4' or 'auto', which are not subject to the bf16-compute gate.","Or switch to the family's dense (bf16) base repo if the earlier repo_is_prequantized check was the near-miss; then confirm mixed_precision='bf16'."],"exampleFix":"# before\ncfg = DiffusionLoraConfig(base_model='Qwen/Qwen-Image', base_precision='int8', mixed_precision='fp16')\n# after\ncfg = DiffusionLoraConfig(base_model='Qwen/Qwen-Image', base_precision='int8', mixed_precision='bf16')","handlingStrategy":"validation","validationCode":"def check_precision_pair(base_precision, mixed_precision, family):\n    bp = str(base_precision or 'nf4').strip().lower()\n    if family != 'sdxl' and bp in ('bf16', 'int8', 'fp8', 'mxfp8') and mixed_precision != 'bf16':\n        raise ValueError('set mixed_precision=bf16 for dense base_precision modes')","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Build training configs through one factory that pairs dense base_precision modes with mixed_precision='bf16' automatically.","Surface the base_precision/mixed_precision combination in the UI as a linked control so they cannot disagree."],"tags":["training","config","precision","diffusion","validation"],"backgroundTag":null,"analyzedSha":"203007d19051dcd2ae33876786d117c99f6b0368","analyzedAt":"2026-08-15T02:48:39.846Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}