Commit Graph
27 Commits
Author SHA1 Message Date
digital-garbage 41a75c3cd6 fix: server messages name the right Settings pages; effect, add-on, shot camera, LoRA, VAE, erase and SLA hints say what they do 2026-10-15 13:08:08 +03:00
digital-garbageandClaude Opus 5.5 8ce237dcdd feat: loader logs the file's real weight format (int8 file at bf16 says int8); warns when a cu12 torch on Blackwell halves int8 speed
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 18:34:58 +03:00
digital-garbageandClaude Haiku 5.5 77748b7a7e fix: dense steps '0' means none, as the tooltip and the earlier commit say (was flagged as a bad token)
Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
2026-10-10 16:15:51 +03:00
digital-garbageandClaude Haiku 5.5 78a418812b fix: SLA light references on comfy_kitchen pool in plain torch, so they run without Triton
Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
2026-10-10 16:13:15 +03:00
digital-garbageandClaude Opus 5.5 f313ed6ef6 fix: Triton SLA no longer falls back to dense when K arrives in another layout than Q
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 01:52:37 +03:00
digital-garbageandClaude Opus 5.5 71892d05fd fix: SLA dense steps count from 1 like a person does ('1' is the first; 0 means none in both fields); the run log names the steps that ran at full attention
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 01:49:15 +03:00
digital-garbageandClaude Opus 5.5 8fabfe3b3f feat: the model loader's fields read in order: file, storage, attention, then SLA as its choices narrow it
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 01:40:01 +03:00
digital-garbageandClaude Opus 5.5 fc92e5869b feat: the model loader shows each SLA field only in the mode it belongs to (sparsity for sla/vsa, tau for sol-attn, block size and stabilize for Triton, tail for comfy_kitchen)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 01:38:45 +03:00
digital-garbageandClaude Opus 5.5 8eaf5be5f4 feat: SLA method choice (sla / sol-attn / vsa via ComfyUI's Model Sparse Attention); first step dense by default; dense steps read from the schedule, so a cancel or a two-call sampler no longer shifts them
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 01:30:59 +03:00
digital-garbageandClaude Opus 5.5 91f9cdb70d feat: SLA gains comfy_kitchen's int8 sol_attn engine, precise word/audio protection, reference tiers, dense steps, block 32, tail, stabilize motion; later wrappers no longer skipped
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 01:00:58 +03:00
digital-garbageandClaude Opus 5.5 837a4215a4 fix: v4 regressions before the rental: taste judge trains under inference mode; LoRA keys unwrapped, misfits dropped, no-match said; unsupported dtype said; missed run finish read from history; prompt nudge no longer holds the model
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 03:08:29 +03:00
digital-garbageandClaude Sonnet 5.5 054f18a525 fix: Generate reads the live screen, not a save; autosave delay is a setting that waits for typing; H3 preset always carries a LoRA loader (None = untouched)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-04 15:51:40 +03:00
digital-garbageandClaude Sonnet 5.5 d3f43c31e5 fix: shot camera cut times, rating undo, locked memory, re-roll caching; int8 speed caveat declared
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-04 14:21:10 +03:00
digital-garbageandClaude Sonnet 5.5 b9717ed1cc feat: int8_convrot option on the diffusion model loader (H3 bf16 file -> int8 + rotation at load)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-04 14:09:24 +03:00
digital-garbageandClaude Sonnet 5.5 639b29e697 fix: LTX temporal styles scaled nothing (core hands the wrapper a bare frame_rate); identity transfer on guided latents; context-window overlap cut below the window; fault record survives model clones
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-03 11:08:28 +03:00
digital-garbageandClaude Sonnet 5.5 f41136e3e0 fix: learners teach only from pushes that were felt, per setup; sla counter ignores throwaway calls; camera frame change; shot memory amount 0
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-02 09:44:24 +03:00
digital-garbageandClaude Sonnet 5 06621bb2e3 docs: note has_block's contains-not-is limit on SLA's H3 gate
Round 2 of extensive_testing on 548d99a found no exploitable defect --
has_block's "contains, not is" semantics are shared with minimax_h3's
own equally consequential is_h3() gate, and nothing in this codebase
nests diffusion_model in a wrapper that could trigger a false positive
today. Recorded as a one-line limit rather than left implicit, per the
round's only (non-blocking) suggestion.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-15 15:24:29 +03:00
digital-garbageandClaude Sonnet 5 548d99a39b fix: SLA's H3 gate now matches the qualified class, not a bare name
Round 1 of extensive_testing on 79ca8cf found is_h3_model() matched on
diffusion_model's bare class name ("MiniMaxH3Model"), inherited
unchanged from v4. This codebase's own core/traits.py.has_block()
documents exactly why that's unsafe for a name this generic: a
same-named class from an unrelated custom node or a future FunPack
model would be silently treated as H3 and sparsified at 0.90 with
H3-specific audio-prefix pinning -- the identical LTX-collision risk
this file's own docstring already warns about, just not guarded
against strongly enough. modules/models/minimax_h3 already qualifies
its own identical check (MODEL_CLASS = the dotted path); this port
carried over the private, weaker duplicate instead of reusing that
pattern.

Switched to core/traits.py's has_block() with the same qualified dotted
name, kept as a local string (not an import of modules/models/minimax_h3
itself, which pulls in comfy_extras at import time -- this file
deliberately stays importable without ComfyUI on the path). Added a
test exercising the exact collision the bare match would have missed:
a class named MiniMaxH3Model from an unrelated module.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-15 15:20:51 +03:00
digital-garbageandClaude Sonnet 5 79ca8cfb6b feat: SLA block-sparse attention for MiniMax H3, ported from v4
Loader-level attention option: mean-pool Q and a smoothed K into
blocks, score them with one small matmul, attend only the top
1-sparsity fraction of key blocks per query block, via a vendored
Triton kernel. Runs alongside the chosen attention backend rather than
replacing it (one override slot; the backend becomes SLA's dense
fall-through for the text refiner, masked calls, and trailing dense
steps), and refuses cleanly -- naming why -- on anything that is not
MiniMax H3 or a machine without CUDA+Triton.

modules/loaders/sla_block_map.py and sla_kernel.py are near-verbatim
ports of v4's vendored files (no FunPack-specific imports, so nothing
to adapt); sla_attention.py is the loader-facing glue (H3 gate,
override composition, per-step wrapper), same content as v4's with a
"not a module" note added to match gguf_support.py's convention.
Wired into FunPackDiffusionModelLoader as six new optional widgets,
following v4's loaders.py wiring but expressed in v5's io.Schema style.

