[MLA] Deterministic single-split decode option for reproducible serving (fixes #4364)#4378
Open
MohitAMD wants to merge 1 commit into
Open
[MLA] Deterministic single-split decode option for reproducible serving (fixes #4364)#4378MohitAMD wants to merge 1 commit into
MohitAMD wants to merge 1 commit into
Conversation
The MLA decode split-KV reduce is fp-non-associative, so a request's decode output depends on how many KV splits it is given. That per-request split count is drawn from the GLOBAL budget min(cu_num, max_split_per_batch * batch_size), which varies with batch composition -- so two identical requests at temperature 0 can land on different split counts across steps and produce slightly different logits. On GLM-5.1-FP8 DSA this shows up as +/-1-2 NIAH needles at mid context. Repro (op_tests/test_mla_qh16_decode_determinism.py, MI300X/gfx942, nhead=16 fp8/fp8): the kernel is deterministic for a FIXED split count (split=1 and split=8 are each bit-stable run-to-run), but split=1 vs split=8 differ by max|d|=2.44e-3 -- i.e. the split count itself changes the numerics. Workaround: AITER_MLA_DECODE_DETERMINISTIC=1 (or AITER_MLA_DECODE_MAX_SPLIT_PER_BATCH=n) clamps get_mla_metadata_v1 to a single (or fixed) split per request, making the reduce a no-op and the output independent of batch composition. With it set, split=8 collapses onto the split=1 baseline (max|d|=0.000e+00). Opt-in; costs decode parallelism at long context. The durable fix is an order-stable reduce in the kernel. Fixes ROCm#4364.
Contributor
🏷️ CI GuideRuns automatically on every PR:
Extended tests (opt-in via labels):
|
Contributor
There was a problem hiding this comment.
Pull request overview
Adds an opt-in deterministic MLA decode mode by clamping the per-batch KV split cap via environment variables inside get_mla_metadata_v1, plus a standalone op_tests/ reproducer for issue #4364 to demonstrate split-count-dependent numerics and validate the workaround.
Changes:
- Add env-var-controlled clamping of
max_split_per_batchinaiter/ops/attention.pyto force single-split (or a fixed cap) for reproducible serving. - Add
op_tests/test_mla_qh16_decode_determinism.pyto reproduce and validate the determinism workaround on qh16 fp8/fp8 decode.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| op_tests/test_mla_qh16_decode_determinism.py | Adds a minimal standalone repro/validator for split-count-driven nondeterminism and the deterministic single-split workaround. |
| aiter/ops/attention.py | Adds env knobs to clamp decode split cap inside get_mla_metadata_v1 to stabilize numerics across batch composition. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+1427
to
+1430
| try: | ||
| _det_cap_i = int(_det_cap) | ||
| except ValueError: | ||
| _det_cap_i = 1 |
Comment on lines
+116
to
+118
| N = 8 | ||
| det_env = os.getenv("AITER_MLA_DECODE_DETERMINISTIC", "0") not in ("0", "") | ||
|
|
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.
Motivation
Closes #4364.
The MLA decode split-KV reduce is fp-non-associative, so a request's decode
output depends on how many KV splits it is given. The per-request split count is
drawn from the global budget
min(cu_num, max_split_per_batch * batch_size)(see
csrc/kernels/mla/metadata/v1_2_device.cuh), which varies with batchcomposition. Two identical requests at temperature 0 can therefore land on
different split counts on different steps and produce slightly different logits.
On GLM-5.1-FP8 (DSA, qh16 fp8 decode) this surfaces as run-to-run
nondeterminism — ±1–2 retrieved NIAH needles at mid context (20k–35k), while the
extremes (8k, 96k) are stable (#4364).
Reproducer
op_tests/test_mla_qh16_decode_determinism.py(added here) isolates the mechanismon a single MI300X (gfx942), nhead=16 fp8/fp8 persistent decode, batch=1, ctx=8192:
So the kernel is bit-stable for a fixed split count, but the result depends on
the split count — and production picks that count from the batch-dependent
budget, which is why identical requests drift run-to-run.
Workaround (this PR)
Opt-in env knobs, honored in
get_mla_metadata_v1:AITER_MLA_DECODE_DETERMINISTIC=1— force a single split per request(shorthand for the cap below = 1).
AITER_MLA_DECODE_MAX_SPLIT_PER_BATCH=<n>— pin the per-batch split cap to afixed
n(≥1), independent of batch size.Forcing a single split makes the reduce a no-op, so a request's output no longer
depends on batch composition and is reproducible. Clamping the cap down is
always buffer-safe (it can only reduce the number of partial-reduce entries
relative to what the caller already allocated).
Validation (same reproducer,
AITER_MLA_DECODE_DETERMINISTIC=1):Trade-off: forcing a single split removes decode split-K parallelism, so long
context / low batch decode loses some latency headroom. It is therefore opt-in
and intended for serving that requires reproducible outputs. The durable fix is
an order-stable reduce in the kernel (fixed split count + deterministic
accumulation order), which would keep both determinism and split-K performance;
happy to help test such a kernel change.
Test plan
op_tests/test_mla_qh16_decode_determinism.pyon MI300X (gfx942): baselineshows split-count-dependent numerics (
2.44e-3) with each fixed split countbit-stable;
AITER_MLA_DECODE_DETERMINISTIC=1collapses split=8 onto split=1(
max|d|=0) and PASSES.path at long context — reviewer/maintainer guidance welcome.
Env: ROCm 7.2.3, MI300X (gfx942), AITER v0.1.18, PyTorch 2.11, GLM-5.1-FP8.