unslothai/unsloth · error · ValueError
base_precision must be one of nf4 / bf16 / int8 / fp8 / mxfp
Error message
base_precision must be one of nf4 / bf16 / int8 / fp8 / mxfp8 / auto
What it means
The validator rejected a base_precision value outside ('nf4', 'bf16', 'int8', 'fp8', 'mxfp8', 'auto'). base_precision selects how the frozen base model's weights are quantized during LoRA training (NF4/INT8/FP8 via bitsandbytes, dense bf16, or 'auto'). The value is strip().lower()-ed first, so this error is purely about an unrecognized name.
Source
Thrown at studio/backend/core/training/diffusion_train_common.py:1104
f"checkpoint bundle. Leave it at 0; the adapter is still saved at the end."
)
try:
ema_decay = float(self.ema_decay or 0.0)
except (TypeError, ValueError) as exc:
raise ValueError(f"ema_decay must be a number, got {self.ema_decay!r}") from exc
# decay = 1.0 would freeze the shadow at its init forever; the update is shadow * decay + param * (1 - decay), so valid decays live in [0, 1).
if not 0.0 <= ema_decay < 1.0:
raise ValueError("ema_decay must be in [0, 1); 0 disables the EMA adapter")
# A blank cond_cache_dir (the Studio default when unset) means "off", not cwd.
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 notView on GitHub (pinned to 203007d190)
Solutions
- Use one of: nf4, bf16, int8, fp8, mxfp8, auto (case-insensitive).
- For 4-bit use 'nf4'; for 8-bit use 'int8'; there is no fp16 option by design.
- If unsure, 'auto' picks a sensible default for the family.
Example fix
# before config = TrainConfig(base_precision='4bit') # after config = TrainConfig(base_precision='nf4')
Defensive patterns
Strategy: validation
Validate before calling
VALID_BASE_PRECISION = {"nf4", "bf16", "int8", "fp8", "mxfp8", "auto"}
def check_base_precision(v) -> str:
s = str(v or "nf4").strip().lower()
alias = {"4bit": "nf4", "nf4": "nf4", "8bit": "int8", "none": "auto"}
s = alias.get(s, s)
if s not in VALID_BASE_PRECISION:
raise ValueError(f"base_precision must be one of {sorted(VALID_BASE_PRECISION)}, got {v!r}")
return s Type guard
def is_valid_base_precision(v) -> bool:
return str(v or "nf4").strip().lower() in {"nf4", "bf16", "int8", "fp8", "mxfp8", "auto"} Try / catch
try:
session.submit_training(config)
except ValueError as e:
if "base_precision must be one of" in str(e):
config.base_precision = "auto"
session.submit_training(config)
else:
raise Prevention
- Keep mixed_precision (compute) and base_precision (weight quantization) straight — fp16 is never a base_precision.
- Use the exact enum names (nf4/int8/fp8/mxfp8/bf16/auto), not GGUF/GPTQ vocabulary.
- Use dropdowns sourced from the validator's allowlist.
When it happens
Trigger: Passing base_precision='fp16' (not supported — fp16 is a compute precision, not a base quantization), '4bit', '8bit', 'q4', 'none', or spellings from other tools (GGUF names, 'awq', 'gptq').
Common situations: Copying quantization vocabulary from llama.cpp/GGUF or autogptq configs; confusion between mixed_precision (compute) and base_precision (weight storage); UI free-text entry.
Related errors
- base_precision={base_precision!r} needs a dense base repo, b
- gradient_accumulation_steps must be >= 1
- lora_rank must be >= 1
- lora_alpha must be >= 1 (a zero/negative alpha scales the ad
- resolution must be a multiple of 8 and >= 64
AI-assisted analysis of unslothai/unsloth@203007d190 (2026-08-15).
Data as JSON: /api/errors/2fe0e55b0a30c06e.
Report an issue: GitHub.