1
0
mirror of https://github.com/vladmandic/sdnext.git synced 2026-10-23 06:28:57 +03:00

252 Commits

Author SHA1 Message Date
CalamitousFelicitousness
4b5502c368 fix(offload): move transformers no-split units as one group
Leaf group offload hooked every Linear and Conv inside a decoder layer on its own, below the unit a transformers model declares in _no_split_modules. Qwen3.5 passes conv1d.weight to the causal-conv1d kernel without calling conv1d, so the weight stayed on cpu and the encode failed. Under leaf_level each declared unit of a transformers component now onloads as one group on its own forward, leaves outside the units keep their groups, and the stream prefetch tracer is registered again over the new groups.
2026-10-18 22:22:52 +01:00
CalamitousFelicitousness
9daacaad81 fix(lora): keep the bias backup in backup mode
network_backup_weights cloned the bias into a local and never stored it on the module, so network_apply_weights found no bias backup and refused every diff_b delta whenever the native path ran in backup mode (quantized models, select stacking, lora_fuse_native off). The test-lora-apply helpers stamped backups by hand and now go through network_backup_weights.
2026-10-18 21:44:32 +01:00
CalamitousFelicitousness
be9a81afce feat(attention): remap layout kinds from SD_SPARSE_KINDS for experiments
SD_SPARSE_KINDS=cond=image remaps a declared kind for every stream that
carries it, so a running server can A/B sparsified reference images from an
environment variable.
2026-10-16 23:04:02 +01:00
CalamitousFelicitousness
4b791c2e83 feat(attention): declare the flux 3 packing
Flux 3 runs per-mode blocks over text, image and reference images
separately, then joint blocks over all three, so each forward attends at
three or four sequence lengths. The declaration follows the order measured
on both checkpoints: text, image, then one concatenated reference stream;
prompt padding is attended.
2026-10-16 23:04:02 +01:00
CalamitousFelicitousness
cf59a50c89 feat(attention): declare packing per transformer, one layout per group
Each transformer class declares its streams and the stream order of every
block group that attends over a sequence; the class set it replaces read
txt_ids and img_ids and fit only single-sequence models. The reader
publishes one layout per group keyed by sequence length, the stage looks it
up by the length it is called with, and where two groups share a length the
one keeping more tokens dense serves both. The modular pre-hook reads the
same declaration, so modular denoisers without *_indices tensors publish
too. The stage logs each layout once per shape.
2026-10-16 23:04:02 +01:00
Vladimir Mandic
57e2222667 scheduler add stop state, update hints
Signed-off-by: Vladimir Mandic <mandic00@live.com>
2026-10-14 11:57:11 +02:00
Vladimir Mandic
0c8cffff82 scheduler task retrry
Signed-off-by: Vladimir Mandic <mandic00@live.com>
2026-10-13 10:25:19 +02:00
Vladimir Mandic
dd80957c2b scheduler queue locking
Signed-off-by: Vladimir Mandic <mandic00@live.com>
2026-10-13 08:56:28 +02:00
Vladimir Mandic
473076e310 scheduler fix init
Signed-off-by: Vladimir Mandic <mandic00@live.com>
2026-10-12 17:20:52 +02:00
Vladimir Mandic
cff86a9161 set header text on click
Signed-off-by: Vladimir Mandic <mandic00@live.com>
2026-10-12 10:44:43 +02:00
Vladimir Mandic
66906eb423 scheduler fixes, linting, hints
Signed-off-by: Vladimir Mandic <mandic00@live.com>
2026-10-11 20:29:31 +02:00
Vladimir Mandic
ac3d7f2a60 scheduler video draft
Signed-off-by: Vladimir Mandic <mandic00@live.com>
2026-10-11 09:51:27 +02:00
Vladimir Mandic
14850411c8 scheduler draft
Signed-off-by: Vladimir Mandic <mandic00@live.com>
2026-10-11 08:08:03 +02:00
CalamitousFelicitousness
078779e34f test(api): cover hires and detailer on condition-image models 2026-10-04 21:01:22 +01:00
CalamitousFelicitousness
f723d0b824 fix(models): declare one condition image for kontext and qwen-image-edit
The request now sets their output size. sd_models.takes_condition_set (a declared count above 1) keeps an image list on these two models as one image per sample.
2026-10-04 21:01:22 +01:00
CalamitousFelicitousness
21dc63dc03 feat(detailer): run on condition-image models as a crop edit
Each detection's crop is the condition image and the mask applies on paste; these models were rejected as not compatible. test/test-detailer-mode.py covers the verdict per model.
2026-10-04 21:01:22 +01:00
Vladimir Mandic
c6bf7b4368 samplers expose base/max seq len, improve sampler options save, copy defaults
Signed-off-by: Vladimir Mandic <mandic00@live.com>
2026-09-30 18:37:05 +02:00
CalamitousFelicitousness
d1d3c7c438 feat(lora): pdd exports with a trained sigma grid and replaced weights
Inference-only PDD exports such as alibaba-pai's Qwen-Image-2.1-Fun-Acc-4Step carry no pdd_num_steps: the grid is pdd_sigmas in the metadata or in the pdd_config.json the release keeps beside the weights, and the file replaces norm weights outright. Those parameters are set with the heads, blended toward the loaded value by strength and restored on removal. The pin passes the grid's block boundaries as sigmas and turns off dynamic shifting, static shift and terminal stretch on that generation's scheduler, which would otherwise reshape them, and leaves num_timesteps alone where the pipeline exposes it as a read-only property. Qwen-Image 2.1 gets an ArchSpec and the PDD loader in its chain; a file with heads but no grid warns and loads its backbone only.
2026-09-30 08:09:08 +01:00
CalamitousFelicitousness
c5c09d6cc9 feat(lora): native loading for qwen-image 2.1
QwenImage21Transformer2DModel keeps attention and the SwiGLU split, while ComfyUI checkpoints fuse the SwiGLU input as img_mlp.gate_up with rows [gate_layer; proj], the layout ai-toolkit and musubi-tuner train against. pipelines/qwen/qwen21_lora.py splits that projection by row halves for LoRA, DoRA, LoKr and LoHA in dotted and kohya-flattened form and binds every other key verbatim; qwen21 joins allow_native and NATIVE_DISPATCH. The diffusers path loads none of the fused files and fails on transformer.-prefixed files that carry alpha tensors. The tests map every layout found on CivitAI and the Hub against the real class, check the split against the fused SwiGLU forward, and refuse Qwen-Image 1.x files.
2026-09-30 08:08:46 +01:00
CalamitousFelicitousness
55b0442e7c fix(civitai): name files from the /models payload
/model-versions can still report a fresh upload by its storage key
(VAPA5E3KPBRRJZ2PMTCMW8WSE0.safetensors) while /models already carries
the uploader name, and it drops GGUF quantType; /models is also what
the UIs list from. The names route and id-based download therefore take
their file entries from /models whenever it answers, and keep the
version's own files only when it does not.
2026-09-30 03:48:49 +01:00
CalamitousFelicitousness
803583c6f4 fix(civitai): drop redundant variant and role suffixes from save names
A suffix only adds what the CivitAI name lacks: the variant is skipped
when the name already spells that token (ideogram4INT8_...UncondINT8
stays as is, x_fp8 still gains -fp8_e4m3fn once the header names the
exact dtype), header-derived expert roles obey the same file-name guard
as title-derived ones (ideogram4_fp8Uncond no longer ends in -uncond),
and companions never take a role, since the text encoder of a
high-noise version is the same file the low-noise version ships.
2026-09-30 03:34:50 +01:00
CalamitousFelicitousness
f49595da0a feat(civitai): name gguf downloads by their header quant
A GGUF's variant is its quant, never metadata.fp, which is the dtype it
was quantized from (a Q4_K_M upload tagged fp8 was saved as -fp8). The
name route now reads the GGUF header the way it reads safetensors
headers: general.file_type gives the exact quant (Q4_K_M) and files
without it, such as Ideogram 4 GGUFs with an empty KV block, fall back
to the dominant tensor type (Q4_0). When the header cannot be read the
metadata or url quantType still applies; fp never does.

