fix(sampler): H3 audit — context windows and ALG guide blur off and hidden

Both are structurally inert on H3; context windowing also mis-reported the
cause as an old ComfyUI. alg_anchor deliberately kept: a continuation scene
carries real latent frames for it to act on.
This commit is contained in:
digital-garbage
2026-08-22 22:49:27 +03:00
parent dacfeeea0e
commit 13bcdb24f3
4 changed files with 87 additions and 1 deletions
+6
View File
@@ -99,6 +99,12 @@
looked exactly like one where the feature was switched off.
### Fixed
- **Context windowing and ALG's guide blur are switched off and hidden on MiniMax H3.**
Core's windowing unpacks the LTXAV stream specifically and measures its window on LTX's 8x
latent ratio; ALG's guide blur acts on guide frames appended to the latent, and an H3 guide
is a condition row, so that tail is always empty. Context windowing also reported the wrong
reason on H3 — it blamed the ComfyUI version for what is a model difference.
- **JoyAI-Echo is switched off and hidden on MiniMax H3, where it was doing damage.** The
memory bank places frame *i* at sequence position *i*, but H3's packed layout pins only the
first or last frame — so every frame past the first was refused, and the one that landed
+17 -1
View File
@@ -128,6 +128,14 @@
bounded_attention_enabled:
"Bounded Attention masks text cross-attention; H3 puts text in the same self-attention "
+ "stream as the video, where the mask would be far too large to hold.",
context_windows:
"Core's context windowing unpacks the LTXAV stream specifically — mapping each video "
+ "window onto its audio window and re-slicing the guide entries. H3 packs its sequence "
+ "by a different layout, and the window length is measured on LTX's 8x latent ratio.",
alg_blur_guides:
"This blurs the trailing GUIDE frames appended to the latent. On H3 a guide is a "
+ "condition row rather than an appended frame, so that tail is always empty. "
+ "(alg_anchor is NOT hidden — a continuation scene does carry real latent frames.)",
joyai_memory:
"JoyAI-Echo places memory frame i at sequence position i. H3's packed layout pins only "
+ "the FIRST or LAST frame, so every frame past the first is refused — and the one that "
@@ -135,6 +143,13 @@
+ "one is not merely inert on H3, it is harmful, so the sampler forces it off.",
};
// Sub-settings of the two groups above: they configure machinery that cannot run here.
const CONTEXT_SUB_INPUTS = [
"context_window_length", "context_window_overlap", "context_window_schedule",
"context_window_fuse", "context_window_freenoise", "context_window_retain_first",
];
const ALG_GUIDE_SUB_INPUTS = ["alg_guide_blur_strength", "alg_guide_blur_sigma_threshold"];
// JoyAI's own sub-settings: they configure a bank that cannot be built here.
const JOYAI_SUB_INPUTS = [
"joyai_memory_size", "joyai_fix_frames", "joyai_frame_select", "joyai_memory_strength",
@@ -182,7 +197,8 @@
if (!usesChainSampler(st)) return new Set();
if (!isH3(st)) return new Set(Object.keys(H3_ONLY_SAMPLER_INPUTS));
return new Set([...Object.keys(H3_DEAD_SAMPLER_INPUTS), ...IDENTITY_SUB_INPUTS,
...JOYAI_SUB_INPUTS, ...H3_DEAD_VALUE_INPUTS]);
...JOYAI_SUB_INPUTS, ...CONTEXT_SUB_INPUTS, ...ALG_GUIDE_SUB_INPUTS,
...H3_DEAD_VALUE_INPUTS]);
}
// Returns [{short, detail}] for settings that are ON but cannot do anything on H3.
@@ -93,3 +93,44 @@ test("JoyAI stays available on LTX", () => {
assert.ok(!inert.has(k), `${k} must remain reachable on LTX`);
}
});
// ── the rest of the H3 audit ──────────────────────────────────────────────────
test("context windowing and its settings disappear on H3", () => {
const inert = PC.familyInertInputs(h3);
for (const k of ["context_windows", "context_window_length", "context_window_overlap",
"context_window_schedule", "context_window_fuse",
"context_window_freenoise", "context_window_retain_first"]) {
assert.ok(inert.has(k), `${k} should be hidden on H3`);
}
});
test("ALG's GUIDE blur goes on H3 but its ANCHOR blur stays", () => {
// The guide blur acts on frames appended to the latent, and H3 guides are condition rows
// (tail always 0). The anchor blur acts on latent frame 0, which a continuation scene
// really does carry — hiding that one would neuter a knob that works.
const inert = PC.familyInertInputs(h3);
assert.ok(inert.has("alg_blur_guides"));
assert.ok(inert.has("alg_guide_blur_strength"));
assert.ok(inert.has("alg_guide_blur_sigma_threshold"));
assert.ok(!inert.has("alg_anchor"));
assert.ok(!inert.has("alg_anchor_strength"));
});
test("knobs that depend on the INSTALL, not the family, stay visible", () => {
// decode noise (which VAE), second pass / detailing (which upsampler) are reported at run
// time against the actual object. A family rule here would be a guess about a models folder.
const inert = PC.familyInertInputs(h3);
for (const k of ["decode_noise_scale", "decode_timestep", "second_pass_op",
"segmented_detailing", "plateau_cache"]) {
assert.ok(!inert.has(k), `${k} is install-dependent and must not be hidden by family`);
}
});
test("LTX keeps everything H3 cannot run", () => {
const inert = PC.familyInertInputs(ltx);
for (const k of ["context_windows", "alg_blur_guides", "joyai_memory",
"bounded_attention_enabled", "identity_transfer_enabled"]) {
assert.ok(!inert.has(k), `${k} must remain reachable on LTX`);
}
});
+23
View File
@@ -6062,6 +6062,16 @@ class FunPackLTXAVSceneChainSampler:
window the packed tensor blindly and quietly wreck audio and guides — the same class
of packed-vs-unpacked mistake that killed DynamicConditioning. Refuse instead.
"""
if self._is_h3:
# Checked BEFORE the capability gate below, which would otherwise report a
# missing LTXAV core feature and blame the ComfyUI version for what is really a
# model difference. Core's windowing unpacks LTXAV's packed AV stream and
# re-slices its guide entries; H3's sequence is packed by a different layout
# entirely, and the latent window length here is computed on LTX's 8x temporal
# ratio besides.
return None, None, ("MiniMax H3 has no context-window support — core's windowing "
"unpacks the LTXAV stream specifically, and the window length "
"is measured on LTX's 8x latent ratio")
try:
import comfy.context_windows as _cw
import comfy.patcher_extension as _pe
@@ -6680,6 +6690,15 @@ class FunPackLTXAVSceneChainSampler:
"against LTX's 4096-wide cross-attention context, and the overlap "
"tokens need LTX's patchifier; H3's native ref2va reference blocks "
"are the equivalent and are not wired yet)")
if context_windows:
_dead.append("context_windows (core's windowing unpacks the LTXAV stream and "
"re-slices its guide entries; H3 packs its sequence differently, "
"and the window length is measured on LTX's 8x latent ratio)")
if alg_blur_guides:
_dead.append("alg_blur_guides (it blurs the trailing GUIDE frames appended to "
"the latent; on H3 a guide is a condition row, so the appended "
"tail is always 0 and there is nothing to blur. alg_anchor still "
"works — a continuation scene does carry real latent frames)")
if joyai_memory:
_dead.append("joyai_memory / JoyAI-Echo (the memory bank places frame i at "
"sequence position i, and H3's packed layout pins only the FIRST "
@@ -6709,6 +6728,10 @@ class FunPackLTXAVSceneChainSampler:
# an LTX project must not keep doing that here.
joyai_memory = False
joyai_audio_memory = False
# These two only ever no-op on H3 — off here so the run report does not list a
# mechanism that did nothing.
context_windows = False
alg_blur_guides = False
v2a_grad_scale = 1.0
# second_pass_op is NOT switched off here. It only needs a latent upsampler that
# matches this model's latent width; which file that is depends on what is