unslothai/unsloth · error · ValueError
The LoRA selection changed, but a quantized (int8/fp8) trans
Error message
The LoRA selection changed, but a quantized (int8/fp8) transformer bakes its adapters at load time. Reload the model with the new adapter selection.
What it means
Also from `_adjust_baked_loras`: the quantized load DID bake adapters, but the generate request's adapter set differs from the baked one. Value-level changes are fine -- the same (name, path) set with new weights goes through `set_adapters` (absorbed by torch.compile guards), and disabling all is scale 0. But a different adapter set changes topology, which the baked-and-compiled quantized transformer cannot accept, so it raises a clean ValueError directing a reload.
Source
Thrown at studio/backend/core/inference/diffusion.py:5132
pipe._unsloth_loras = tuple((n, p, 0.0) for (n, p, _w) in current)
return
desired = self._resolve_lora_set(
specs,
family = getattr(state.family, "name", None),
hf_token = state.hf_token,
cancel = cancel,
)
if desired == current:
return
if [(n, p) for (n, p, _w) in desired] == [(n, p) for (n, p, _w) in current]:
# Same adapters, new weights: value-level change on the baked topology.
pipe.set_adapters(
[n for (n, _p, _w) in desired],
adapter_weights = [w for (_n, _p, w) in desired],
)
pipe._unsloth_loras = desired
return
raise ValueError(
"The LoRA selection changed, but a quantized (int8/fp8) transformer bakes its "
"adapters at load time. Reload the model with the new adapter selection."
)
@staticmethod
def _reset_step_cache(pipe: Any) -> None:
"""Clear the transformer's stateful step cache (FBCache) before a forward.
diffusers keys FBCache residuals by cache context ("cond"/"uncond") on the
long-lived transformer. The context exit does NOT reset them; the end of a
pipeline ``__call__`` does, via ``maybe_free_model_hooks()`` -- but only when
the call RETURNS. A call that raised (an OOM this generate() backs off from, a
cancelled denoise, a failed prior request) leaves its own batch's residual on
the resident transformer, and the next forward's first step then compares
against it: a tensor-shape mismatch when the resolution/batch changed, or a
stale-cache reuse otherwise. The transformer-level reset entry point is
``_reset_stateful_cache`` in diffusers 0.39 (``reset_stateful_hooks`` lives only
on the HookRegistry, so a getattr for it on the transformer is a silent no-op).View on GitHub (pinned to 203007d190)
Solutions
- Keep the adapter selection identical to what was baked; adjust only weights/scales at generate time.
- If a different set is needed, reload the model with the new adapter selection so it bakes correctly.
- Track the baked set (pipe._unsloth_loras / load response) and diff against requested specs client-side before calling.
Example fix
# before: baked [lora-a], requested [lora-b] -> raises
diffusion.generate(prompt="...", loras=[("lora-b", 0.8)])
# after: same baked adapter, new weight -- allowed
diffusion.generate(prompt="...", loras=[("lora-a", 0.6)]) Defensive patterns
Strategy: validation
Validate before calling
# Diff requested adapters against the baked set before generate
baked = {(n, p) for (n, p, _w) in state.baked_loras}
requested = [(n, p) for (n, p, _w) in normalize(lora_specs)]
if set(requested) != baked:
await diffusion.load(model, transformer_quant=state.transformer_quant, loras=lora_specs) # re-bake Type guard
def same_adapter_set(desired: list, current: list) -> bool:
"""Baked topology matches: same (name, path) pairs regardless of weights."""
return [(n, p) for (n, p, _w) in desired] == [(n, p) for (n, p, _w) in current] Try / catch
try:
diffusion.generate(prompt=p, loras=loras)
except ValueError as e:
if "selection changed" in str(e):
await diffusion.load(model, transformer_quant="int8", loras=loras)
return diffusion.generate(prompt=p)
raise Prevention
- On quantized builds, treat adapter identity as load-time immutable; only scales vary per generate.
- Keep the baked set (from pipe._unsloth_loras / load response) as the source of truth in clients.
- UIs should force a reload flow when the user swaps adapters on a quantized load.
When it happens
Trigger: Load-time loras baked as [("lora-a",1.0)] but generate() passes [("lora-b",0.8)], or adds/removes an adapter: the (name, path) list comparison `[(n,p) for desired] == [(n,p) for current]` fails, falling to the raise. Same set with different weights does NOT raise.
Common situations: UI LoRA picker letting users swap adapters on a quantized load; API clients building per-request LoRA lists without consulting what was baked; session state desync between load parameters and generate parameters.
Related errors
- This quantized (int8/fp8) load was built without LoRA adapte
- transformer_quant='{requested}' could not be used: {reason}.
- text_encoder_quant='{requested}' could not be used: {reason}
- The requested LoRA adapters could not be applied: baking ada
- LoRA is not supported for this model/quantisation on the dif
AI-assisted analysis of unslothai/unsloth@203007d190 (2026-08-15).
Data as JSON: /api/errors/e51aa10ca67df2de.
Report an issue: GitHub.