- peek_civitai gains a v2/v3 GGUF reader over a 1 MB ranged read, with
  the same id-keyed cache and the quant token in the "quant" field
- peek_headers dispatches by extension, so .gguf siblings are probed
  alongside .safetensors ones
2026-09-30 03:22:02 +01:00
CalamitousFelicitousness
87e62e6545 feat(civitai): choose download file names server-side
Enso, the Gradio CivitAI tab and API callers share one naming rule in
modules/civitai/names_civitai.py. The variant token (metadata.fp,
quantType, or the quantType url parameter) is suffixed unconditionally
so names stay stable when a creator adds variants; dual-transformer
expert roles (Wan 2.2 A14B high/low noise, Ideogram 4 uncond) join it
from the version title or the file header; remaining collisions cascade
to the size class, then the file id. Header peeks upgrade a bare fp8
claim to the dtype-exact token.

- GET /sdapi/v2/civitai/version/{id}/names lists save name, route type,
  variant and role per file
- POST /sdapi/v2/civitai/download takes version_id + file_id and
  resolves url, name, sha256 and companion type; url + filename callers
  are unchanged
- /model-versions drops GGUF quantType, so such versions take their
  files from /models
- civitai_save_precision (Settings > Huggingface) drops the
  unconditional suffix; roles stay and names remain unique per version
