detect_quant now reads _quantization_metadata as the authoritative quant
source when present, and resolves marker-file formats from the marked
layers' stored weight dtypes instead of file-wide dtype voting, which
mislabeled fp8 files carrying extra uint8 tensors and had no nvfp4
mapping at all. Schema bump so cached probe entries refresh.
Triton has no e4m3 conversions before sm_89, so any compiled graph
touching fp8 storage weights fails with an InductorError on Ampere.
Select the eager dequant and re-quantize paths for e4m3 weights when
the hardware cannot compile them; other dtypes keep compiled dequant.
SDNQ_ALLOW_FP8_COMPILE overrides the detection.
The secondary unet loads from the networks panel toggle or the settings
page; companion ordering and dynamic visibility pushes in ui_settings.py
are not worth their footprint for one setting.
The hidden change_refiner button passed key='sd_model_checkpoint', so
loading a card with the refine toggle active reloaded the base model
and never set sd_model_refiner.
json_helpers does its own error handling and file locking, so the
try/except wrappers, threading locks and isfile checks were dead
weight; probe cache file paths are now defined in paths.py.
One UNET override cannot serve dual-transformer arches: ideogram4
conditional/unconditional and wan combined-stage experts need separate
files, and previously a single override landed on both experts.
- sd_unet_secondary option with per-slot tracking, consumed-state sync,
arch-change reset, and incompatible-override fallback
- dropdown renders beside the primary, follows it into quicksettings,
and is visible only for dual-transformer model types
- ideogram4 native single-file spec with a quant-aware fused-qkv
converter; such converters run before comfy_quant detection via
TransformerSpec.converter_handles_quant
- quicksettings render in configured order (sort keyed on the option
object and always fell back to alphabetical)
- post-load dtype warning skips quantized transformers
fp8_e4m3fn and fp8_e5m2 differ in kernel support, so a bare fp8 token
is not enough to know whether a file runs on a given architecture;
scaled_fp8 derives its token from the detected format.
Local probes read the marker tensor bytes for the true format string
(nvfp4, mxfp8, int8_tensorwise) instead of inferring from weight
dtypes; remote ranged peeks stay dtype-inferred. precision_token maps
quant format or dominant dtype to the short filename token.
peek-header now returns the full probe (architecture fingerprint,
dtypes, quant scheme) alongside the metadata block, and caches the
response persistently by civitai file id; file content per id is
immutable, so cached probes skip the ranged fetch entirely.
Analyzes safetensors/gguf headers without reading weights: curated
tensor-name fingerprints for common families, container kind detection
(model/lora/vae/text-encoder), element-weighted precision over core
tensors, comfy_quant/scaled-fp8/gguf quant detection, lora base
resolution via trainer metadata with shape arbitration, and full
__metadata__ passthrough. Results cached by mtime in
data/model_probe.json.
- analyze_header is pure and shared by remote ranged peeks and local
file reads
- fingerprints verified against the local library and live civitai
headers; unmatched families report unknown rather than guessing
The API carries no field distinguishing dual-transformer expert files;
conversion tools embed it in the header __metadata__. peek-header
range-fetches the JSON header and returns the metadata block without
downloading the file. Restricted to civitai.com urls.
Versions bundle companion files typed by the file, not the model;
'Text Encoder' had no TYPE_MAP entry so companions landed in the
checkpoint folder where the loader never scans.
Interrupted downloads leave url-hash .tmp resume files that nothing
cleans up; the queue that knows about them is in-memory only.
- iter_type_roots lists every folder downloads resolve into
- partials older than 7 days by mtime are deleted when the download
manager starts; active partials always have a fresh mtime
Multi-variant versions serve one canonical filename per file; the
precision, size class, format, and scan status that distinguish them
were dropped at the model layer.
- CivitFile gains metadata (format, size, fp), pickle and virus scan
results, and scannedAt
History entries stored only the query or tag term, so restoring a
search dropped every filter, and filter-only browsing was never
recorded at all.
- SearchHistory.add takes an optional params dict stored on the entry
- get_search records non-default filters: type, sort, period, base
models, nsfw, username, favorites
- filter-only searches are recorded as 'filter' entries labeled with
the filter values
A 200 reply to a resumed download carries the full file, not the
remainder; appending it to the partial produced a corrupt file that
passed the size check and only failed at hash verification. Truncate
the temp file and restart from byte 0 when a Range request comes back
as 200 instead of 206.
The /model-versions endpoint now serializes availability as null, which
failed str validation and turned every version lookup into a 404. Coerce
null to the default like the creator username validator already does.
Pass through earlyAccessEndsAt and earlyAccessConfig so clients can see
that a download requires a Buzz purchase before requesting the file.
diffusers pipeline downloads build subfolder config.json allow-patterns
with os.path.join, and huggingface_hub>=1.22 matches patterns with
fnmatchcase which does not normalize path separators
(huggingface/huggingface_hub#4435). On windows the resulting backslash
patterns match nothing, so per-component config.json files are never
downloaded and the incomplete snapshot still passes the diffusers
cache-completeness check, failing every subsequent load with
"no file named config.json".
Prefetch component configs with forward-slash patterns before pipeline
load. This covers all model families and also repairs snapshots already
broken by the bug on the next load attempt. No-op on linux, in offline
mode, and for local folder or single-file models.
Removing all loras never called set_adapters, so peft adapters stayed
active until model reload. Removal now uses disable_lora, which keeps
modules intact; unload_lora_weights would detach balanced offload hooks.
Load calls enable_lora after set_adapters since peft set_adapter does
not clear the disabled flag. Removal of fused diffusers loras remains
unhandled.
NetworkModule.multiplier matched text encoders via 'transformer' in the
key prefix, which fits dit keys but never lora_te keys, so text encoder
modules followed unet_multiplier[0] and the te= tag strength was ignored.
Network activation ran after prompt encoding, so text encoder lora
weights never affected embeds on the first generation and the stale
result was then served from the embed cache. The trailing unfiltered
activate in network_load also overrode the te exclude filter, so the
lora_apply_te setting was never honored.
- parse and activate networks in process_base before pipeline args are built
- activate_filtered gates text encoder components on per-request or global
lora_apply_te; used by base, hires, detailer and faceid call sites
- network_load accepts activate=False for callers that run their own
deactivate/activate sequence with include/exclude
- network_activate walks excluded components in restore-only mode so a
filtered text encoder reverts to backup instead of keeping stale deltas
- loaded_loras cache is single-entry since per-filter entries go stale when
the setting toggles
- prompt embed cache key includes the effective lora_apply_te value
transformers >=5.6 removed the text_model wrapper from CLIPTextModel, so
kohya te keys no longer matched the network layer mapping and text encoder
weights were silently skipped. KeyConvert retries te keys with the
text_model segment dropped; lora extraction keeps writing canonical kohya
naming for flattened encoders.
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.