unslothai/unsloth · error · ValueError
base_precision={base_precision!r} trains in bf16 compute; se
Error message
base_precision={base_precision!r} trains in bf16 compute; set mixed_precision to bf16. What it means
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.
Source
Thrown at studio/backend/core/training/diffusion_train_common.py:1114
cond_cache_dir = (
str(self.cond_cache_dir).strip() if self.cond_cache_dir is not None else ""
) or None
compile_transformer = str(self.compile_transformer or "auto").strip().lower()
if compile_transformer not in ("off", "on", "auto"):
raise ValueError("compile_transformer must be one of off / on / auto")
base_precision = str(self.base_precision or "nf4").strip().lower()
if base_precision not in ("nf4", "bf16", "int8", "fp8", "mxfp8", "auto"):
raise ValueError("base_precision must be one of nf4 / bf16 / int8 / fp8 / mxfp8 / auto")
# 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.
if resolved_family != "sdxl" and base_precision in ("bf16", "int8", "fp8", "mxfp8"):
if repo_is_prequantized(self.base_model):
raise ValueError(
f"base_precision={base_precision!r} needs a dense base repo, but "
f"'{self.base_model}' is already bitsandbytes-quantized. Pick the "
f"family's dense (bf16) base repo for this mode, or use nf4/auto."
)
if self.mixed_precision != "bf16":
raise ValueError(
f"base_precision={base_precision!r} trains in bf16 compute; set "
f"mixed_precision to bf16."
)
# Refuse a scheme this family's DiT is known to corrupt, and also one the training bar holds back while
# inference allows it: qwen-image fp8 now renders inside the accuracy gate, but no one has measured whether a
# LoRA converges against fp8-frozen linears, so it fails fast here rather than silently training on faith.
# MiniMax-H3 runs all three modalities through one set of linears, so the
# per-family activation range the fp8 module filter was measured against does not
# describe it. Refuse the float8 modes rather than train against a clipped forward.
if resolved_family == "minimax-h3" and base_precision in ("fp8", "mxfp8"):
raise ValueError(
f"base_precision={base_precision!r} is not supported for minimax-h3: its "
f"packed sequence mixes video, audio and text through one set of linears, "
f"so the activation range fp8 was measured against does not apply. Use "
f"'nf4', 'int8', 'bf16', or 'auto'."
)
# _family_train_denied, not _family_denied: it is the strict superset (every inference
# deny plus the training-only ones), so importing the narrower helper here would let aView on GitHub (pinned to 203007d190)
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'.
Example fix
# before cfg = DiffusionLoraConfig(base_model='Qwen/Qwen-Image', base_precision='int8', mixed_precision='fp16') # after cfg = DiffusionLoraConfig(base_model='Qwen/Qwen-Image', base_precision='int8', mixed_precision='bf16')
Defensive patterns
Strategy: validation
Validate before calling
def check_precision_pair(base_precision, mixed_precision, family):
bp = str(base_precision or 'nf4').strip().lower()
if family != 'sdxl' and bp in ('bf16', 'int8', 'fp8', 'mxfp8') and mixed_precision != 'bf16':
raise ValueError('set mixed_precision=bf16 for dense base_precision modes') Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- base_precision={base_precision!r} is not supported for minim
- base_precision={base_precision!r} is not validated for train
- base_precision={mode!r} needs a CUDA GPU; this host has none
- gradient_accumulation_steps must be >= 1
- resolution must be a multiple of 8 and >= 64
AI-assisted analysis of unslothai/unsloth@203007d190 (2026-08-15).
Data as JSON: /api/errors/4ffecc8a09fec0ce.
Report an issue: GitHub.