feat(LTX25-TILED-DECODE): tiled + STREAMING Conv VAE decode, and the 60 GiB is not in the decode (#644) - #656
Open
localai-bot wants to merge 3 commits into
Open
feat(LTX25-TILED-DECODE): tiled + STREAMING Conv VAE decode, and the 60 GiB is not in the decode (#644)#656localai-bot wants to merge 3 commits into
localai-bot wants to merge 3 commits into
Conversation
…emise it refutes (#644) Spec before code, per AGENTS.md. The row was dispatched on "448x256/25f stops because upstream's default decode is tiled and we call the untiled path". Executed against the pinned upstream (fd4ded7f), that half of the premise does not hold: TileSizeConfig.from_long_side with the Conv auto layout (helpers.py:62-63) resolves to ONE tile and ONE temporal group at 448x256/25f, because split_by_size short-circuits when dim <= size (tiling.py:199-200) and the latent is 8x14 against a 14x24 grid tile, 4 frames against a 10-latent-frame temporal tile. Upstream calls forward() once on the whole volume at that size too. Tiling first binds at 896x512 (spatial) and 121 frames (temporal). The decoder's own buffers at that shape are ~2 orders of magnitude too small to be the 60 GiB: the shipped ladder read from the checkpoint's own metadata gives a peak on the order of hundreds of MB, and the whole pixel tensor is 32.8 MiB. The structural port is still owed (ltx2_video_vae.cpp:17-18 records it) and this spec carries it, together with the derived — not rounded — equivalence bound, the blend mutation that must RED, and the memory measurement that decides the attribution. FOLLOWING_AGENTS_PROTOCOL Following-Agents-Protocol: true AI-Assisted: true Assisted-by: AGENT:claude-opus-5 [Claude Code]
…60 GiB is not there (#644) Ports `ConvVideoDecoder.tiled_decode` (conv_video_decoder.py:383-484) with `_accumulate_temporal_group_into_buffer` (:508-557), the interval algebra and separable trapezoidal blend (tiling.py:13-49, 174-361, 423-491, 494-571, 619-841), both axis mappers (video_vae.py:549-592) and the CONV AUTO layout (ltx_pipelines/utils/helpers.py:59-88). Upstream pin fd4ded7f. `ltx2_video.cpp` now decodes through `Ltx2VideoDecodeStreaming` and writes each PPM frame as its temporal chunk arrives, mirroring ti2vid_two_stages.py:365-376. The full pixel volume is never materialized. MEASURED BEFORE BUILDING, and it refutes the dispatching premise twice. 1. Upstream's own AUTO layout is a NO-OP at 448x256/25f. `split_by_size` returns one interval when `dim <= size` (tiling.py:199-200); the latent is 8x14 against a 14x24 grid tile and 4 frames against a 10-latent-frame temporal tile. Executed at the pin and emitted as a golden: 1 tile, 1 group. Tiling first binds at 896x512 spatially and 121 frames temporally. So the size that failed is a size upstream does not tile either. 2. The decode's own memory is 170x too small to be the 60 GiB. Real shipped conv VAE, real 448x256/25f latent decoded to completion, exact operator new accounting: heap peak live 361.72 MiB, largest single allocation 99.20 MiB, decode-attributed RSS 362.23 MiB. The analytic ladder model predicted the largest allocation to three significant figures at two scales. The 60 GiB is NOT attributed by this row and the axis stays open with named next steps. Also newly measured: that decode takes 2681 s (44.7 min) of single-threaded double-precision convolution, so the reported 24-second window cannot have been a completed decode. Separate row; phase L6 owes the production-dtype arm. The equivalence gate the brief asked for does not exist and was not fabricated. Swept across tile sizes and both causality arms, upstream's own max|tiled - untiled| is 0.67-1.29 TIMES the output range and does not converge — the receptive field is wider than the 2-latent-cell overlap. What IS exact is the ONE-TILE CONTROL: a config whose splits all short-circuit reproduces `forward` bit for bit, upstream measures 0 and the port is held to == 0.0. That is what makes the pipeline routing safe at every size run so far. Gates: BUILD_EXIT=0 clean, no ENOSPC/BFD, ctest -N 416, full ctest 416/416. test_ltx2_tiling 9/9 830 assertions; test_ltx2_vae 36/36 3039; test_ltx2_video 30/30 502. Blend mutation (linear ramp -> hard cut) REDs 6/9 cases and 39/830 assertions with tiled max|diff| 1.11411 vs a 5e-6 band, and is caught in four independent places; restored byte-for-byte (md5 e734ee2e35..., rebuild GREEN). FOLLOWING_AGENTS_PROTOCOL Following-Agents-Protocol: true AI-Assisted: true Assisted-by: AGENT:claude-opus-5 [Claude Code]
FOLLOWING_AGENTS_PROTOCOL Following-Agents-Protocol: true AI-Assisted: true Assisted-by: AGENT:claude-opus-5 [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.
Row 2 of the LTX-2.5 full port. Issue: #644.
Spec:
.agents/specs/ltx25-tiled-decode.md(committed at9e9fd0e5c, before any code).What landed
ConvVideoDecoder.tiled_decode(conv_video_decoder.py:383-484) with_accumulate_temporal_group_into_buffer(:508-557), the interval algebra andseparable trapezoidal blend (
tiling.py:13-49, 174-361, 423-491, 494-571, 619-841),both axis mappers (
video_vae.py:549-592), and the CONV AUTO layout(
ltx_pipelines/utils/helpers.py:59-88). Upstream pinfd4ded7f.ltx2_video.cppnow decodes throughLtx2VideoDecodeStreamingand writes each PPMframe as its temporal chunk arrives, mirroring
ti2vid_two_stages.py:365-376. Thefull pixel volume is never materialized.
Read this part first: the dispatching premise is refuted, twice
This row was dispatched with "448x256/25f stops because upstream's default decode is
tiled and we call the untiled path; MemAvailable falls 60 GiB in 24 s in the decode."
Measured before building, as the brief required:
1. Upstream's own AUTO layout is a NO-OP at 448x256/25f.
split_by_sizereturns oneinterval when
dim <= size(tiling.py:199-200). The latent is 8x14 against a 14x24grid tile and 4 frames against a 10-latent-frame temporal tile. Executed at the pin and
emitted as a golden (
kLtx2AutoCases, asserted intest_ltx2_tiling):Tiling first binds at 896x512 spatially and 121 frames temporally. The size that failed
is a size upstream does not tile either.
2. The decode's own memory is 170x too small to be the 60 GiB. Real shipped conv VAE,
real 448x256/25f latent decoded to completion (
[3, 25, 256, 448]), with the globaloperator new/deletereplaced by an exact live/peak counter:The analytic ladder model predicted the largest allocation to three significant figures
at both scales, so this is not one run's artefact. Flat process RSS while
MemAvailablefell 60 GiB is itself consistent with the decode not being the consumer.
The 60 GiB is NOT attributed by this row and the axis stays open, with next steps
named in the spec's
## Outcome.Also newly measured: that decode took 2681 s (44.7 min) of single-threaded
double-precision convolution, so the reported 24-second window cannot have been a
completed decode. Separate row; phase L6 already owes the production-dtype arm.
The probes are committed as
scripts/probe_ltx2_*so a reviewer can re-run them.The equivalence gate the brief asked for does not exist, and was not fabricated
Swept across tile sizes, latent extents and both causality arms, upstream's own
max|tiled - untiled|is 0.67-1.29 times the whole output range and does notconverge as the tile grows — the decoder's receptive field in latent units is wider than
the overlap the layout uses (768 px tile, 64 px overlap on a 32x grid: two latent
cells). Upstream accepts that seam and blends it.
What holds instead, and is what this suite gates:
5e-6band everyother LTX-2.5 golden uses.
reproduces
forwardbit for bit; upstream's own value is0on every arm, emitted asa golden, and the port is held to
== 0.0. This is what makes the pipeline routingsafe at every size the AUTO layout does not tile — today, every resolution this project
has run.
Gates
BUILD_EXIT=0clean rebuild, noNo space left/BFD assertion,df -h /91%.ctest -N416; fullctest -j 6416/416 after mergingorigin/main(
test_engine_core_procstarved once under-jand passes serially — the knownparallel-starvation set).
test_ltx2_tiling9/9, 830 assertions (new);test_ltx2_vae36/36, 3039;test_ltx2_video30/30, 502.agent-ready.py: all gates green, including the newcheck-oracle-pins.Blend mutation — RED, then restored byte-for-byte
Linear ramp replaced by a hard cut at the ramp midpoint in a scratch copy:
COUNTS unchanged — only the verdicts moved.
<= 5e-6to max|diff| = 1.11411 (causal) / 1.16359(non-causal): five orders of magnitude past the band.
masks), not one.
md5 e734ee2e3503e10ea111305a33574293before and after,git diffempty,rebuild GREEN 9/9 830/830.
Owed, recorded not dropped
memory_efficient_decode.py:1-43— deliberately not ported, since peak decode memorymeasures 362 MiB and it is a second rewrite of
CausalConv3d;test_ltx2_tiling.cppduplicates ~120 lines of
test_ltx2_vae.cpp's helpers rather than hoisting them,because two other rows are editing that file concurrently and a relocation is the one
merge shape this protocol has been bitten by.
🤖 Generated with Claude Code