The single-file override loaded via from_pretrained(state_dict=...) without a
quantization_config and then relied on do_post_load_quant, which no-ops on a
bare module (it maps Model/TE onto pipeline attributes that a lone encoder does
not have). A custom TE therefore loaded full-precision regardless of the SDNQ
setting. Pass quant_args into from_pretrained like the repo/default path so SDNQ
quantizes during load.
When a checkpoint change switches the model type, a custom sd_text_encoder no
longer fits, so reset it to Default and clear loaded_te, mirroring the sd_unet
reset. The type is resolved with detect_pipeline on both the loaded and incoming
checkpoints, so same-arch switches (Krea2 Base and Turbo share one pipeline
class) do not reset. The checkpoint handler also returns sd_text_encoder
alongside sd_unet so the dropdown reflects it.
cfg=-1 means use the pipeline's own default. Krea2Pipeline serves both Base
and Turbo under one class, so a static signature default cannot fit both: Base
needs real guidance while the distilled Turbo runs guidance-free. Resolve the
unset default from is_distilled (Base 4.5, Turbo 1.0). Explicit cfg is passed
through unchanged.
reload_text_encoder only hot-swapped T5-family encoders and ran only at initial
load, so changing sd_text_encoder for a model with a generic encoder (Krea2's
Qwen3-VL) never took effect until a full model reload. Track the loaded
selection and, for encoders with no in-place swap, reload the model on change,
triggered from the settings handler. The fresh model object also invalidates
the prompt cache.
The single-file override path built a T5EncoderModel regardless of the
requested class, so a non-T5 override (Qwen3-VL for Krea2) became a T5 with the
wrong vocab and overflowed its embedding into a CUDA device-side assert. Load
the file as the class the pipeline requests via from_pretrained(state_dict=...),
letting transformers reconcile per-arch key prefixes, and fall back to the base
text encoder on failure.
git() returns command output on failure instead of raising, so a failed
rev-parse read as != commit and spuriously flagged the repo upgraded and
required a restart. Guard on a 40-char sha, matching the latest-commit check.
strip_prefix returns the detected prefix instead of logging it, so the load
summary reports it alongside the key count and the redundant reading-state
marker is gone. Four near-identical cls/file lines become one.
Base ships last.up all-zeros so the branch is a no-op; pre-branch
finetunes omit both keys. A zero_init_missing spec field zero-fills
them on load instead of falling back to the base transformer.
Under uv, install --upgrade re-resolves the full dependency set eagerly: the pinned tokenizers and transformers installs bumped typing-extensions past its requirements pin on every update, and the requirements check then downgraded it back, flagging a restart each time. The preceding uninstall and exact pins already force the intended change, so the flag only produced churn. The pip-routed diffusers install is aligned for consistency.
The post-upgrade restart depended on a pinned requirement drifting in the same run, since the requirements check was the only place that set restart_required. The direct check compared a short hash and date string against a full sha and never fired. Set restart_required when the repository update moves HEAD so an upgrade restarts even when no package pins changed; a no-op pull now logs the repository as unchanged instead of upgraded and skips the restart.
check_transformers and check_diffusers compared the target commit against a marker stored in server options, which is only persisted after full webui startup. An upgrade restart fires before that point, so the marker stayed stale and the next launch reinstalled the same pin again. Read the installed commit from the package dist-info direct_url.json instead; the options values remain as informational display.
strptime was handed the stat datetime instead of the date string, so it
always failed and left a raw string mtime; the Date sort then crashed on
mixed str/datetime items. Parse the date string, falling back to stat mtime.
CivitAI has no model type for a standalone transformer, so DiT finetunes
are published as 'Checkpoint' like full models and all landed in
Stable-diffusion, where the single-file transformer loader never looks.
Route Checkpoint downloads to UNET unless the base model is a known full
checkpoint (SD1.x/2.x, SDXL and its Pony/Illustrious/NoobAI derivatives,
SVD, Kolors, Stable Cascade). Downloads with no base_model, or a
civitai_save_type_folders override, keep the previous behavior.
An absolute 1024-byte floor rejected valid complete downloads, since
some safetensors are legitimately tiny (a lone projector-diff tensor is
~160 bytes). Verify completeness against the declared Content-Length
instead, accepting any size, and keep the floor only as a fallback when
it is missing. Reject text/* responses up front so an HTML error or
login page served with HTTP 200 is never saved as a model file.