The Triton kernel itself is unexercisable on this Mac (no CUDA) --
matches how real generation is verified in this project (rented GPU,
not local). Ported the CPU-testable half of v4's test suite (the
override contract, the H3 gate, the per-step wrapper); the three
kernel-correctness tests carry the same CUDA+Triton skip guard v4 used.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-15 15:13:05 +03:00
digital-garbageandClaude Sonnet 5 776529e0d8 feat: assign category to every remaining module
The port plan calls for every module under modules/ to declare a
CATEGORY so Settings/Engine panels can group by it. Only alg, sharpen,
appearance, and full_control had one; the other 12 (loaders, empty
latent, media load, minimax_h3, output decode, sampling modifiers/
sampler, system pipeline) are plain infrastructure with no user-facing
settings dial, so they land in "system" except output_decode (post,
matching its STAGE) and the two sampling modules (sampling). Verified
against core/tests (548 passed) -- category validation and the
registry's field-mapping catch a typo here, per the earlier fixture-gap
fix.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-15 09:46:58 +03:00
digital-garbageandClaude Sonnet 5 7a226830b1 feat: GGUF loader support, and fix silent pipeline-editor state loss
GGUF: port v4's gguf_support.py (backend selection, content-based .gguf
detection, dequantize fallback) and wire it into both the diffusion-model
and CLIP loaders.

Pipeline editor: reopening the Models-and-pipeline settings window was
silently discarding the whole edited pipeline (a loaded preset, every
loader file, every sampler setting) because GET /api/pipeline is
deliberately stateless server-side and boot.js never fed its own
already-saved slots back into a freshly remounted editor -- found live
while walking through the MiniMax-H3 setup flow. Fixed by re-validating
the saved slots through check() on reopen instead of always replaying
the raw stateless default.

Also fixes, found via the extensive_testing adversarial loop over both
of the above: a stale file-listing cache in the pipeline window (no way
to see a newly-added model file without a full page reload), and a
chain of races/leaks in its own refresh/commit error-banner handling
that surfaced across five review rounds -- a rejection from a superseded
request overwriting a fresher success, a failure banner never clearing
on success, banners bleeding across groups on navigation, and a
commit()'s refusal landing on the wrong view after the user backs out
before it answers.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-11 18:14:46 +03:00
digital-garbageandClaude Opus 5 cf318c8c0d graph: the pipeline is slots, so a built-in node can be swapped or removed
v4 could not remove a built-in node from the pipeline and the reason was
structural: the wiring lived in code as a CORE dict nobody could reach, so
"remove this" had nothing to delete and "use a different one" had nothing to
change. Code is not a thing a user can edit.

The pipeline is now data. Three operations over it, each refusing with a
reason rather than half-doing the job:

build turns slots into the prompt ComfyUI queues, checking every link's type
and refusing a graph that cannot work. replace points a slot at any node
producing what its consumers read -- the built-in ones have no special
standing, which is what makes them replaceable rather than merely present.
remove takes a slot out and rewires what it fed to what fed it, when the
node has exactly one input matching each CONSUMED output; v4 required one
for every output a class could produce, so a spare FLOAT nobody wired made a
node unremovable.

Demonstrated against real schemas: FunPack's VAE loader swapped for core's
VAELoader, the modifiers node removed with the sampler rewired to read the
model directly, and removing the empty latent refused because nothing
upstream could feed what it fed.

Then run for real. The default pipeline, with three loader slots replaced by
one checkpoint slot, built from data, accepted by ComfyUI's own
validate_prompt, and executed by its own engine to execution_success and a
picture. Every wiring and type validated on the first attempt; the only
things ComfyUI objected to in the untouched default were the three unset
file pickers, which is correct -- a fresh install cannot know which model
you own.

