Skip to content

feat(LTX25-RES2S-LOOP): the res_2s loop, its second evaluation, and the guidance the naive merge would have dropped (#921) - #1125

Merged
localai-bot merged 2 commits into
mainfrom
row/LTX25-RES2S-LOOP-R2
Aug 17, 2026
Merged

feat(LTX25-RES2S-LOOP): the res_2s loop, its second evaluation, and the guidance the naive merge would have dropped (#921)#1125
localai-bot merged 2 commits into
mainfrom
row/LTX25-RES2S-LOOP-R2

Conversation

@localai-bot

Copy link
Copy Markdown
Collaborator

pipeline_kind=res2s_two_stage serves upstream's TI2VidTwoStagesHQPipeline --
the high-quality arm. New TU ltx2_samplers.{h,cpp}, mirroring upstream's own
utils/ partition: a stepper advances a substep, a sampler decides how many
there are.

Ported at fd4ded7f: Ltx2Phi (utils/res2s.py:4-22),
Ltx2GetRes2sCoefficients + Ltx2PhiCache (:25-62),
Ltx2Res2sNormalizeNoise (utils/samplers.py:160-170), Ltx2Res2sDenoisingLoop
(:208-447), and Res2sTwoStageRecipe (ti2vid_two_stages_hq.py:59-340 +
utils/constants.py:95-115).

THE SAMPLER IS THE HQ VARIANT. Serving the HQ preset on the Euler loop renders a
plausible clip that is quietly not HQ, at roughly half the model evaluations the
preset was tuned for, and no shape or token gate can see it. The gate is
therefore an exact DiT-evaluation count -- 2n+1 when the schedule ends at 0,
else 2n -- asserted with the eval-sigma sequence beside it, so two forwards at
the same sigma also fails. End to end: 7 and 11 evaluations at 3 and 5 steps on
res2s_two_stage, against 3 and 5 on one_stage.

phi is a CANCELLATION CLIFF, not a series expansion. Upstream guards only
abs(z) < 1e-10 and otherwise evaluates the quotient directly, so its own
phi(2,-1e-10) is 0.0 and phi(2,-1e-8) is 1.1102230246251563. A Taylor
expansion near zero -- the numerically BETTER port -- returns 0.5 and diverges
from what the model actually ran. Pinned with ==.

GUIDANCE, which the merge nearly dropped. daeff67f2 (#1092) landed the guided
video denoiser into the same phase loop. A textual resolution keeping Evaluate
as a bare Ltx2DitForward would have made the HQ preset the only unguided video
arm in the tree -- upstream's stage 1 runs a GuidedDenoiser at cfg 3.0/7.0 and
rescale 0.45 (ti2vid_two_stages_hq.py:271-281) -- and the evaluation count
cannot see it, because a denoiser call is one evaluation guided or not.

So Evaluate builds the Ltx2X0Model lambda and calls Ltx2GuidedDenoise, and
a SECOND counter was added: dit_forwards counts actual Ltx2DitForward calls
and is 3 * (2n+1) on HQ stage 1 (cond + uncond + modality), asserted exactly at
two step counts with forwards != evaluations as its own assertion. Stripping
guidance from the res_2s arm alone is RED.

step_index mirrors upstream literally: step_idx at the first evaluation
(samplers.py:301), a literal 0 at the substep beside its one-element schedule
(:385), n_full_steps at the terminal one (:437). Since should_skip_step
is step % (skip_step + 1) != 0, the literal 0 makes the substep unskippable at
any skip_step -- inert on the HQ preset's own skip_step = 0, live for a
request override.

A mutation survivor the review did not list: the substep's x0 conversion must use
the latent THAT EVALUATION was handed, because the substep runs over x_mid.
Reading the stream latent moves the whole substep prediction and nothing could
see it, since the loop's arithmetic is gated with a fixture denoiser that
performs no conversion. Now gated and RED.

The engine's VT_CHECK was a tautology -- both operands came from the same
stats object and 2n+1 > n holds for every n -- and is now the trace delta
against stats.evaluations. The argument is executable: the same under-counting
defect beside the restored old check is GREEN.

Both generator scripts are committed rather than described.
scripts/gen-ltx2-res2s-goldens.py imports upstream's own phi,
get_res2s_coefficients, Res2sDiffusionStep, post_process_latent,
_channelwise_normalize and res2s_audio_video_denoising_loop at the pin and
reproduces ltx2_res2s_goldens.inc byte for byte -- which is the evidence the
goldens are upstream's and not this port's.

Supersedes #1101, whose branch carried a merge commit with a bare subject and no
trailer block. check-commit-trailers.py walks merges, that commit was a
first-parent ancestor of every candidate head, and repairing it would have needed
a force-push. Same tree, one commit, block intact.

Owed, not claimed: no render on real weights, and no oracle-run comparison --
everything is gated against upstream SOURCE at fd4ded7f. The HQ preset is
host-only here, because its modality_scale = 3.0 asks for the isolated-modality
pass and Ltx2DitForwardDevice takes no perturbations; that is #1092's owed
device work, not newly incurred.

Closes #921.

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [claude-code]

mudler added 2 commits August 17, 2026 12:03
…he guidance the naive merge would have dropped (#921)

`pipeline_kind=res2s_two_stage` serves upstream's `TI2VidTwoStagesHQPipeline` --
the high-quality arm. New TU `ltx2_samplers.{h,cpp}`, mirroring upstream's own
`utils/` partition: a stepper advances a substep, a sampler decides how many
there are.

Ported at `fd4ded7f`: `Ltx2Phi` (`utils/res2s.py:4-22`),
`Ltx2GetRes2sCoefficients` + `Ltx2PhiCache` (`:25-62`),
`Ltx2Res2sNormalizeNoise` (`utils/samplers.py:160-170`), `Ltx2Res2sDenoisingLoop`
(`:208-447`), and `Res2sTwoStageRecipe` (`ti2vid_two_stages_hq.py:59-340` +
`utils/constants.py:95-115`).

THE SAMPLER IS THE HQ VARIANT. Serving the HQ preset on the Euler loop renders a
plausible clip that is quietly not HQ, at roughly half the model evaluations the
preset was tuned for, and no shape or token gate can see it. The gate is
therefore an exact DiT-evaluation count -- `2n+1` when the schedule ends at 0,
else `2n` -- asserted with the eval-sigma sequence beside it, so two forwards at
the same sigma also fails. End to end: 7 and 11 evaluations at 3 and 5 steps on
`res2s_two_stage`, against 3 and 5 on `one_stage`.

`phi` is a CANCELLATION CLIFF, not a series expansion. Upstream guards only
`abs(z) < 1e-10` and otherwise evaluates the quotient directly, so its own
`phi(2,-1e-10)` is 0.0 and `phi(2,-1e-8)` is 1.1102230246251563. A Taylor
expansion near zero -- the numerically BETTER port -- returns 0.5 and diverges
from what the model actually ran. Pinned with `==`.

GUIDANCE, which the merge nearly dropped. `daeff67f2` (#1092) landed the guided
video denoiser into the same phase loop. A textual resolution keeping `Evaluate`
as a bare `Ltx2DitForward` would have made the HQ preset the only unguided video
arm in the tree -- upstream's stage 1 runs a `GuidedDenoiser` at cfg 3.0/7.0 and
rescale 0.45 (`ti2vid_two_stages_hq.py:271-281`) -- and the evaluation count
cannot see it, because a denoiser call is one evaluation guided or not.

So `Evaluate` builds the `Ltx2X0Model` lambda and calls `Ltx2GuidedDenoise`, and
a SECOND counter was added: `dit_forwards` counts actual `Ltx2DitForward` calls
and is `3 * (2n+1)` on HQ stage 1 (cond + uncond + modality), asserted exactly at
two step counts with `forwards != evaluations` as its own assertion. Stripping
guidance from the res_2s arm alone is RED.

`step_index` mirrors upstream literally: `step_idx` at the first evaluation
(`samplers.py:301`), a literal 0 at the substep beside its one-element schedule
(`:385`), `n_full_steps` at the terminal one (`:437`). Since `should_skip_step`
is `step % (skip_step + 1) != 0`, the literal 0 makes the substep unskippable at
any `skip_step` -- inert on the HQ preset's own `skip_step = 0`, live for a
request override.

A mutation survivor the review did not list: the substep's x0 conversion must use
the latent THAT EVALUATION was handed, because the substep runs over `x_mid`.
Reading the stream latent moves the whole substep prediction and nothing could
see it, since the loop's arithmetic is gated with a fixture denoiser that
performs no conversion. Now gated and RED.

The engine's `VT_CHECK` was a tautology -- both operands came from the same
`stats` object and `2n+1 > n` holds for every n -- and is now the trace delta
against `stats.evaluations`. The argument is executable: the same under-counting
defect beside the restored old check is GREEN.

Both generator scripts are committed rather than described.
`scripts/gen-ltx2-res2s-goldens.py` imports upstream's own `phi`,
`get_res2s_coefficients`, `Res2sDiffusionStep`, `post_process_latent`,
`_channelwise_normalize` and `res2s_audio_video_denoising_loop` at the pin and
reproduces `ltx2_res2s_goldens.inc` byte for byte -- which is the evidence the
goldens are upstream's and not this port's.

Supersedes #1101, whose branch carried a merge commit with a bare subject and no
trailer block. `check-commit-trailers.py` walks merges, that commit was a
first-parent ancestor of every candidate head, and repairing it would have needed
a force-push. Same tree, one commit, block intact.

Owed, not claimed: no render on real weights, and no oracle-run comparison --
everything is gated against upstream SOURCE at `fd4ded7f`. The HQ preset is
host-only here, because its `modality_scale = 3.0` asks for the isolated-modality
pass and `Ltx2DitForwardDevice` takes no perturbations; that is #1092's owed
device work, not newly incurred.

Closes #921.

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [claude-code]
`589abad12` (#1115) landed `vt::Conv1d`/`vt::ConvTranspose1d` while this row was
being recreated. It touches no file this row touches and merges without a
conflict; the index is unchanged by it and `origin/main`'s file remains a
byte-identical prefix.

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [claude-code]
@localai-bot
localai-bot merged commit 4d77486 into main Aug 17, 2026
3 of 16 checks passed
localai-bot pushed a commit that referenced this pull request Aug 17, 2026
`4d7748646` (#921/#1125) landed the `res2s_two_stage` HQ arm into the same four
regions this row edits, so all four conflicts are two arms appended at one place
rather than two edits of one thing. BOTH ARMS SURVIVE, and each is proven to
still reach its denoiser rather than merely to compile.

`ltx2_pipeline.cpp`: the driver interleaved `Res2sTwoStageRecipe` and
`A2VidTwoStageRecipe` because they share a tail (`recipe.height = ...` through
`return recipe;`). Both functions are restored WHOLE, res_2s first, and the
dispatch table carries both keys — `res2s_two_stage` at 2.5 and
`a2vid_two_stage` at all four.

`ltx2_video.cpp`: only the READER ANCHORS line conflicted. #1125's phase loop is
taken unchanged, including the `Evaluate` lambda both samplers share, its
`Ltx2GuidedDenoise` call, `dit_forwards` beside `dit_evaluations`, the
`step_index` policy (`step_idx`, a literal 0 at the res_2s substep,
`n_full_steps` at the terminal one) and the trace-delta `VT_CHECK` that replaced
the tautological one. This row's three additive hunks ride on top, and the
`Ltx2PhaseDenoiser::kSimple` skip stays AFTER the `allow_guidance_override`
refusal — the reverse order turns three landed refusals into silent ignores.

`docs/USAGE.md`: the recipe table lists both kinds and the pair count is now
TWENTY (16 + a2vid's four). Both prose sections are kept, in table order.

`tests/vllm/models/test_ltx2_pipeline.cpp`: both suites append at EOF, so the
driver overlapped them. Kept whole: 8 res_2s cases and 2 a2vid cases, 52 cases
and 3062 assertions for the binary.

`.agents/issue-index.md` union-merged, and the driver's result was NOT accepted.
`origin/main` was taken wholesale and this branch's own unlanded rows (#1117,
#1118) re-appended, then verified three ways: `origin/main`'s 224719 bytes are a
byte-identical PREFIX of the result, the two rows are byte-identical to the
branch head's, and 311 rows carry 311 unique ids.

READER ANCHORS re-derived with the test's own walk: `809 819 820 882 978 994
1029 1120 1145 1250 1291 1333 1335`, replacing #1125's `... 996 1087 1112 1217
1258 1300 1302`. The instrument was armed first — one line inserted above the
readers built clean and took the walk to MISMATCH at exit 1, and the restore is
byte-identical.

Six mutations on the merged tree, each printing its own `git diff --stat`,
whether it BUILT, the compile-error count and the exit code captured directly.
All six DETECTED, and the two that matter for this merge are the first two:
stripping stage 1's guider from `A2VidTwoStageRecipe` is RED on both binaries,
and stripping it from `Res2sTwoStageRecipe` is RED on both. Deleting either
dispatch row is RED. Deleting the `kSimple` skip and deleting
`im.trace.dit_forwards += 1` are each RED on `test_ltx2_video`.

Gate on the merged tree: `CONFIGURE_EXIT=0`, `BUILD_EXIT=0`, 0 `: error:`,
`ctest -N` 502, `CTEST_EXIT=8` with 500/502 passing. The two failures are
`test_engine_core_proc` (#1052) and `test_async_llm` (#294), both load-dependent
and both green when re-run serially at load 33 (they failed at load 82). No
`No space left` and no `BFD` in the configure, build or ctest logs, against a
positive control that matches both strings in a log that carries them.

Not verified here: no render on real weights and no oracle-run comparison for
either arm — unchanged by this merge and already recorded under `## Owed` in
both specs.

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 17, 2026
…ebt gets an open owner (#1144)

The repair one commit back wrote the per-phase strength trap into
`ltx2_loader.h` and this row's `## Owed` and said the note would also go on #921,
which the fresh review named as the owner. #921 is CLOSED. It was closed as
completed on 2026-08-17 at 12:28Z by `LTX25-RES2S-LOOP` (`4d7748646`, PR #1125),
which landed the res_2s sampler four hours before this row's head.

That row was right about its own scope: it names "the distilled LoRA per stage"
as out of scope and unchanged by it. What it did not do is list the item under
its own `## Owed`, so when the issue closed the debt outlived its owner. An
`## Owed` bullet pointing at a closed issue does not own anything; it only looks
like it does, and `check-agent-record.py` cannot see the difference because
GitHub holds the open/closed state and the index deliberately does not.

So #1144 is filed and this points at it: the spec's two strength bullets, the
`Ltx2RebindDitLoras` header, and `Ltx2PhaseLoraScope`'s "NO PER-PHASE STRENGTH,
deliberately" note, which was the one pointer at a closed issue sitting in a
shipped header. The two "#921 when this was written" mentions in Scope and the
port map keep the original number beside the new one, because the row genuinely
was bounded by #921 on the day it was written and rewriting that would be
rewriting history rather than the record.

#1144 is a `bug` and not an enhancement, and the reason is the second half of
the finding: `res2s_two_stage` — this tree's port of `TI2VidTwoStagesHQPipeline`
— sets `loras` on neither phase, so both take `kAllAdapters`, and the load
carries ONE strength (`lora_strength` absent is 1.0). It therefore runs both
stages at 1.0 where upstream runs 0.25 and 0.5 (`utils/args.py:1174-1184`,
placed at `ti2vid_two_stages_hq.py:92-101` and handed to `:154`, `:165`). That
is a live divergence on a shipped arm, pre-existing and not worsened by this
row, and it was unstated anywhere until now. It is not fixed in flow because the
fix changes a seam signature and a checkpoint's state representation, which
needs its own spec and its own fresh review.

`.agents/issue-index.md` was taken from `origin/main` wholesale and the one row
re-appended, per the record rule for a union-merged append-only file. Verified
after writing: `origin/main`'s bytes are an exact prefix of the result, the row
list is main's 315 plus exactly one, all 316 ids are unique, and no row that was
on this branch before is lost.

No build. `READER ANCHORS` re-derived unchanged at `823 833 834 896 992 1008
1043 1134 1159 1264 1305 1347 1349` with the same armed port of the test's own
walk. The two source-text gates over `ltx2_pipeline.h` match flattened comment
TEXT and are explicitly "derived rather than pinned to a line number", and
neither of the strings they hold is touched here.

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [claude-code]
localai-bot added a commit that referenced this pull request Aug 17, 2026
…iT moves between them (#1118) (#1140)

Closes #1118.

`Ltx2PhaseRecipe::loras` carries upstream's per-stage adapter set, and
`A2VidTwoStageRecipe` gives stage 1 `kNoAdapters` — `loras=tuple(loras)`
at
`a2vid_two_stage.py:107` against `(*tuple(loras),
*tuple(distilled_lora))` at
`:114`, read at Lightricks/LTX-2 `fd4ded7f`. Until now
`dit_options.loras` was
pushed once at load and every phase of every recipe ran the same fused
weights,
so stage 1's guided schedule ran against base + distilled where upstream
runs it
against the base alone. That rendered: the frames differed while the
frame
count, the shapes and the sample rate did not, which is why nothing
caught it.

## Upstream holds ONE transformer, not two

The premise that upstream pays two resident weight sets is false, and
correcting
it is what settled the design. Both `DiffusionStage.from_checkpoint`
calls name
the same `model_paths.transformer()` — `a2vid_two_stage.py:104` and
`:116`,
`ti2vid_two_stages.py:137` and `:148` — and differ only in the adapter
tuple. So
upstream pays a second MATERIALIZATION, not a second model.

`Ltx2RebindDitLoras` is exactly that. It re-materializes from the
pristine file
the tensors an adapter targets, fuses the phase's set back in, and
writes into
the buffer the view already points at, so no pointer moves,
`Ltx2DitWeights`
stays valid without re-binding, and no second weight set ever exists.
Peak
residency rises by one tensor plus the adapter's own A/B factors.

Three shapes were costed and the third chosen:

| Shape | Resident memory | Exactness | Verdict |
|---|---|---|---|
| A second resident `Ltx2DitWeights` | doubles the DiT (18.7 GB nvfp4 /
21.0 GB fp8 / ~39 GB bf16) | exact | rejected — heavier than the
reference, and one GB10 has 119 GB with no swap |
| Unfused runtime LoRA | + the adapter | `Wx + s*B(Ax)` vs `round_bf16(W
+ s*BA)x` | rejected — a rounding divergence AND a different GEMM path |
| Re-materialize the targeted tensors at the phase boundary | none |
exact | CHOSEN — it is what upstream does |

The base is reconstructed by RE-READING it, never by subtracting the
delta:
`round_bf16(round_bf16(W + d) - d)` is not `W`.

## The field is a SET, not a boolean

Upstream needs two placements: stage 2 only for TI2Vid, A2Vid and
Keyframe
(`ltx-pipelines/CLAUDE.md:48`), both stages for HQ and DFR (`:49`,
`:50-51`).
Stage 1 `kNoAdapters` with stage 2 defaulted gives the first; both
defaulted
gives the second. Two enumerators are the COMPLETE space while the
adapter arity
is capped at one by a gated refusal (`ltx2_lora.h:167-172`).
`kAllAdapters` is
the default, so `distilled_two_stage`, `dfr`, `retake`, `one_stage`,
`res2s` and
`t2a_one_stage` keep the behaviour they were gated with —
upstream-correct,
since `distilled.py:131` builds one stage set.

Per-phase STRENGTH is deliberately absent:
`ti2vid_two_stages_hq.py:92-101`
needs one, no recipe here would set it, and landing a branch nothing can
select
is what `ltx2_lora.h:41-44` already argues against. Owed to #921.

## The gate that distinguishes per-phase from load-time fusion

`ltx2 a2vid: the distilled adapter rides stage 2 ALONE`, driven entirely
through
`LoadVideoEngine` + `Generate` with the documented `pipeline_kind`,
`lora_path`,
`lora_strength` and `max_phase` load extras:

- stage 1 alone (`max_phase=0`), strength 1.0 vs 0.0: **0 of 63809**
artifact
  bytes move. The adapter is not on stage 1.
- both stages, the same two strengths: **11 of 146753** bytes move. The
adapter
  reaches stage 2.

Both halves are load-bearing. The first REDs on today's load-time
fusion; the
second REDs on an engine that simply stopped fusing. A gate asserting
only "a
LoRA was applied" passes on the defect. Strength 0 is the control rather
than
"no adapter", because `requires_distilled_lora` refuses an a2vid load
carrying
no `lora_path`.

The loader side gates exactness byte-for-byte against a fresh load in
both
directions, including the widened-to-f32 host arm the CPU parity forward
runs.

## Mutations

Every row prints four facts, because each has produced a false green
here before.

| Mutation | diff | BUILT | compile_err | exit | verdict |
|---|---|---|---|---|---|
| M1 drop stage 1's `kNoAdapters` | 1 file, -1 | yes | 0 | 1 | RED |
| M2 delete the rebind call from the phase loop | 1 file, +1/-3 | yes |
0 | 1 | RED |
| M3 delete the load-time fuse site (standing reachability mutation) | 1
file, -1 | yes | 0 | 1 | RED |
| M4 rebind that does not restore the base | 1 file, +1/-1 | yes | 0 | 1
| RED |
| M5 make the phase scope field inert | 1 file, +1/-1 | yes | 0 | 1 |
RED |

M4's first anchor was not unique and silently mutated
`Ltx2StreamDitToDevice`
instead, presenting as a compile error about the code under test; the
harness now
asserts each anchor occurs exactly once.

## Reachability

M3 is the proof: deleting the production call site REDs
`test_ltx2_video` (6
cases). The path is `include/vllm.h` -> `LoadVideoEngine` -> `Generate`,
and
`ltx2-gen --pipeline-kind a2vid_two_stage --lora ... --audio-path ...`
is the
same two calls through the ABI. `/v1/videos` cannot drive it, because
`VideoGenParamsFromRequest` writes no `gen.extras` (#928) — stated so
the reach
claim excludes it.

## The IC-LoRA refusal is NARROWED, not retired

Its reason 2 — "this engine holds one DiT, fused at load, that every
phase runs"
— is now false, and both the comment and the `Fail` text say so and name
what
closed it. Reason 1, the reference clip's pixel path
(`iclora_utils.py:112-117`, `:87-89`, `:144-148`), is untouched by this
row, so
the refusal stands. Retiring it here, as the dispatch proposed, would
have
shipped an arm whose geometry nothing supplies.

## Gate

`cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=Release
-DVLLM_CPP_CUDA=OFF`

CONFIGURE_EXIT 0, BUILD_EXIT 0, `: error:` count 0, `ctest -N` 503,
CTEST_EXIT 8, `99% tests passed, 1 tests failed out of 503`. The one
failure is
`test_serve_low_tools` (#428, load-dependent); it passes in isolation,
measured
rather than assumed. `No space left` 0 and `BFD` 0, each with a positive
control
in the same log (505 of 506 build lines matched `Building|Linking`; 500
`Passed`
lines in the ctest log). Load average 73.8 at build, 47.1 at rerun; 13
GB free.

No GPU and no real-weights result is claimed: this is a weight-lifetime
seam and
the CPU goldens are its correct gate. A real-weights comparison against
upstream's own render is still owed. It is no longer blocked on an
artifact:
the distilled adapter and the full `-dev-` transformer have both since
landed on
the NAS and their headers were read (see the review repair below). What
is owed
is the RUN.

Spec: `.agents/specs/ltx25-phase-lora.md`, committed in `86422587f`
before any
product code.

## Review repair (2026-08-17)

A fresh review returned PASS with three non-blocking findings, all
records. They
are repaired in `17b211384`, `10d9d010e` and `08ea64b15`. No behaviour
changed:
a spec `## Outcome`, two header comments, one source comment, one
`docs/USAGE.md`
section and one new issue.

**THE HEADLINE GATE'S MARGIN IS ONE BYTE.** "ltx2 a2vid: the distilled
adapter
rides stage 2 ALONE" has two halves, and the review's mutations measured
both.
At head, unmutated: stage 1 alone moves **0 of 63809** artifact bytes,
both
stages move **11 of 146753**, `SUCCESS!` over 2420 assertions. Deleting
`stage1.loras = kNoAdapters` moves stage 1 to **1 of 63809** and reds
`CHECK(s1_differing == 0)`. So the assertion that catches this row's own
defect
catches it by 0.0016% of the artifact. It cannot go falsely RED, because
the
render is deterministic. It can go falsely GREEN: a fixture change to
the block
count, the 2-step schedule, the sigma table or the PPM's 8-bit
quantization
could take that 1 to 0. The other half carries 11 and reds under
"stopped fusing
altogether", so the pair does not fail open together. Both margins and
all three
mutation counts are now in the spec's `## Outcome`, which the row also
owed for
reaching `DONE`.

**PER-PHASE STRENGTH NEEDS MORE THAN A FIELD, and #921 is CLOSED.**
`Ltx2RebindDitLoras` early-returns on `currently_fused == fuse`, and its
header
calls that a no-op it detects itself. The state is a BOOLEAN, so it
means
"already fused" and never "already fused at this strength". HQ is stage
1 at 0.25
and stage 2 at 0.5 (`ti2vid_two_stages_hq.py:92-101`, `:154`, `:165`;
defaults at
`utils/args.py:1174-1184`) with BOTH stages fused, so that early return
would
no-op the transition and stage 2 would silently render at stage 1's
strength.
The trap is now written beside the early return. The review named #921
as the
inheriting owner; #921 was closed as completed the same day by
`LTX25-RES2S-LOOP` (`4d7748646`, PR #1125), which correctly scoped the
distilled
LoRA out but did not list it under its own `## Owed` — so the debt
outlived its
owner. **#1144 is filed for it**, the spec and both headers point there,
and a
forwarding comment is left on #921. Recorded with it: `res2s_two_stage`
already
runs both stages at strength 1.0 where upstream runs 0.25/0.5,
pre-existing and
unstated until now, which is why #1144 is a `bug`.

**THE ARTIFACTS ARRIVED.** The `## Owed` bullet said the real-weights
comparison
needs an adapter `find /mnt/nas_share/checkpoints -iname '*lora*'`
returns
nothing for. That control now returns two. Headers read on the files,
not copied
from a model card: `ltx-2.5-22b-distilled-lora-450-bf16.safetensors`,
8,899,889,568 bytes, 3320 BF16 tensors = 1660 `lora_A`/`lora_B` pairs,
rank and
alpha 450, `model_version` 2.5.0, data end == file size; and
`ltx-2.5-22b-dev-transformer-bf16.safetensors`, 42,018,190,584 bytes,
4349
tensors, 21.004 B params, BF16 4059 / F32 290, `model_version` 2.5.0,
`keyframes_abs_pos_embedding` present, data end == file size.

Also folded in, so nobody derives them twice: the f32-widen branch's
direct write
is unreachable with a device queue; contract drift between load and
rebind cannot
occur; after a `max_phase = 0` render the reference refusal prints "no
adapter
was supplied" because `lora_fused_tensors` doubles as the state bit,
which is
message-only on a path that refuses anyway. The phase-loop comment
claimed a
two-stage render pays one rebind; it pays two, and `docs/USAGE.md` now
says so
and says the cost is UNMEASURED.

**One gate is RED and it is not hidden.** `check-doc-checkpoint.py`
classifies
any `include/vllm/` path as `user_usage` and demands `docs/USAGE.md` in
the SAME
commit, by path, without reading content. `17b211384` and `10d9d010e`
changed
only COMMENTS in two headers and carried no `docs/USAGE.md`, so both
fail that
gate per-commit. That is a real rule, deliberately per-commit because a
diff-scoped range is never re-covered. Repairing it in place needs a
rewrite of
two pushed commits and this session may not force-push, so it is
reported rather
than hidden. `08ea64b15` carries the owed `docs/USAGE.md` section, and
the
squash-merge commit was simulated with `git commit-tree` and checked: it
exits 0.
The red is on the pull-request lane only.

No build was run for the repair: the change is comments and prose, and
no build
can move a doctest `MESSAGE` count. `READER ANCHORS` was re-derived with
a
faithful port of the test's own walk and is unchanged at
`823 833 834 896 992 1008 1043 1134 1159 1264 1305 1347 1349`; the port
was armed
first against a one-line insertion and reported MISMATCH at exit 1.
`check-public-doc-tables.py`, `check-issue-index-append-only.py`,
`check-agent-record.py`, `check-commit-style.py` and
`check-commit-trailers.py`
all exit 0, and the first two were each armed and refused at exit 1
before the
tree was restored byte-for-byte.

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [claude-code]

---------

Co-authored-by: Ettore Di Giacinto <mudler@localai.io>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

LTX-2.5: the res_2s DENOISING LOOP is unported, so TI2VidTwoStagesHQPipeline cannot be served — only its per-step arithmetic exists

2 participants