record(LTX25-PROMPT-ADALN): the prompt-AdaLN defect was understated ~138x, and the keyframes claim next door was false (#644) - #663
Open
localai-bot wants to merge 6 commits into
Open
Conversation
`use_prompt_adaln_single` defaults TRUE in both references — diffusers `transformer_ltx2.py:1185` and LTX-2 `model.py:77` / `model_configurator.py:76,138` — and the shipped FP8 DiT carries the 18 tensors the flag builds. `ltx2_loader.cpp:988` (and `:573`, `:626`) cleared it unconditionally, so every render kept only the static `prompt_scale_shift_table` and dropped the timestep-conditioned half of the prompt K/V modulation. Shapes, finiteness and every committed golden agree with the defect, because the goldens were generated with the flag OFF. Spec only; no code. Records the upstream anchors for the module (`model.py:222-227`, `:252-257`), the producer (`transformer_args.py:274-277`, driven by `modality.sigma` and NOT `timesteps`), the consumer (`transformer.py:441-446`), and what replaces the cleared flag so `allow_unported_modules` can no longer silently disable a ported feature. Issue #644, row 0. FOLLOWING_AGENTS_PROTOCOL Following-Agents-Protocol: true AI-Assisted: true Assisted-by: AGENT:claude-opus-5 [Claude Code]
…learing it
`use_prompt_adaln_single` defaults TRUE in both references — diffusers
`transformer_ltx2.py:1185`, LTX-2 `model.py:77` and
`model_configurator.py:76`/`:138` — and the shipped DiT carries the module's
tensors. `ltx2_loader.cpp` cleared it in three places, so every render kept
only the static `prompt_scale_shift_table` and dropped the
timestep-conditioned half of the prompt K/V modulation. Nothing saw it:
shapes unchanged, values finite, and every committed golden was generated
with the flag OFF.
MEASURED, flag ON vs OFF over the same shared weights: the timestep term is
51.7% the magnitude of the static table it is added to, moves the block-0
modulated prompt K/V by 5.82%, and moves the DiT output by 1.46e-4 — 73x the
gate's f32 floor.
Ported, citing what each piece came from:
the module <- model.py:222-227 (video), :252-257 (audio);
AdaLayerNormSingle(dim, embedding_coefficient=2), adaln.py:19-45
the producer <- transformer_args.py:274-277 driven by `modality.sigma`
[batch] and NOT the per-token `timesteps`, scaled by
timestep_scale_multiplier at :173-186
the consumer <- transformer.py:441-446, summed into the table BEFORE
`(1 + scale)` applies, threaded per stream at :288-296/:317-325
diffusers twin <- transformer_ltx2.py:1536-1547, :1648-1649, :677-693
Both arms: `Ltx2DitForward` and `Ltx2DitForwardDevice` (f32 and the bf16
production stream).
The three `= false` assignments are replaced by an invariant: the resolved
flag must equal whether the FILE carries `prompt_adaln_single`. And
`Ltx2AdoptDeclaredDitParams` now clears exactly ONE flag in its config copy —
`use_keyframes_abs_pos_embedding`, whose module really is unported — so
`allow_unported_modules=1`, which a real render still needs, can no longer
switch a ported feature off. A config that disagrees with the shapes about
the flag is refused rather than forced into agreement.
Both shipped DiTs were re-read off the NAS to check this refuses neither: the
FP8 file carries no `__metadata__` at all and the NVFP4 file's config OMITS
the key, so upstream's TRUE default decides on both, matching their tensors.
Evidence. Goldens executed from upstream LTX-2 @fd4ded7f at reduced dims
(`gen-ltx2-goldens.py` section 6); every pre-existing golden VALUE is
byte-identical. Five mutations, each RED and each restored byte-for-byte:
dropping the term host-side (3/35 cases), dropping it device-side (1/15),
re-adding the cleared flag (the guard throws; assertion count drops
4826->4815), driving the MLP from `timesteps` instead of `sigma` (2/35), and
swapping the shift and scale rows (2/35). A permanent in-tree case asserts
the flag-ON forward MISSES the flag-OFF golden, so a bound-but-unused module
cannot pass.
Suites vs `cefacd2d0`: test_ltx2 30/1627 -> 35/2435, test_ltx2_loader
24/4817 -> 26/4826, test_ltx2_device 13/498 -> 15/523, test_ltx2_video
30/502 -> 30/502 (its fixture now carries the module, which is the shipped
shape). Full `ctest` 423 registered, 422 pass under -j8 and
`test_serve_low_tools` passes on its serial re-run.
Spec .agents/specs/ltx25-prompt-adaln.md @baa92ccf7. Issue #644, row 0.
FOLLOWING_AGENTS_PROTOCOL
Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [Claude Code]
Brings in b81a5e4 (the secondary-oracle registry). No conflict and no overlap with this row's files; rebuilt clean and re-ran the full gate after the merge, because a clean merge is not a compiling one: BUILD_EXIT=0, ctest 423/423. FOLLOWING_AGENTS_PROTOCOL Following-Agents-Protocol: true AI-Assisted: true Assisted-by: AGENT:claude-opus-5 [Claude Code]
…138x, and the keyframes claim next door was false (#644) The port landed and reviewed PASS. What we WROTE about it did not. ## The headline numbers were fixture artifacts The spec Outcome, the PR body and test_ltx2.cpp all quoted 51.7% ("term vs table") and 5.82% (block-0 K/V) as the answer to "does this matter". Both come from the generator's synthetic init: `prompt_scale_shift_table` AND every prompt-AdaLN MLP parameter are drawn from the same `param_spec` rule at scale=0.05 (gen-ltx2-goldens.py:100-106), so the ratio between them is a property of the FIXTURE. It moves with the init scale: 0.005 gives 4.1%, 0.2 gives 1450%. The Outcome disclaimed only the two OUTPUT rows as synthetic-bounded and then called the other two the answer, though all four have identical provenance. Measured on the SHIPPED weights instead, through upstream's own AdaLayerNormSingle(dim, embedding_coefficient=2) evaluated on sigma*1000 exactly as transformer_args.py:274-278/:177 do, against all 48 prompt_scale_shift_table tensors of `ltx-2.5-22b-distilled-transformer-nvfp4.safetensors`: video audio rms|table| (48 blocks) 0.017553 0.021925 rms|term| (uniform s) 0.236446 0.347171 term/table RMS 1347% 1583% max|term|/max|table| 7119% 2817% Like for like -- 51.7% is a max-vs-max ratio, and the same ratio on the real weights is 7119% / 2817% -- the fixture UNDERSTATED the defect by 138x (video) and 54x (audio). On the shipped model the timestep term DOMINATES the static table; the table is the perturbation. Pre-row renders applied `context*(1 + ~0.018 rms) + ~0.018` where upstream applies `context*(1 + ~0.32 rms) + ~0.10`; on a unit-rms context the modulated context moves +8.8% (video) / +31.3% (audio). Both dispositions the finding offered are taken: the four fixture rows are now labelled GATE-FLOOR numbers from synthetic weights in the spec, the goldens' comment block and test_ltx2.cpp, AND the real-checkpoint measurement is stated as the answer. `scripts/measure-ltx2-prompt-adaln.py` is committed so the number is re-runnable rather than transcribed; it asserts `ltx_core.__file__` under the named checkout before reading anything. ## A false claim about a checkpoint, the same class this row just fixed ltx2.h:47-49 -- a line surviving inside the paragraph this row rewrote -- said "LTX-2.5's checkpoint does not carry the parameter" about keyframes_abs_pos_embedding. Both shipped DiTs contradict it, each on a different half, read off their headers and run through upstream's own configurator: FP8 (vonkaiser): CARRIES keyframes_abs_pos_embedding F8_E4M3 [1,4096] + scale, and declares NO __metadata__ at all -- so LTXModelConfigurator.from_metadata cannot configure it: KeyError: 'caption_channels', raised by _build_caption_projections on the empty dict, BEFORE the flag at model_configurator.py:82 is ever read. NVFP4 (1st-party): DECLARES the flag true and does NOT carry the tensor, so the parameter stays torch.zeros(1, inner_dim) (model.py:217-219) through load_state_dict(..., strict=False) (single_gpu_model_builder.py:98) -- a genuine no-op there. It is also not keyframe-only: transformer_args.py:269 applies it on every prepare whose keyframes_mask is set, and tools.py:186-196 sets that mask unconditionally. REFUSAL KEYING: unchanged, deliberately. It fires on the TENSORS the file carries. Keying it on the resolved flag would, on the FP8 DiT, read a DEFAULT rather than the file -- that file declares nothing -- and load it while silently discarding a trained [1,4096] parameter. No behaviour changed, so no new gate is owed; three refusal MESSAGES changed, because they asserted an implication that is false in both directions. ## Records the lifecycle change did not move model-matrix.md's inventory row still listed "timestep-INDEPENDENT prompt K/V (cacheable once per request)" -- precisely what this row disproved. docs/STATUS.md's LTX-2.5 row did not mention the prompt-side AdaLN at all; FEATURES.md and USAGE.md described the keyframes opt-in as if only one file were involved. ## Two things recorded honestly rather than fixed - test_ltx2_video's shipped-checkpoint case is env-gated on LTX2_CHECKPOINT_ROOT and SKIPS by default, so the row's "unchanged 30/502" meant the whole real-header case did not run. With the variable set the same binary measures 30/8734 -- verified here, exit 0 both ways. Noted in the spec and at the skip site. - Upstream loads with strict=False, so a config declaring the prompt-AdaLN flag false over a file that carries the module would silently run flag-OFF upstream where we now refuse. Ours is better; it is a DOCUMENTED DIVERGENCE, not a mirror, and it is named as one. ## Gate BUILD_EXIT=0; build logs grepped for `No space left|BFD assertion` (0 hits); df -h / 92% used, 37G free. ctest -N = 423; full ctest -j8 422/423 with test_serve_low_tools starved under -j (known parallel flake), 1/1 PASS serially, exit 0; 2 skipped as on the baseline. Suite counts unchanged from the row: test_ltx2 35/2435, test_ltx2_loader 26/4826, test_ltx2_device 15/523, test_ltx2_video 30/502 (skipped default) and 30/8734 with the checkpoint root. ltx2_goldens.inc REGENERATED from gen-ltx2-goldens.py against ltx_core fd4ded7f: every golden VALUE byte-identical, the diff is the comment block alone. An earlier full run was VOIDED rather than reported: another session's disk-pressure cleanup deleted build/ while ctest was at 421/423 and the last two tests recorded "Not Run -- Failed to change working directory". A run whose tree vanished under it is not a result; it was rebuilt and re-run from scratch. One finding detail did not hold on inspection: it cited `.agents/model-matrix.md:98` as already saying the two DiTs "differ in a TRAINED keyframes_abs_pos_embedding". That file contains no occurrence of "keyframes" at all on this branch; the corroborating anchors are `.agents/specs/ltx-2-5.md` section 3.1 and `tests/vllm/multimodal/test_ltx2_video.cpp:913-914`. FOLLOWING_AGENTS_PROTOCOL Following-Agents-Protocol: true AI-Assisted: true Assisted-by: AGENT:claude-opus-5 [Claude Code]
This was referenced Aug 13, 2026
…d device-leakage red (#644) The head was behind and inherited a `check-device-leakage` FAIL it did not cause: `kcuda=2 > baseline 0`, both hits in `src/vllm/multimodal/ltx2_video.cpp:532,549` — a file this branch does not touch, present at the parent `968461cda` and already fixed on `main` by `11cc1d589`. Merging is the whole repair; no edit of mine was needed and none was made. `check-device-leakage` before: FAIL, `kcuda=2`. After: OK, `kcuda=0`, DSR 32 == baseline 32. RESOLUTION, recorded because it was NOT a plain auto-merge. This branch's base row `row/LTX25-PROMPT-ADALN` was SQUASHED onto main as `65e79eee5`, so the merge base predates the squash and git reports add/add conflicts on files where both sides carry identical content. Resolved deterministically rather than hunk by hunk: the tree was set to `origin/main` wholesale (`git read-tree -u --reset origin/main`), then this branch's single commit `968461cda..2990ed8` was reapplied on top with `git apply --3way`. All 14 paths applied cleanly. VERIFIED, not assumed: `git diff origin/main` on the resolved tree is byte-identical to `git diff 968461c 2990ed8` except for two hunk-header line offsets (`.agents/model-matrix.md` 429->445, `tests/vllm/multimodal/test_ltx2_video.cpp` 913->925) where main's own later edits shifted the file. The four paths BOTH sides changed — `.agents/model-matrix.md`, `docs/FEATURES.md`, `docs/STATUS.md`, `tests/vllm/multimodal/test_ltx2_video.cpp` — were each inspected directly: main's content intact, this branch's edit present exactly once, no duplicated relocation. FOLLOWING_AGENTS_PROTOCOL Following-Agents-Protocol: true AI-Assisted: true Assisted-by: AGENT:claude-opus-5 [Claude Code]
…not zeroed, and the audio factor had the wrong denominator (#644, #673) Review findings F-1 and F-2 on PR #663. The reviewer re-ran every measurement in that PR and every published digit reproduced; this repairs the two claims that did not. ## F-1 (blocking) — a claim about upstream that upstream's own code contradicts Three places said that on the NVFP4 DiT the absent `keyframes_abs_pos_embedding` means the parameter "keeps `torch.zeros(1, inner_dim)` (model.py:217-219) through `load_state_dict(..., strict=False)` (single_gpu_model_builder.py:98) — a genuine no-op there": `include/vllm/model_executor/models/ltx2.h` (THE PRODUCT TREE), the spec, and the PR body. IT IS NOT A NO-OP. The claim quoted `single_gpu_model_builder.py:98` while dropping the `assign=True` that is on that same line, and upstream builds on the META DEVICE -- `loader/helpers.py:84-95`, `create_meta_model`: `with torch.device("meta"): configurator.from_metadata(...)` at `:90-91`. A key absent from the state dict is therefore never materialised at all. RUN HERE, not transcribed, through upstream's own `create_meta_model` on the shipped file's real `__metadata__` (read with upstream's own `read_model_metadata` / `SafetensorsModelStateDictLoader`, sft_loader.py:58-74, which JSON-decodes each value -- the flag lives at `config.transformer`, not at the top level, so a raw `__metadata__` read returns None for it): keys matching 'keyframes_abs_pos' in the file : [] (0 of 7876 entries) config.transformer['use_keyframes_abs_pos_embedding'] = True keyframes_abs_pos_embedding: shape=(1, 4096) f32 device=meta is_meta=True supports_keyframes_abs_pos_embedding (BEFORE load) : False after load_state_dict(sd, strict=False, assign=True): neighbour patchify_proj.weight : device=cpu is_meta=False <- materialised keyframes_abs_pos_embedding : device=meta is_meta=True in missing_keys : True reading the value RAISES : RuntimeError: Tensor.item() cannot be called on meta tensors supports_keyframes_abs_pos_embedding (AFTER load) : False Upstream states this itself and then never asks. `supports_keyframes_abs_pos_embedding` (model.py:166-173) returns False for "a model whose config set the flag but whose checkpoint carried no weight for it (the parameter would still be on ``meta``)" (:170), and `enable_keyframes_abs_pos_embedding` (model.py:175-200) exists because such a parameter "would fail at the first forward" (:182). BOTH ARE DEFINED AND NEVER CALLED: `grep -rn` over the whole Lightricks/LTX-2 checkout at fd4ded7f returns exactly 1 hit each, the definition, re-confirmed here against a positive control rather than asserted from a null grep. Polarity is not what fails: `apply_keyframes_absolute_embedding` is `hidden_states + mask * embedding` (transformer_args.py:23-43, the sum at :43), so REAL zeros would be inert. The mechanism claim fails on `meta`, not on additivity. This STRENGTHENS the row's conclusion and changes nothing downstream: the refusal stays keyed on TENSOR PRESENCE for the FP8 file, and the NVFP4 file is refused by FLAG in `ParseLtx2DitParams` (ltx2.cpp:192-198). NOTHING RUNTIME CHANGED IN THIS COMMIT. `ltx2.h` and `test_ltx2.cpp` move comment text only; the one script edit (`gen-ltx2-goldens.py`) alters only the COMMENT the generator emits; `ltx2_goldens.inc` moves two comment lines with every value byte-identical. No `src/` file is touched at all. Suite counts are therefore expected to be identical, and the point of the gate below is that they are. The same anchor is now quoted in full at the OTHER place it appears (the documented-divergence bullet), because dropping the `assign=True` is precisely what made the claim above wrong. ## F-2 — the audio factor's denominator The Outcome read "138x (video) and 54x (audio)" as if both were per-stream. The video figure is right and like-for-like. The audio one divided the shipped AUDIO ratio by the VIDEO fixture denominator, because `gen-ltx2-goldens.py` emits exactly ONE fixture ratio and it is the video stream's. 54x is literally true about that single published figure and errs CONSERVATIVE. Recomputed by IMPORTING the generator, so the weight stream is bit-identical and no weight is re-drawn: video: max|term| = 0.0252012 max|table| = 0.0487142 -> 51.7327% (7119/51.73 = 137.6x) audio: max|term| = 0.0201763 max|table| = 0.0496868 -> 40.6068% (2817/40.61 = 69.4x) FIXED AT THE SOURCE, not only in prose. The generator emitted BOTH video-only rows unlabelled -- "timestep term vs static table" and "block 0 modulated prompt K/V" -- which is exactly how a video denominator came to be applied to an audio numerator. `gen-ltx2-goldens.py` now names the stream on both, and `ltx2_goldens.inc` was REGENERATED against ltx_core fd4ded7f to carry them (REGEN_EXIT=0). The regeneration diff is those two comment lines and NOTHING else: every golden VALUE byte-identical, and the "Regenerate with:" header unchanged because the committed command was re-run verbatim -- so this re-proves provenance as well as the labels. The Outcome now carries a per-stream table with each row against its own denominator, and `test_ltx2.cpp` and the spec's gate-floor table say which stream they mean. No fifth golden was added: the audio figure is a denominator for this record, not a gate floor, so "ALL FOUR ROWS ARE GATE-FLOOR NUMBERS" still holds and the three files that label those four are otherwise untouched. ## Recorded, not fixed — issue #673 `LTX2_CHECKPOINT_ROOT` is set by NO workflow: `grep -rn CHECKPOINT_ROOT .github/` exits 1 with zero hits while the same pattern matches in `tests/` and `.agents/` (positive control run in the same command). CI therefore executes 502 of 8734 assertions -- 5.7% -- of `test_ltx2_video`, at an UNCHANGED case count of 30, and `scripts/measure-ltx2-prompt-adaln.py` is a manual tool no gate invokes. This row's checkpoint-derived evidence is manual and host-local. Filed as visible debt and linked in the roadmap issue table and the spec; wiring checkpoints into CI is explicitly not in this row. ## No test asserts this text, and none was invented Searched in the subject's own vocabulary: the corrected claim lives only in a `ltx2.h` comment, the spec and the PR body. The runtime refusal MESSAGES (`ltx2.cpp:195-198`, `ltx2_loader.cpp` `RefuseUnported`) never carried the "zeros"/"no-op" implication, and no checker reads the header comment. Writing a test here would be writing one that cannot fail, so this change adds none. The tensor-keyed refusal it defends is already pinned by a mutation the reviewer ran: making `LoadedElsewhere` swallow the tensor takes `test_ltx2_loader` to 25/26 cases, 4817/4818 assertions, exit 1. FOLLOWING_AGENTS_PROTOCOL Following-Agents-Protocol: true AI-Assisted: true Assisted-by: AGENT:claude-opus-5 [Claude Code]
localai-bot
pushed a commit
that referenced
this pull request
Aug 13, 2026
…-- retire that refusal, apply nothing (#658) FOLLOWING_AGENTS_PROTOCOL The spec recorded a live disagreement for the implementer to settle: one reviewer read the NVFP4 arm's `keyframes_abs_pos_embedding` as zero-initialized and therefore an exact no-op; another said it stays on the meta device. Both readings are consistent with the source. Only one is consistent with what runs, and an implementer on the sibling row (#663) has now RUN it, using upstream's own `create_meta_model` and its own metadata reader rather than a hand-rolled probe: keys matching 'keyframes_abs_pos' in the file : [] (0 of 7876 entries) config.transformer['use_keyframes_abs_pos_embedding'] = True keyframes_abs_pos_embedding: shape=(1, 4096) device=meta is_meta=True supports_keyframes_abs_pos_embedding (BEFORE load) : False after load_state_dict(sd, strict=False, assign=True): neighbour patchify_proj.weight : device=cpu is_meta=False <- materialised keyframes_abs_pos_embedding : device=meta is_meta=True in missing_keys : True reading the value RAISES : RuntimeError: Tensor.item() cannot be called on meta tensors supports_keyframes_abs_pos_embedding (AFTER load) : False The materialised NEIGHBOUR is what makes the result mean anything: the loader ran and populated the model, and only the absent key stayed on `meta`. Without that control the transcript would be equally consistent with a loader that did nothing. So on the first-party NVFP4 DiT upstream never reaches the add at all. The correct mirror there is to LOAD AND APPLY NOTHING -- neither the refusal `ltx2.cpp:192` raises today, which is stricter than upstream, nor a synthesised zero, which would invent the behaviour `supports_...` exists to prevent. The row retires that refusal outright, and section 6 now names the tempting middle option as the risk rather than leaving it open. One narrow consequence, stated narrowly so it is not over-read: a render taken on the NVFP4 DiT with `allow_unported_modules` is upstream-equivalent FOR THIS MODULE ONLY. It says nothing about the render as a whole. Also corrected here: the guards are `model.py:166-173` and `:175-200`, not `167-182`/`175-193`; and the flag is NOT at the top of `__metadata__` -- a raw read returns None, it lives at `config.transformer`, which is why upstream's JSON-decoding reader is needed to see it at all. Following-Agents-Protocol: true AI-Assisted: true Assisted-by: AGENT:claude-opus-5[1m] [claude-code]
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Claims-and-records repair for #644, on top of #654. The port itself is untouched
— reviewed PASS, and nothing executable changes here except three refusal
messages.
F1 — the headline numbers were fixture artifacts, and the truth is far worse
The spec Outcome, #654's body and
tests/vllm/models/test_ltx2.cppall quoted51.7% ("term vs table") and 5.82% (block-0 K/V) as the answer to "does
this matter". Both come from the generator's synthetic init: the static
prompt_scale_shift_tableand every prompt-AdaLN MLP parameter are drawnfrom the same
param_specrule atscale=0.05(
scripts/gen-ltx2-goldens.py:100-106), so the ratio between them is a propertyof the FIXTURE — it moves with the init scale (0.005 → 4.1%, 0.2 → 1450%). The
Outcome disclaimed only the two OUTPUT rows as synthetic-bounded and then called
the other two the answer, though all four have identical provenance.
Re-measured here on the shipped weights, through upstream's own
AdaLayerNormSingle(dim, embedding_coefficient=2)evaluated onsigma * 1000exactly as
transformer_args.py:274-278/:177do, against all 48prompt_scale_shift_table/audio_prompt_scale_shift_tabletensors of/mnt/nas_share/checkpoints/ltx-2.5/lightricks-ltx-2.5/diffusion_models/ltx-2.5-22b-distilled-transformer-nvfp4.safetensors,with
ltx_coreatfd4ded7fimported by path and its__file__asserted:rms|table|, 48 blocksrms|term|, uniform σ∈[0,1]max|term|/max|table|Like for like — the fixture ratio is max-vs-max and so is the shipped one —
per stream, each against its OWN fixture denominator:
max|term|/max|table|prompt_adaln_singlevsprompt_scale_shift_table)audio_prompt_adaln_singlevsaudio_prompt_scale_shift_table)On the shipped model the timestep term DOMINATES the static
table; the table is the perturbation. Pre-row renders applied
context*(1 + ~0.018 rms) + ~0.018where upstream appliescontext*(1 + ~0.32 rms) + ~0.10; stated as the quantity actually consumed attransformer.py:446, on a unit-rms context the modulated context moves +8.8%(video) and +31.3% (audio).
Both dispositions the finding offered are taken. The four fixture rows are
now labelled GATE-FLOOR numbers from synthetic weights — in the spec, in the
goldens' emitted comment block, and in
test_ltx2.cpp— and thereal-checkpoint measurement is stated as the answer to "does this matter".
Labelling alone would have left the spec with no answer to its own §6 question;
stating the real numbers alone would have left four unlabelled fixture ratios in
three files for someone to re-quote.
scripts/measure-ltx2-prompt-adaln.pyis committed so the number is re-runnablerather than transcribed.
F2 — a false claim about a checkpoint, the same class this row just fixed
ltx2.h:47-49, a line surviving inside the paragraph #654 rewrote, said "LTX-2.5'scheckpoint does not carry the parameter" about
keyframes_abs_pos_embedding.Verified independently against both files' headers and upstream's own loader:
vonkaiser)F8_E4M3 [1, 4096]+ F32 scale__metadata__AT ALLtrueLTXModelConfigurator.from_metadataKeyError: 'caption_channels'[1, 4096]Two corrections to the reasoning that came with the finding, both measured:
Falseatmodel_configurator.py:82". Upstream never reaches line 82 on it —_build_caption_projectionsindexescaption_channelson the empty configfirst and raises. That file ships no config at all, so what its flag resolves
to is decided entirely out of band, and the tensor it carries is trained.
absent — 0 of its 7876 entries match
keyframes_abs_pos. What that leaves isan UNMATERIALISED META PARAMETER, not a silent zero.
Confirmed too that it is not keyframe-only:
transformer_args.py:269applies iton every
preparewhosekeyframes_maskis set, andtools.py:186-196setsthat mask unconditionally on the first latent frame.
Refusal keying: UNCHANGED, deliberately.
RefuseUnportedfires on theTENSORS the file carries. Keying it on the resolved flag would, on the FP8 DiT,
read a DEFAULT rather than the file — that file declares nothing — and load it
while silently discarding a trained
[1, 4096]parameter. Tensor presence is theonly signal that file actually carries. No behaviour changed, so no new gate is
owed; three refusal MESSAGES changed, because they asserted an implication that
is false in both directions.
F3 — records the lifecycle change did not move
.agents/model-matrix.mdstill listed "timestep-INDEPENDENT prompt K/V(cacheable once per request)" — precisely what the row disproved.
docs/STATUS.mddid not mention the prompt-side AdaLN. Added inside theSHRINK-ONLY ratchet: the cell went 218 → 217 chars and
check-public-doc-tables.pystays green atoversized_cells: 44.docs/FEATURES.mdanddocs/USAGE.mddescribed the keyframes opt-in as if onefile were involved; both DiTs need it, for different reasons.
One finding detail did not hold. It cited
.agents/model-matrix.md:98asalready saying the two DiTs "differ in a TRAINED
keyframes_abs_pos_embedding".grep -n keyframes .agents/model-matrix.mdreturns nothing on this branch. Thecorroborating anchors are
.agents/specs/ltx-2-5.md§3.1 andtests/vllm/multimodal/test_ltx2_video.cpp:913-914.The two LOW notes, recorded honestly
test_ltx2_video's shipped-checkpoint case is env-gated onLTX2_CHECKPOINT_ROOTand SKIPS by default, so "unchanged 30/502" meant thewhole real-header case did not run. With the variable set the same binary
measures 30 / 8734 — verified here, exit 0 both ways. Recorded in the spec's
gate table and at the skip site, so the next quote carries its configuration.
Now also filed as #673:
LTX2_CHECKPOINT_ROOTis set by no workflow —grep -rn CHECKPOINT_ROOT .github/exits 1 with zero hits while the same pattern matches intests/and.agents/(positive control in the same command) — so CI executes 502 of 8734assertions, 5.7%, at an unchanged case count of 30, and
scripts/measure-ltx2-prompt-adaln.pyis a manual tool no gate invokes. Thisrow's checkpoint-derived evidence is therefore manual and host-local.
Recorded as visible debt; wiring checkpoints into CI is explicitly not in scope
here.
strict=False, assign=True(
single_gpu_model_builder.py:98— quoted in full, because dropping theassign=Trueis exactly what made the keyframes claim above wrong), so aconfig declaring the prompt-AdaLN flag false over a file that carries the
module would silently run flag-OFF upstream where we now refuse. Ours is
better; it is a documented divergence, not a mirror, and is named as one
alongside the tensor-keyed keyframes refusal.
F4 — the branch was behind, and inherited a red it did not cause
check-device-leakageFAILED on the head:kcuda=2 > baseline 0, both hits insrc/vllm/multimodal/ltx2_video.cpp:532,549— a file this diff does not touch,present at the parent
968461cdaand already fixed onmainby11cc1d589.Merging
origin/mainis the whole repair; no edit of mine was needed and none wasmade. Before: FAIL,
kcuda=2. After: OK,kcuda=0, DSR 32 == baseline 32.The merge was not a plain auto-merge and the resolution is recorded in its own
commit message. This branch's base row
row/LTX25-PROMPT-ADALNwas SQUASHED ontomain as
65e79eee5, so the merge base predates the squash and git reportedadd/add conflicts on files where both sides carry identical content. Resolved
deterministically: the tree was set to
origin/mainwholesale(
git read-tree -u --reset origin/main), then this branch's single commit968461cda..2990ed81bwas reapplied withgit apply --3way. Verified, notassumed —
git diff origin/mainon the resolved tree is byte-identical togit diff 968461cda 2990ed81bexcept two hunk-header line offsets where main'sown later edits shifted the file. The four paths BOTH sides changed
(
model-matrix.md,FEATURES.md,STATUS.md,test_ltx2_video.cpp) were eachinspected directly: main's content intact, this branch's edit present exactly
once, no duplicated relocation.
windows-msvc-cpu/windows-msvc-vulkanare red on every open PR in the repofrom a separate cause, tracked as #664 and being fixed on
row/FIX-WINDOWS-POSIX-VIDEO-ENGINE. Not chased here, andsrc/vllm/multimodal/video_engine.cppis untouched.Gate
Nothing runtime changed.
ltx2.handtest_ltx2.cppmove comment text only;the one script edit (
gen-ltx2-goldens.py) alters only the COMMENT the generatoremits;
ltx2_goldens.incmoves two comment lines with every value byte-identical.No
src/file is touched at all — so identical suite counts are the expectedresult and the point of measuring them.
BUILD_EXIT=0on a clean Release configure of the merged head; build log greppedfor
No space left|BFD assertion— 0 hits;warning:|error:— 0 hits.ctest -N= 423.Suite counts, unchanged from the row. All four re-measured on this head,
exit 0 each:
test_ltx2test_ltx2_loadertest_ltx2_devicetest_ltx2_videoLTX2_CHECKPOINT_ROOTtests/vllm/models/ltx2_goldens.incwas regenerated fromscripts/gen-ltx2-goldens.pyagainstltx_corefd4ded7f(REGEN_EXIT=0):every golden VALUE byte-identical, the diff is the two stream labels alone — which
re-proves provenance as well as the wording.
Full
ctest -j4on the merged head: 422/423,CTEST_EXIT=8, 2 skipped as onthe baseline (
test_modelopt_mixed_precision_checkpoint,test_voxtral_e2e). Thesingle failure is
test_async_llm, which is on this repo's documentedstarve-under-
-jlist; re-run serially it is 1/1 PASS, exit 0.Two environment failures, recorded rather than reported as verdicts.
LTX2_CHECKPOINT_ROOTrun exited 1 with a zero-byte log — nodoctest summary at all — under a load average above 190. An empty log is a
killed process, not a failing test. Re-run:
30 / 8734, Status: SUCCESS, exit 0.test_cpu_x86_llamacpp_floorfails withNO_QUIET_WINDOW(exit 4,busy=102%,load 53–204). It is the documented behaviour of that harness on a box that is
never quiet — around ten agents were building throughout. Both files it
exercises are byte-identical to
origin/main(git diff origin/main -- scripts/cpu-x86-llamacpp-floor.sh tests/scripts/test_cpu_x86_llamacpp_floor.pyis empty), so running it here is running main's version: it cannot be this
diff. Reported as pending an idle box, not waived and not fixed.
An earlier full run was VOIDED rather than reported: another session's
disk-pressure cleanup deleted
build/while ctest was at 421/423, and the lasttwo tests recorded
Not Run — Failed to change working directory. A run whosetree vanished under it is not a result; it was rebuilt and re-run from scratch.
Spec:
.agents/specs/ltx25-prompt-adaln.md..agents/specs/ltx-2-5.mdisoperator-owned and untouched.
🤖 Generated with Claude Code