Added a checkpoint loader, because the split loaders are right for LTX and
H3 and cannot read an SD-family single file at all.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-29 18:06:25 +03:00
digital-garbageandClaude Opus 5 74671329f9 log: a severity, a source, and a message
[Log] Info: FunPack Diffusion Model Loader | flux.safetensors loaded, attention sage
    [Log] Alert: MiniMaxH3ImageToVideo node | no "first_image" input is connected
    [Log] Warning: FunPack LoRA Loader | style.safetensors is empty and will not load
    [Log] Critical: torch | cannot allocate 14 GB (3 GB free); the run will not start

The difference between the middle two is the one that matters. Alert is a
choice you may not have made on purpose. Warning is something that will NOT
do what its name says -- the level v4 needed and did not have, which is how
560 handlers came to swallow a failure and carry on, so a feature could be
switched on, do nothing, and never say so.

Info is not decoration either: "loaded on GPU using sage attention" is how
an attention setting that did nothing gets noticed months before the
pictures look wrong enough to investigate.

Every call site moved -- there is no note() left to be vague through -- and
the loaders now say what they actually loaded rather than only what they
were asked for. Records are kept in a bounded ring as well as printed, so a
long rental session cannot turn the log into a memory leak, and served at
/funpack/api/log so a person can read it somewhere other than a terminal
full of ComfyUI's own output. There is a page for it.

Also dropped the preflight this was traded for: min and max are already
declared and already enforced at both doors, and a second protection layer
around a check that exists is ceremony.

Two mistakes worth keeping: a log line reached into the model's shape to
describe it and could have failed the load it was only narrating; and both
new pages passed `children` to an element that takes `rows`, which the kit
accepted and silently dropped. It throws on an unknown element and not on an
unknown prop.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-29 17:09:33 +03:00
digital-garbageandClaude Opus 5 20a4c39db3 loaders: compute_dtype cast the input and left the weights behind
set_model_compute_dtype sets force_cast_weights on purpose: it is what
casts each layer's weights to match. Clearing it afterwards left the model
casting its INPUT to the chosen dtype while the weights stayed as loaded,
so the first Linear of the first sampling step raised "mat1 and mat2 must
have the same dtype".

Picking any compute dtype other than default therefore broke sampling on a
full-VRAM load. It survives on constrained hardware only because the
low-VRAM path forces the cast back on by itself, which is why nobody hit it.

Straight port from v4, where the same line has shipped since 3837f8f. The
branch had no test at all; it now has one that fails against the old line.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-29 12:06:45 +03:00
digital-garbageandClaude Opus 5 e272a3b443 loaders: three the attacker found, and the silence around one of them
A backend that carries a zero-copy container path lost it: wrap_attn offers
that path only when the OVERRIDE has the attribute, so dropping it selects
the backend, computes the right answer, and never uses the thing the backend
exists for. ComfyUI forwards it in set_model_optimized_attention; now so do we.

An unknown encoder family fell back to stable_diffusion and reported success.
A family mismatch in this project reads as an unrelated fault, so it refuses
and lists what this ComfyUI actually knows.

fp16 accumulation is one flag for the whole interpreter, so a per-node
checkbox cannot mean "this model": a second loader changes the first model's
maths, and loader caching outlives the run. It cannot be scoped, so it is at
least no longer silent -- every transition says what it really covers. The
honest fix is to move it to a machine-level setting.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-29 03:41:04 +03:00
digital-garbageandClaude Opus 5 ab9cbdb556 loaders: the four FunPack loaders, as V3 nodes
Ported from v4, minus two mechanisms that are no longer needed. The LoRA
loader takes one LoRA and chains, so the FlexibleOptionalInputType dict
subclass that lied to ComfyUI's validator has nothing left to do. The CLIP
loader uses numbered slots like core's DualCLIPLoader instead of a JSON
array in a string widget.

Autogrow looked like the right answer for the encoder list and is not: it
sets force_input on any widget input, so a list of combos renders as sockets
and the file picker stops being a picker. Every core use of it is a
connection type.

GGUF and SLA are deliberately not here. Both are capabilities rather than
loader options, and both belong in modules of their own.

The tests follow what the loaders PRODUCE rather than stopping at the call:
the attention override is carried into comfy's real dispatch and checked
against every backend this machine registers, because an override that only
fails at the first attention call fails at sampling, not at load.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-29 03:32:06 +03:00
digital-garbageandClaude Opus 5 7330ba0c18 core: nodes are announced by modules, like everything else
ComfyUI's V3 entrypoint replaces NODE_CLASS_MAPPINGS, which must not exist
at all: nodes.py checks it first and reaches comfy_entrypoint only in an
elif, so an empty dict registers nothing and reports no error.

A module declares NODES for graph structure and SETTINGS for preferences,
and the two never mix -- a saved workflow stores class_type and input
names, so letting a new setting add a socket would rot existing graphs.

Traits now come from two places: facts core can read off any model, and
providers announced by a model's own module. Core names no model, so
supporting a new one is a folder rather than an edit here.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-29 03:03:19 +03:00