- header peek moves to peek_civitai.py; failed reads are never cached
- ui/civitai.ts passes file ids instead of computing names
- test/test-civitai-names.py replays recorded /model-versions, /models
  and header responses under both toggle states
2026-09-30 03:01:02 +01:00
CalamitousFelicitousness
9f705b263e test(api): add multi-image condition set tests
Cases: two images on img2img, an aligned first image with a different requested size, a batch size above the image count, a request over max_condition_images, and two control inputs. With --log each case also reads the Base log line for the image count and call size the pipeline received; a call sized from the first image returns the requested size with scrambled content.
2026-09-26 18:47:37 +01:00
Vladimir Mandic
484e6acae7 Merge pull request #5110 from QualiaRain/fix/video-load-failure
Avoid default image-model reload after video load failure
2026-09-25 07:59:11 +02:00
Blood
b7e8d73681 Create test-video-load-failure.py 2026-09-24 22:26:06 -04:00
Blood
514ed9540c Create test-refiner-prompt-restore.py 2026-09-24 21:58:05 -04:00
CalamitousFelicitousness
c67b4f499f fix(lora): read the pdd grid from the file header when the cache lacks it
The metadata cache keeps a failed read forever and --no-metadata returns
nothing, and in both cases the head loader returned None silently while
the backbone still applied. The grid is now read from the file's own
header when the cached metadata lacks it, and head-shaped tensors
without a grid log a warning.
2026-09-16 19:26:21 +01:00
Vladimir Mandic
059ccbaf0b Merge pull request #5091 from CalamitousFelicitousness/feat/lora-pdd
feat(lora): parallel decoding heads and minimax schedule controls
2026-09-16 07:45:57 +02:00
CalamitousFelicitousness
b259a48448 fix(lora): give replaced pdd projections their own memory
The projection a parallel head replaces waits out of the module tree,
so nothing moves it, and a weight still viewing its checkpoint shard
keeps the whole shard mapped. The stash now clones the projection's
tensors.
2026-09-16 03:23:03 +01:00
CalamitousFelicitousness
09e861157f fix(offload): hand back the loaded cpu tensors on no-stream offload
Group hooks on the no-stream path and the on-demand hook return a
component to cpu through a device copy, so a memory-mapped text encoder
sits in memory twice, as the mapped file its never-run vision tower
keeps alive and as the copies, and every encode pays a device-to-host
transfer of unchanged weights. The engine now records the cpu tensors
at onload and hands them back at offload; a component moved by any
other path still takes the copy.
2026-09-16 01:57:23 +01:00
CalamitousFelicitousness
726907dd5b fix(video): count minimax steps as transformer evaluations
MiniMaxH3Scheduler counts the terminal sigma in num_inference_steps, so
Steps N ran N-1 evaluations while every other model runs N. The shim
hands the scheduler p.steps + 1, the slider starts at 1, and the PDD
pin records the evaluation count while passing the scheduler its grid
argument. Metadata written before this change counted grid points.
2026-09-16 00:47:46 +01:00
CalamitousFelicitousness
29fe895c0b feat(video): absolute per-request minimax shift on every path
Shift is a property of the trained schedule, not of the step count, so
the tab sliders take absolute values, defaulting to the shipped 12 and
3. video_minimax resolves each request from the request value or the
scheduler config inside apply_overrides, which the tab, the api and
the still path all call, so a request without values lands on the
shipped schedule. The api maps sampler_shift onto the video schedule
and gains audio_shift. Applied values are recorded as Video shift and
Audio shift; the PDD pin records what it enforces.
2026-09-15 23:01:41 +01:00
CalamitousFelicitousness
57328dc615 fix(lora): bind minimax extraction residuals
Layer-wise extractions (FastH3) ship diff_b on every projection and
diff on the norms; final_layer.norm had no rename onto norm_out.norm,
so its residual went unmapped.
2026-09-15 03:52:04 +01:00
CalamitousFelicitousness
a800fe59cf fix(lora): accept lowercase lora_a and lora_b factor names
TaoLive adapters save the factors as lora_a and lora_b without the
.weight suffix, which no suffix table knew, so the file bound nothing.
2026-09-15 03:52:04 +01:00
CalamitousFelicitousness
a0f0097e52 refactor(lora): make the fused chunk slicer public
The fidelity CLI slices fused saves the way try_load_lora does.
2026-09-15 03:52:04 +01:00
CalamitousFelicitousness
5860ea9153 feat(lora): parallel decoding heads for pdd acceleration files
PDD files pair a backbone LoRA with the output projections repeated per
interval of a training grid; each step fuses the heads of its block
into one projection. network_pdd reads the grid from the metadata,
swaps a ParallelHead in for each projection, fuses from the scheduler's
step_index and pins the step count and shift while heads are
installed. The MiniMax loader declares which scheduler each head
follows.
2026-09-15 00:23:27 +01:00
CalamitousFelicitousness
3e705bc4af feat(lora): project adaln deltas onto the pruned minimax basis
The pruned transformer stores W @ P for each AdaLN projection against
the rank-8 basis in time_embedder.basis, so deltas trained at the
released width failed the shape check. try_load_lora gains an
adapt_weights hook and the MiniMax loader refits lora_down as down @ P,
which is exact.
2026-09-15 00:23:09 +01:00
CalamitousFelicitousness
6d5c63d9fe fix(hashes): snapshot the stores under a lock before saving the cache
save_cache handed writefile the live HashStore objects, so an add_hash
from another thread during the deep copy raised "dictionary changed
size during iteration" and dropped the save. The stores are now copied
under a lock that also covers the write, so a later save never lands
under an earlier snapshot.
2026-09-13 20:35:37 +01:00
CalamitousFelicitousness
68c64fb4bc fix(json_helpers): write atomically by default and warn on empty reads
Every caller writes a whole JSON document, and a plain open/write can
leave a torn or empty file when the process dies or another writer
overlaps, which readfile then returns as {}. Writes now go through the
temp file and replace unless atomic=False or the mode is append. A read
waits out an open that Windows refuses while a replace of the same name
is in flight, and an empty file is reported when the read is not
silent, since a zero-byte config.json otherwise resets settings without
a trace.
2026-09-13 19:20:10 +01:00
CalamitousFelicitousness
b39639ce2e fix(json_helpers): serialize file access per path within the process
The fasteners lock is inter-process only. On Linux fcntl record locks
belong to the process, so two threads writing the same file were never
serialized and could tear it; on Windows they were, until the lock
switched itself off. Every writer of these files runs inside one
multi-threaded process, so that is the case that matters.

