Repository navigation
[test] add a shared numerical alignment tool with a baseline-error rule - #6487
Merged
Merged
Conversation
Add tests/kit/numerics, a shared tool for judging whether an implementation
matches a reference numerically. The rule follows PyTorch TorchInductor accuracy
check: the baseline error is how far the reference implementation deviates from
a float64 truth at the tested precision, and the tested output may deviate at
most 3x (fp16/bf16) or 2x (fp32) as much, with a larger allowance for small
tensors.
- compare.py: flatten nested outputs, float64 metrics (rmse, max abs, rel l2, cosine)
- judge.py: judge / assert_aligned with a per-tensor report
- capture.py: run_fwd_bwd with a fixed upstream gradient for op/module checks
- README.md: the rule, runnable examples, how to read the report
- trace.py: Trace, one run as {name: tensor} plus metadata, saved as a single
safetensors file so runs from different machines can be judged offline
The unit tests check that a reordered summation passes while a dropped column
fails, that saved traces round-trip bit-exactly, and run on CPU in the CPU unit
test job.
The Layer 1 CPU job calls run_colossalai_batch.sh cpu, which keeps its own test list separate from run_cpu_unit_tests.sh used by the fork-safe gate. Without this entry the new tests would only run in the fork-safe gate.
JazyJiang
marked this pull request as ready for review
October 27, 2026 10:23
yuxuan-lou
approved these changes
Oct 27, 2026
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.
No linked issue. This adds shared test tooling; it does not fix a reported bug.
1. Background and problem
Current behaviour. Tests that compare an implementation with a reference use hand-picked
atol/rtolper test. Undertests/test_shardformer/test_modelalone there are more than ten different pairs, a few loosened to4e-2or9e-2with no recorded reason.Problem. The error a correct low-precision implementation makes differs by orders of magnitude between models and between tensors of the same model. A fixed tolerance tight enough for one rejects correct code in another, and a loose one hides real bugs. Once a tolerance has been loosened, nobody can tell whether it absorbs rounding noise or a bug. Each new model or kernel test picks its own number again, and there is no way to compare runs made on different machines (e.g. GPU and NPU).
Expected behaviour. One shared rule whose allowance is measured, not chosen: for every tensor, the implementation under test may deviate from a float64 ground truth by at most a small multiple of how far the reference implementation itself deviates at the same precision.
Why now. New models, kernels and optimizers are being added that all need a reference comparison. Having one tool before they write their tests avoids a new set of fixed tolerances.
2. What changed
New module
tests/kit/numerics(test-only, nothing undercolossalai/changes):judge.py:judge(test, ref, truth)andassert_aligned(...). Per tensor,baseline error = RMSE(ref, truth),test error = RMSE(test, truth); passes iftest error <= multiplier * baseline error + tol / 10, withmultiplier3 for fp16/bf16 and 2 for fp32 (at least 3 below 1000 elements); anallclose(test, ref)fast path passes first. This is the rule PyTorch uses fortorch.compileaccuracy checks (same(..., fp64_ref=...)intorch/_dynamo/utils.py). Returns a per-tensor report; failures are listed first with their ratio.capture.py:run_fwd_bwd(fn, inputs, dtype)runs a function ornn.Moduleforward and backward at a given dtype with a fixed random upstream gradient, so the float64 truth, the reference and the test see identical inputs, weights and gradients. TF32 is disabled during the run.trace.py:Trace, one run as{name: tensor}plus metadata. Saved as a single.safetensorsfile with the metadata as JSON in the header (no pickle, dtypes preserved), so runs from different machines can be judged offline.compare.py: flattening of nested outputs and float64 metrics (RMSE, max abs, relative L2, cosine).README.md: the rule, runnable operator and module examples, how to read the report, and what makes a comparison meaningless (different precision recipes, shared code between reference and test).tests/test_numerics/test_numerics_core.py: 14 CPU tests. Registered in both CPU test lists: thecpubatch of.github/scripts/ci/run_colossalai_batch.sh(Layer 1) and.github/scripts/ci/run_cpu_unit_tests.sh(Fork-safe PR Gate). The two lists are maintained separately.Not included in this PR:
tests/kit/model_zooand runs them through booster plugins.3. User and compatibility impact
tests/kit)CI: one more file in the CPU unit test job, about 3 s.
4. Test environment
CPU only; no GPU is needed or used by these tests. Two environments, matching the two CI jobs that run CPU tests.
A. Repository CI image (the image used by the GPU batches), on the CI host:
CUDA_VISIBLE_DEVICES=empty)torch.version.cuda13.0, not exercised)sha256:ae8ff34bf340a692803edca6e0f38a576fc1a2b206c01b4ef6f7c2a40dfd8c10(currentCOLOSSAL_CI_IMAGE)515e8354(this branch, on top ofcb3b2234)B. Same packages as the GitHub-hosted CPU jobs: fresh Python 3.10.12 virtualenv with
torch==2.5.1from the PyTorch CPU index,pip install -r requirements/requirements.txt(Transformers 5.17.0, safetensors 0.8.0) andpytest, as inci_layer_1_pr.yml/fork_pr_checks.yml. Commit407f6840(the second commit only adds a list entry).5. Test commands and results
5.1 Layer 1 cpu batch (environment A)
tests/test_numericscases, all passedtests/test_checkpoint_io/test_optimizer_safetensors_v2.py("Requires a guarded CUDA device")FAST_TEST=1(set by the batch script); it does not affect these tests. No rerun, no xfail, no ignore$COLOSSAL_RESULTSby the batch script5.2 CI helper tests (environment A)
5.3 GitHub CPU job packages (environment B)
run_cpu_unit_tests.sh: exit code 0; 2 skipped (the same CUDA-guarded cases); the total count was not recorded in this runtests/test_numerics: 14 passed in 1.34 s5.4 README examples
Every Python block in
tests/kit/numerics/README.mdwas extracted and executed in order in environment A: the attention example passesassert_aligned, the module example reports 4/4 tensors aligned (max ratio 1.33), and the saved traces reload and judge identically.6. Known issues
None introduced by this PR.
tf5.17.0-exp-20261019, not the currentCOLOSSAL_CI_IMAGE),tests/test_infer/test_async_engine/test_request_tracer.pyfails at collection because its diffusers importsFLAX_WEIGHTS_NAME, which Transformers 5.17 removed. Reproduced onmain(cb3b2234) without this change, and absent in the current image (diffusers 0.35.2). Not addressed here.7. Risks and rollback
Risk. A multiplier that is too tight for some operator would make a correct kernel fail. The self-tests leave a wide margin: a legitimate reordering of the summation reaches a ratio of at most 1.18 (limit 3), while dropping one column of the reduction dimension gives at least 20 in bf16 and over 10^5 in fp32.
Rollback. Revert the commit. Nothing outside
tests/and one line of the CPU test list depends on it.8. Docs and release impact
tests/kit/numerics/README.md).version.txt, PyPI, DockerHub: none.