unslothai/unsloth · error · ValueError
No DiT trainer for family {cfg.resolved_family!r}
Error message
No DiT trainer for family {cfg.resolved_family!r} What it means
Raised at the top of the DiT LoRA trainer when the normalized config's resolved_family has no entry in _SPECS. resolved_family is what normalization computes from the base model, so this means the run targets a family the trainer build knows nothing about. It fails before any heavy imports, so it is purely a config/version mismatch signal.
Source
Thrown at studio/backend/core/training/diffusion_dit_trainer.py:1838
return False
def run_dit_lora_training(
config: DiffusionLoraConfig,
*,
on_event: Optional[EventCb] = None,
should_stop: Optional[StopCb] = None,
) -> str:
"""Train a flow-matching DiT LoRA (FLUX.1 / FLUX.2 / Qwen-Image / Z-Image / Krea 2 / LTX-2) and export it.
Resumable: ``cfg.resume_from_checkpoint`` restores the adapter, optimizer moments, LR
position, EMA shadow, sampler cycle and RNG streams from a ``checkpoint-<N>`` bundle,
and the loop runs steps N+1..train_steps (the TARGET TOTAL). A stop-and-save and every
``cfg.save_steps`` interval write such a bundle."""
cfg = config.normalized()
spec = _SPECS.get(cfg.resolved_family)
if spec is None:
raise ValueError(f"No DiT trainer for family {cfg.resolved_family!r}")
# DiT families train in bf16, so an explicit fp16 request is refused, not silently upgraded. Validated before the heavy imports so a host without diffusers still sees the real error.
if cfg.mixed_precision == "fp16" and spec.force_bf16:
raise ValueError(
f"{spec.family} LoRA training requires bf16: fp16 overflows its fp32 RoPE / "
f"embedder internals. Set mixed precision to bf16."
)
import torch
rng = random.Random(cfg.seed)
torch.manual_seed(cfg.seed)
_FLUX_STATIC.clear()
save_on_stop = True
def _check_stop() -> bool:
nonlocal save_on_stopView on GitHub (pinned to 203007d190)
Solutions
- Check the supported families in the trainer docstring (FLUX.1 / FLUX.2 / Qwen-Image / Z-Image / Krea 2 / LTX-2) and set base_model to one of those.
- Print cfg.resolved_family after config.normalized() to see what the family actually resolved to and fix the source of the bad value.
- Align versions: update the backend so the family your config references is registered in _SPECS.
Example fix
# before cfg.resolved_family = "flux.3" # not a real family -> No DiT trainer # after cfg.base_model = "black-forest-labs/FLUX.1-dev" # normalization resolves a known family
Defensive patterns
Strategy: validation
Validate before calling
SUPPORTED = {"flux.1", "flux.2", "qwen-image", "z-image", "krea-2", "ltx-2"} # mirror _SPECS keys
def family_supported(resolved_family: str) -> bool:
return resolved_family in SUPPORTED Try / catch
try:
train_diT_lora(cfg)
except ValueError as e:
if "No DiT trainer for family" in str(e):
raise SystemExit(f"Unknown family {cfg.resolved_family!r}; check base_model spelling/backend version")
raise Prevention
- Log config.resolved_family right after normalized() to catch bad family resolution early.
- Keep backend and client versions in lockstep; don't open configs from newer versions.
When it happens
Trigger: cfg.resolved_family resolving to a string not present in _SPECS: a typo or custom family name injected into the config, a new model family saved by a newer Studio version then opened by an older backend, or direct API calls constructing configs by hand.
Common situations: Downgrading the backend or mixing backend/frontend versions; hand-written config dicts; a family constant renamed between releases; custom forks adding a family without registering a spec.
Related errors
- '{family_name}' needs diffusers ({pipeline_class}), but this
- base_precision={mode!r} needs a CUDA GPU; this host has none
- {spec.family} LoRA training requires bf16: fp16 overflows it
- base_precision={base_precision!r} trains in bf16 compute; se
- base_precision={base_precision!r} is not supported for minim
AI-assisted analysis of unslothai/unsloth@203007d190 (2026-08-15).
Data as JSON: /api/errors/cc862ec3adb896cf.
Report an issue: GitHub.