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:
@@ -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
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user