Skip to content

feat(ltx2): tile arithmetic and trained-span reporting for stage-2 refinement - #674

Merged
jamesbrink merged 3 commits into
mainfrom
tiling-primitives
Aug 3, 2026
Merged

feat(ltx2): tile arithmetic and trained-span reporting for stage-2 refinement#674
jamesbrink merged 3 commits into
mainfrom
tiling-primitives

Conversation

@jamesbrink

Copy link
Copy Markdown
Member

First half of #673, and the prerequisite for the 4K tranche of #592 and high-resolution #594.

What this is

The verified arithmetic for tiled stage-2 refinement — interval splitting, the separable trapezoidal blend window, and tile enumeration — plus a planner and a diagnostic that uses it today.

The per-tile denoise wiring is deliberately not here; it needs a GPU equivalence run to be trustworthy and is tracked in #673. What is here is the part that fails silently when it is wrong: a blend window desynced from the token order produces a plausible-looking seam, not an error. So it is written and pinned now rather than under pressure later.

Pinned to upstream, not to my reading of it

The split_by_count fixtures are values captured by running upstream's own implementation in its virtualenv:

input intervals
(21, 2, 8) [(0,15,0,8), (7,21,8,0)]
(34, 2, 6) [(0,20,0,6), (14,34,6,0)]
(20, 4, 2) [(0,7,0,2), (5,12,2,2), (10,16,2,2), (14,20,2,0)]

Tile enumeration order is part of the contract, not an implementation detail — upstream seeds each tile's noise from its index.

A bug found in upstream while porting

blend has no normalization pass, so correctness depends entirely on the per-tile windows summing to exactly 1. That holds for two tiles. Once the stride drops below the overlap, tiles i and i+2 also overlap, three trapezoids stack, and the sum climbs:

split window sum
(21, 2, 8) 1.000
(21, 3, 8) up to 1.074
(21, 4, 8) up to 1.161

The seam gets silently brightened rather than erroring. Upstream's _clamp_tile_to_latent only prevents the ValueError, not this. Solving tile_size >= 2 * overlap gives the closed form overlap <= dim / (n + 1), which this port enforces — my first attempt computed the tile size from the unclamped overlap and the partition-of-unity test caught it immediately, which is the argument for building this layer as pure arithmetic first.

Upstream ships 2 tiles per axis, which can never triple-overlap, so they do not hit it. Any layout tuned for 4K would.

What runs in production today

plan_stage2_tiling decides when tiling is warranted, from the same fact that motivates it: RoPE was trained over a 2048px span, which is 64 latent cells after the VAE's /32 compression. A shape already inside that span is left untiled, because tiling costs a full denoise pass per tile. That covers every resolution mold ships, 1920×1088 included.

Stage 2 now reports on the existing LTX-2 VRAM telemetry target when a render exceeds that span, naming the tile layout that would fix it. A render past the trained span still produces a picture — the failure is degraded structure, not an error — which is exactly why it is worth saying out loud.

Verification

12 tests, all CPU: upstream fixture parity, ramp values, partition of unity across seven layouts, the triple-overlap clamp, tile ordering, window-to-token reconstruction to 1e-5, the (f-1)*8+1 pixel inverse (not f*8 — the causal VAE's first latent frame is one pixel frame), and a 4K plan whose every tile lands back inside the trained span.

Full CI-equivalent gate green; the only test failures are the known pre-existing execution_plan::tests::* filesystem-identity ones, confirmed against main single-threaded.

Copilot AI review requested due to automatic review settings August 3, 2026 02:55
Pure arithmetic only: interval splitting, the separable trapezoidal blend
window, and tile enumeration. No tensor or device dependency, so the part
that is easy to get subtly wrong is exhaustively testable on CPU.

Fixtures are values captured from running upstream's own `split_by_count`
in its virtualenv, so this is pinned to the reference rather than to a
reading of it.

Includes a guard upstream lacks: `split_by_count` silently breaks the
partition of unity once the stride drops below the overlap, because three
trapezoids then stack and `blend` has no normalization pass. Measured sums
reach 1.16, which would brighten the seam rather than fail. Solving
`tile_size >= 2 * overlap` gives `overlap <= dim / (n + 1)`; two-tile
layouts cannot triple-overlap so upstream's shipped 2/8-6-6 is untouched.

Not yet wired into `render_real_two_stage_av` — the module is dead code
until then, so this is not PR-ready.
The tile arithmetic needs a policy: when to tile at all, and into how many
tiles. Both answers come from the same fact that motivates tiling — the
checkpoints' RoPE was trained over a 2048px span, which is 64 latent cells
after the VAE's /32 compression.

A shape already inside that span is left untiled, because tiling costs a
full denoise pass per tile and must not be paid for nothing. That covers
every resolution mold ships today, 1920x1088 included. An oversized axis
is split into the smallest number of tiles that brings every tile back
inside the span, using upstream's shipped overlaps.

Time stays whole: the duration budget already caps frames, so the temporal
axis is not what runs past the trained span at high resolution.

The 4K test asserts the property that matters — every tile of a 120x68
latent plan fits the trained span, and the blend windows still reconstruct
the field to 1e-5.
A render above the span the checkpoints were trained on still produces a
picture, which is exactly why it needs saying out loud — the failure mode
is degraded structure, not an error. Stage 2 now reports the shape and the
tile layout that would bring it back inside, on the existing LTX-2 VRAM
telemetry target.

Also documents why the tile execution arithmetic is staged ahead of its
caller: it is the part that fails silently when wrong, so it is verified
against upstream now rather than written under pressure later.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new LTX-2 “tiling primitives” layer (pure arithmetic + tests) and wires a small stage-2 diagnostic into the existing LTX-2 VRAM telemetry so operators get an explicit signal when a stage-2 latent exceeds the RoPE-trained spatial span, along with the tile layout that would bring it back into-distribution.

Changes:

  • Introduces ltx2::tiling: interval splitting, trapezoidal blend windows, tile enumeration order, and a plan_stage2_tiling planner (with CPU-only tests pinned to upstream fixtures).
  • Logs a stage-2 trained-span warning (on the existing mold::ltx2::vram tracing target) when stage-2 spatial latents exceed the trained span, including the planned tile counts.
  • Registers the new tiling module under ltx2.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.

File Description
crates/mold-inference/src/ltx2/tiling.rs New pure arithmetic tiling primitives + exhaustive CPU tests; includes a stage-2 tiling planner and trained-span constant.
crates/mold-inference/src/ltx2/runtime.rs Calls the new diagnostic from stage-2 render paths and adds report_stage2_trained_span telemetry logging.
crates/mold-inference/src/ltx2/mod.rs Adds mod tiling; to include the new module in the LTX-2 inference crate.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@jamesbrink
jamesbrink merged commit d814223 into main Aug 3, 2026
15 checks passed
@jamesbrink
jamesbrink deleted the tiling-primitives branch August 3, 2026 03:05
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.

2 participants