Commit Graph

9444 Commits

Author SHA1 Message Date
CalamitousFelicitousness ead32daddf chore(lora): trace pdd head fusion under SD_LORA_DEBUG
One line per fused block shows which heads a generation runs on.
2026-09-16 19:26:21 +01: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 909db4b797 packages
Signed-off-by: Vladimir Mandic <mandic00@live.com>
2026-09-16 20:23:53 +02:00
CalamitousFelicitousness 6b7c43cd29 fix(lora): resolve network names that carry a dot in the filename
add_network keys available_networks by the basename with dots mangled to
underscores, and create_item looked the name up in that table using the
name as loaded, so any file with a dot in its stem missed and logged
"not registered". The tag pass then dropped the network's own tags and
used the filename instead. The lookup now falls back to the alias table,
which already carries the natural basename and the subfolder path.
2026-09-16 18:26:06 +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 a7d430a8ba feat(offload): warn when streams clamp the group offload blocks
Streamed prefetch runs one block per group, so a larger blocks setting
is reduced to one at apply time. The clamp is now logged once per
component.
2026-09-16 02:18:07 +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
Vladimir Mandic a941d101c5 lint
Signed-off-by: Vladimir Mandic <mandic00@live.com>
2026-09-15 18:01:34 +02:00
Vladimir Mandic fe6c3acd16 minimax vdn experimental
Signed-off-by: Vladimir Mandic <mandic00@live.com>
2026-09-15 17:16:12 +02:00
Vladimir Mandic 07320874d3 fix font paths
Signed-off-by: Vladimir Mandic <mandic00@live.com>
2026-09-15 12:40:53 +02:00
Vladimir Mandic b7aa4b895a prompt cache prevent clear on task change
Signed-off-by: Vladimir Mandic <mandic00@live.com>
2026-09-15 12:29:14 +02:00
Vladimir Mandic af16ef567c theme handle cli
Signed-off-by: Vladimir Mandic <mandic00@live.com>
2026-09-15 09:34:10 +02:00
Vladimir Mandic 28c20f6aa0 refactor theme loading
Signed-off-by: Vladimir Mandic <mandic00@live.com>
2026-09-15 08:17:27 +02: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 f001a38dd3 fix(lora): accept bare lora_down and lora_up parameter names
Wrappers holding the factors as nn.Parameter save them without the
.weight suffix (alibaba-pai PDD files), which the marker gate rejected
before grouping. The MiniMax-only normalization for that form is
removed.
2026-09-15 00:22:40 +01:00
CalamitousFelicitousness 16a20a337a fix(video): apply the minimax shift through set_shift on both schedulers
MiniMaxH3Scheduler reads its shift from the instance, not config.shift,
and the per-request video scheduler was replaced by the Default sampler
restore. Both schedulers now take set_shift, including the
default_scheduler copy the restore reads.
2026-09-15 00:22:13 +01:00
Vladimir Mandic af69cb7a88 lint
Signed-off-by: Vladimir Mandic <mandic00@live.com>
2026-09-14 20:59:55 +02:00
Vladimir Mandic e4766f99dc minimax redo video/audio shift
Signed-off-by: Vladimir Mandic <mandic00@live.com>
2026-09-14 20:41:02 +02:00
Vladimir Mandic 516b9f4a45 lint
Signed-off-by: Vladimir Mandic <mandic00@live.com>
2026-09-14 12:11:52 +02:00
Vladimir Mandic cb7bc0faca fix grid with lora, add dlss framgen logging, add 8bit minimax variants
Signed-off-by: Vladimir Mandic <mandic00@live.com>
2026-09-14 11:34:37 +02:00
Vladimir Mandic bc416b759c cleanup wildcard metadata
Signed-off-by: Vladimir Mandic <mandic00@live.com>
2026-09-14 09:18:57 +02:00
Vladimir Mandic 808d7b77fe Merge pull request #5088 from CalamitousFelicitousness/refactor/json-helpers-path-lock
Refactor/json helpers path lock
2026-09-14 08:51:45 +02:00
CalamitousFelicitousness b3c78e9b56 fix(civitai): thumbnail video previews from the cdn's h.264 copy
CivitAI video covers are AV1, which OpenCV builds without dav1d cannot
decode. Previews fetch the CDN's transcode=true,width=450 H.264 copy
first, fall back to the original named by its content type, and drop a
video that yields no frame for the next media item. An unreadable frame
logs one line, and the download path is absolute before registration.
2026-09-14 04:00:38 +01:00
CalamitousFelicitousness 6d20ea0332 fix(civitai): keep civitai's reason on refused downloads
A refused download recorded only the status code and logged nothing.
The error now carries CivitAI's own message, as in "HTTP 403: Early
Access: ...", and the refusal and rename failure log like every other
branch.
2026-09-14 04:00:38 +01:00
CalamitousFelicitousness 9a6b7a1c93 fix(civitai): register a finished download with its loader list
A finished download refreshed the checkpoint list alone, so a new LoRA
or UNET stayed invisible to check-local and Networks until a manual
refresh. add_network, now module-level, registers one LoRA file; unet,
vae and checkpoint downloads run their loader's scan.
2026-09-14 04:00:38 +01:00
CalamitousFelicitousness 7554389f2e fix(civitai): stop check-local from reporting deleted model files
A hash cache hit now resolves through its loader's registry and counts
only while the file exists; entries whose file is gone are pruned, on
the request that finds them and once per process for the rest.
filename is always the local path.
2026-09-14 04:00:38 +01:00
CalamitousFelicitousness 229db02b14 feat(civitai): show search failures in the models tab
CivitSearchResponse carries the server's error text; the Gradio page
renders it, or a no-results line, in the details area instead of a
blank card list. The legacy route reads items from the response.
2026-09-14 04:00:38 +01:00
CalamitousFelicitousness ef31ce70c7 refactor(civitai): seed the base-model filter from discovery only
search_civitai.base_models was a hand-kept copy of the /enums list that
lacked every base added this year. The dropdown starts empty and takes
the discovered names minus the bases CivitAI has retired (in BaseModel
but not ActiveBaseModel). The tab handler refreshes the choice lists on
every visit, since later browser sessions used to get no update; the
initial search still runs once per process.
2026-09-13 23:19:56 +01:00
CalamitousFelicitousness eb3a062339 feat(civitai): list every file of a version in the gradio model details
The versions table showed only files[0], so precision variants of one
version could not be downloaded. Each file gets its own row under
rowspan version cells, sorted by precision then size, with a variant
column and a star on the primary; rows download by fileId URL and All
variants queues each version's primary from the fetched model. Companion
files pass their own type, and save names carry the precision, then
full/pruned and the file id only when needed to stay unique.
2026-09-13 23:19:56 +01:00
CalamitousFelicitousness b06b538104 feat(civitai): verify downloads in flight and cache under loader keys
The downloader hashes bytes as it writes them, seeding from the partial
on resume, and checks the declared SHA256 against that digest instead
of rereading the file. The declared hash, or the computed one when none
is given, is cached under the key the owning loader reads; loader_kind
and hash_cache_title derive that key for the downloader and the sweeps.
2026-09-13 23:19:56 +01:00
CalamitousFelicitousness cd86ea6321 fix(civitai): keep windows separators literal in save subfolder paths
resolve_save_path passed os.sep as the re.sub replacement string; on
Windows that lone backslash is an unfinished escape and every subfolder
download raised PatternError. A callable replacement is inserted
verbatim.
2026-09-13 23:19:56 +01:00
CalamitousFelicitousness 244db2e93e feat(civitai): retry overloaded search and log civitai error messages
An overloaded text search answers 503 with Retry-After, which send now
retries like a 429. Failure logs carry the server's error text with
ZodError issues flattened; a 404 from by-hash and a 401 from /me stay
quiet.
2026-09-13 23:19:56 +01:00
CalamitousFelicitousness 0b59d2acc4 fix(civitai): identify models by file digest in batched metadata sweeps
The sweeps queried with the extra-networks shorthash, which for LoRA is
the kohya sshs_model_hash and never matches, and the update sweep
skipped every uncached checkpoint. Hashes now come from the default
hash store or from hashing the file, lookups are batched, hashing stops
on interrupt and honours --no-hashing, and one lock serializes both
sweeps with a second start answered by 409.
2026-09-13 23:19:56 +01:00
CalamitousFelicitousness b10fefca77 feat(civitai): add batch hash lookups and 429 backoff to the client
Every API call goes through CivitaiClient.send, which caps concurrent
requests at shared.max_workers and retries 429 up to four times, using
Retry-After or exponential backoff up to 60s. New lookups wrap POST
/model-versions/by-hash/ids, POST /model-versions/by-hash and GET
/models?ids= within their caps and return a status per input whose chunk
failed; the ids query sends nsfw=true because it drops NSFW models
otherwise.
2026-09-13 23:19:56 +01:00
CalamitousFelicitousness 4cf734dbd6 feat(civitai): add the mini version endpoint
GET /sdapi/v2/civitai/version/mini/{id} exposes /model-versions/mini:
the primary file flattened onto the version, every hash, and the
permission flags a download needs. CivitVersionMini is its own model
because its field set is per-file, not per-version.
2026-09-13 23:19:56 +01:00
CalamitousFelicitousness ca6ad175d6 fix(civitai): follow the stats and profile fields upstream
favoriteCount, ratingCount and rating are gone since reactions replaced
ratings, tippedAmountCount is new, and unreported counts arrive as null,
which a strict int field turned into a rejected search page. /me lost
its avatar and reports tier, status and isMember, with tier absent for
non-members; email, emailVerified and tokenScope stay unmodelled.
2026-09-13 23:19:56 +01:00
CalamitousFelicitousness 7c364b4554 feat(civitai): route text encoder, unet, clip and detection downloads
Eight live ModelType values had no TYPE_MAP entry and fell into the
checkpoint folder, where a detection or encoder model shows up in the
model picker. TextEncoder, UNet, CLIP, CLIPVision and Detection get
their own folders; LLM, VisionLanguage and ComfyWorkflows have none and
are logged once per session.
2026-09-13 23:19:56 +01:00
CalamitousFelicitousness a1614e6b2d refactor(civitai): derive hidden base models from the enums endpoint
The civitai repo dropped base-model.constants.ts, so the GitHub fetch
404ed and every call lost the group and hidden flags. /enums carries
ActiveBaseModel next to BaseModel; the difference is the retired set the
hidden flag marked.
2026-09-13 23:19:56 +01:00
CalamitousFelicitousness 1701d6aa17 fix(civitai): route settings writes through the options setter
post_settings wrote opts.data directly, bypassing the __setattr__ hook
that files _token keys into secrets.json; a token saved through the
endpoint landed in config.json. The setter also applies the freeze and
restricted-key guards.
2026-09-13 23:19:56 +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 489cbf8048 lora: keep parsed network data through pipeline
Signed-off-by: Vladimir Mandic <mandic00@live.com>
2026-09-13 16:31:16 +02:00