Found while repairing LTX-2.5 phase L5 (#435, PR #437), where it concealed a real defect. It is not confined to LTX-2.5 — test_minimax_h3.cpp has the same form, and that is a shipped model.
The defect
Two spellings of the same helper, both NaN-blind:
// form A, tests/vllm/models/test_ltx2.cpp:189
if (d > worst) worst = d; // NaN is never > anything
// form B, tests/vllm/models/test_ltx2_vae.cpp:183
// tests/vllm/models/test_ltx2_text_encoder.cpp:152
// tests/vllm/models/test_minimax_h3.cpp:143
worst = std::max(worst, std::abs(...)); // std::max(a,b) is `a < b ? b : a`;
// a < NaN is false, so it returns `a`
Demonstrated:
form A (if d > worst): worst = 0.000000 -> NaN seen? NO
form B (std::max): worst = 0.000000 -> NaN seen? NO
both report a PASS against any bound: A<1e-5=1 B<1e-5=1
So a brick that emits all NaN, compared against entirely correct goldens, reports max|diff| = 0.0 and passes every bound. The comparison helper cannot see the defect class it exists to catch.
How it was found, and what it hid
L5's repair added a sweep over sigma-schedule step counts and found Ltx2SigmaSchedule(1, ...) returning {-nan, 0} where upstream returns {0.10000002, 0}. The OneStep arm had been comparing NaN against a correct golden and reporting worst = 0.0 — green.
(The underlying steps == 1 defect is real and separate: upstream's shift is a Python scalar divided by a tensor, which torch evaluates as scalar * reciprocal(tensor), giving 0.99999994 at sigma == 1 rather than 1.0. At steps == 1 that one-ulp residue is the entire stretch anchor; computing in f32 gives exactly 1.0 and divides 0/0. That needs its own row.)
Why this matters beyond one arm
Every LTX-2.5 golden comparison and every MiniMax-H3 one routes through one of these two forms. A passing gate is not evidence of absence of NaN anywhere in either model. Any brick could be producing NaN in some regime with its gate reporting zero.
This is the same meta-pattern the LTX-2.5 spec records in §7.0: the instrument cannot see the defect. Previous instances were a golden reduced to isfinite (hiding a 23,842x-tolerance dtype error) and a fixture whose inputs could not separate a correct implementation from one ignoring an entire input stream. This one is the comparison helper itself.
Wants
- Harden every
MaxAbsDiff-style helper so a NaN operand is a failure, not a zero — e.g. propagate explicitly, or REQUIRE(std::isfinite(...)) per element.
- Re-run every affected suite after hardening and report whether anything goes red. That is the part that matters: the fix is trivial, the question is what it uncovers.
- Audit for other NaN-blind reductions (
std::max/> over computed values) in test helpers.
Affected today: test_ltx2.cpp, test_ltx2_vae.cpp, test_ltx2_text_encoder.cpp, test_ltx2_pipeline.cpp, test_minimax_h3.cpp, and likely test_deepseek_v4_forward.cpp:174 / test_deepseek_v4_mtp.cpp:215 (same signature, bodies unverified).
🤖 Generated with Claude Code
Found while repairing LTX-2.5 phase L5 (#435, PR #437), where it concealed a real defect. It is not confined to LTX-2.5 —
test_minimax_h3.cpphas the same form, and that is a shipped model.The defect
Two spellings of the same helper, both NaN-blind:
Demonstrated:
So a brick that emits all NaN, compared against entirely correct goldens, reports
max|diff| = 0.0and passes every bound. The comparison helper cannot see the defect class it exists to catch.How it was found, and what it hid
L5's repair added a sweep over sigma-schedule step counts and found
Ltx2SigmaSchedule(1, ...)returning{-nan, 0}where upstream returns{0.10000002, 0}. TheOneSteparm had been comparing NaN against a correct golden and reportingworst = 0.0— green.(The underlying
steps == 1defect is real and separate: upstream's shift is a Python scalar divided by a tensor, which torch evaluates asscalar * reciprocal(tensor), giving0.99999994at sigma == 1 rather than1.0. Atsteps == 1that one-ulp residue is the entire stretch anchor; computing in f32 gives exactly1.0and divides 0/0. That needs its own row.)Why this matters beyond one arm
Every LTX-2.5 golden comparison and every MiniMax-H3 one routes through one of these two forms. A passing gate is not evidence of absence of NaN anywhere in either model. Any brick could be producing NaN in some regime with its gate reporting zero.
This is the same meta-pattern the LTX-2.5 spec records in §7.0: the instrument cannot see the defect. Previous instances were a golden reduced to
isfinite(hiding a 23,842x-tolerance dtype error) and a fixture whose inputs could not separate a correct implementation from one ignoring an entire input stream. This one is the comparison helper itself.Wants
MaxAbsDiff-style helper so a NaN operand is a failure, not a zero — e.g. propagate explicitly, orREQUIRE(std::isfinite(...))per element.std::max/>over computed values) in test helpers.Affected today:
test_ltx2.cpp,test_ltx2_vae.cpp,test_ltx2_text_encoder.cpp,test_ltx2_pipeline.cpp,test_minimax_h3.cpp, and likelytest_deepseek_v4_forward.cpp:174/test_deepseek_v4_mtp.cpp:215(same signature, bodies unverified).🤖 Generated with Claude Code