readfile(lock=True) and writefile now take a re-entrant lock per
normalized path, held from the snapshot through the replace so writes
to one path land in call order. Other processes are covered by the
atomic replace. A .lock file left next to a JSON file by the old lock
is removed the first time that path is used.
2026-09-13 19:20:10 +01:00
CalamitousFelicitousness
cdc76c25c6 fix(json_helpers): make atomic saves work on windows, keep lock file
writefile(atomic=True) renamed the temp file while it was still open,
which Windows refuses, so every atomic save failed there and left a temp
file behind. The temp file is now created with mkstemp, closed before
os.replace and removed when the save fails; the replace retries briefly
when another handle holds the target, which Windows reports as a
permission error.

Both helpers removed the .lock file after releasing it. That removal
raced other holders on both platforms, and any failure switched locking
off for the whole process without a log line. The lock file now stays in
place; a failed release or a lock timeout is logged instead.

writefile deep-copied and validated the live object in Python, so a
concurrent insert into a shared dict raised "dictionary changed size
during iteration" and dropped the save. dict.copy and list.copy run
under the GIL, so the deep copy and the per-key validation now walk that
snapshot; nested containers remain the caller's responsibility.

test/test-json-helpers.py covers all three on Linux and Windows.
2026-09-13 18:41:33 +01:00
Vladimir Mandic
da5d934f1f Merge branch 'dev' into feat/filter-sampler-upscaler-choices 2026-09-13 07:41:53 +02:00
Yifan Chen
bae986e90b address selection filter review feedback 2026-09-12 00:08:08 -07:00
CalamitousFelicitousness
619a25eea6 fix(offload): key the group stats report by component
A checkpoint-name key survives unload, so a reload of the same checkpoint
never printed the per-module stats block again, even with a different
quantization. Each component now carries its own reported stamp: a task
switch rebuilds the pipe around the same modules and stays quiet, while a
reload or a component swap brings new modules and reports them.
2026-09-07 22:35:38 +01:00
CalamitousFelicitousness
8619dbc0af test(offload): address the split offload modules in the placement role tests
The group offload functions live in sd_offload_group, sd_offload_utils and
sd_offload_state rather than modules.sd_offload, so the tests and their
monkeypatches now import and patch those modules directly.
2026-09-07 22:32:54 +01:00
Yifan Chen
a174e94183 feat(ui): filter generated sampler and upscaler lists 2026-09-07 08:29:37 -07:00
CalamitousFelicitousness
b434eb0c1b refactor(lora): route every bare key through the resolver
The parser no longer takes reference-name prefixes to tell bare
reference keys from bare diffusers keys. Any bare key carries the
sentinel and the arch resolver renames what it knows and passes the rest
through. Flux2 keeps its list for file-format detection only.
2026-09-06 04:25:44 +01:00
CalamitousFelicitousness
783b66c3be refactor(lora): offer unknown bare keys to the resolver
A bare key that matches no known prefix is parsed with the
bare-diffusers sentinel and handed to the resolver instead of being
dropped at parse time. The per-arch lists of bare diffusers prefixes are
gone, and a path that names no live module counts as unmapped.
2026-09-06 04:25:44 +01:00
CalamitousFelicitousness
1c91fb2047 refactor(lora): make the fused row reorder a chunk capability
A ChunkSpec can reorder equal row blocks of the rows it selects, so an
arch declares a swapped SwiGLU projection on the target instead of
permuting the state dict first. Only the LoRA family applies it; the
others skip a reordered target with a warning.
2026-09-06 04:25:44 +01:00