Background
In pypto-lib, models/deepseek_v4_flash_mtp/prefill_fwd.py (l3_prefill_fwd, the packed-prefill program DeepSeek-V4-Flash serving uses) on a2a3 (8 devices) has a precision problem: any packed prefill extent above 128 tokens produces NaN logits with real W8A8 weights, and the NaN-derived routing then faults the follow-on MTP/decode program with an AICore "VEC instruction error: the ub address out of bounds", killing the request.
Reproduce with pypto-serving (hw-native-sys/pypto-serving PR #204, head a261960 — its KV-sizing ring-budget fix is required, otherwise a separate 4×ring_heap pooled-arena OOM on origin/main masks this failure first):
pypto-serving \
--model <w8a8 checkpoint dir> \
--prompt "<' and' repeated 150 times> Huawei is" \
--platform a2a3 --devices <8 free device ids> \
--dp 8 --ep 8 --block-size 128 \
--max-model-len 1024 --max-num-seqs 8 --max-num-batched-tokens 512 \
--long-prefill-token-threshold 4096 \
--generate-config '{"max_new_tokens": 16, "temperature": 0.0}' \
--num-speculative-tokens 1 --no-enable-prefix-caching \
--ring-dep-pool 131072 --ring-task-window 131072 --ring-heap 2147483648
Checkpoint: convert HF deepseek-ai/DeepSeek-V4-Flash with pypto-serving's scripts/convert_deepseek_v4_to_w8a8.py (procedure in pypto-serving docs/dev/model/deepseek-v4.md).
Observed — deterministic on 8 devices, per packed extent:
| Packed extent |
Result |
| 64, 128 tokens |
correct greedy generation |
| 129, 160, 256, 302 tokens |
Sampler received non-finite logits, then AICore 507015 → empty completion |
Reproduction environment:
| Component |
Version |
| pypto-lib |
85e0790 (main tip; two local inert harness patches noted below) |
| pypto |
7542c36d (main, detached) |
| simpler |
0659e29b (pypto runtime gitlink, detached) |
| ptoas |
0.60 |
| pto-isa |
be5ccb76 (per runtime/pto_isa.pin) |
| CANN |
9.0.0 |
All components match pypto 7542c36d's pin chain. Local-only patches while reproducing (inert to the repro): --save-data flag in prefill_fwd.py's harness main(), and a GOLDEN_DEVICE_OUT_DIR device-output dump hook in golden/runner.py — neither touches kernel code or the serving path.
Diagnosis: unclear (pypto-lib kernel authoring vs toolchain) — the corruption is inside l3_prefill_fwd's multi-tile (>128-token) walk, but pypto/simpler cannot be bisected against this pin: pypto-lib 85e0790 fails to compile under ptoas 0.59 at every pypto revision tried (6863c6dd, af8c15f4, 106df194, 8cf3f058 — all with 'pto.tcvt' op requires explicit tmp for non-saturating narrowing tcvt when PlanMemory is skipped), so 85e0790 has only ever executed on ptoas v0.60 + simpler 0659e29b.
Description
Evidence collected (all on the environment above):
- Failure chain:
l3_prefill_fwd emits non-finite logits for extents > 128 (host sampler warning fires immediately after prefill); the NaN activations produce garbage routing/top-k; the next program crashes with VEC instruction error: the ub address out of bounds (0x4000000000000000); the worker lane is poisoned and the request returns empty. Device plog names the faulting kernel aicore_kernel_0_mix_aic, which is simpler's merged-binary entry macro (KERNEL_ENTRY(x) = x##_0_mix_aic), so it identifies the program, not the scope; task_id/func_id 15 maps via the generated kernel_config.py to qr_proj_seed (decode program) or qr_rms_norm_quant (mtp-prefill program, launched with a dynamic t_dim/8 block count) — both in models/deepseek_v4_flash_mtp/qkv_proj_rope.py's qr-projection/quant pipeline.
- Ruled out: prefix caching (fails with
--no-enable-prefix-caching), host-side chunking (single 302-token dispatch with --long-prefill-token-threshold 4096 fails identically — the kernel-internal 128-token tile walk alone is sufficient), --max-model-len (260 vs 1024 identical), and all PTO2 runtime timeouts (PTO2_OP_EXECUTE_TIMEOUT_US=400000000 etc. changed nothing).
- Exact threshold: 128 tokens (one tile) passes; 129 fails — and 256 (two perfectly aligned tiles) also fails, so it is not a partial-tail-row artifact: any second tile corrupts. Requires real W8A8 weights: the standalone harness
python models/deepseek_v4_flash_mtp/prefill_fwd.py -p a2a3 -d <ids> --num-tokens 160 runs clean on random weights.
- The standalone harness cannot carry this repro — and hides a NaN of its own: with
golden_fn=None it prints [RUN] PASS (validation skipped). Dumping its device outputs (the local hook above) shows NaNs even at its default 128-token config at both extents tested (128 and 160): one fully-NaN logits row (logits [2, 8, 129280], 258560 NaN), pre_hc_hidden_out token row 95 fully NaN (32768/32768 elements, both ranks), plus NaN rows in kv_cache/csa_*/hca_* states. Whatever that artifact is, the golden path currently has no way to notice.
- This serving path has never been green on any pin: pypto-serving's main still pins pypto-lib
2a1809f, which fails at kernel-compile on current pypto (create_tensor init_value removal), so 85e0790 is the first pin that runs end-to-end — and pypto-lib's own CI skipped its serving-deepseek job at 85e0790 (its model-tests checks are red on main as of Aug 28).
Possibly related: #929 (same-tree buffer-state corruption), #1043 (different — probabilistic near-tie argmax).
Host Platform
Linux (aarch64), Ascend 910 (a2a3), 8 devices
Additional Context
Found via hw-native-sys/pypto-serving#204 CI (its k1-prefix-cache accuracy case is the only red test; all other extents in that matrix pass). Serving-side one-liner repro and full extent table in the Background. Happy to help narrow the faulting scope further on this machine (device access + the dumped standalone outputs are available).
Background
In pypto-lib,
models/deepseek_v4_flash_mtp/prefill_fwd.py(l3_prefill_fwd, the packed-prefill program DeepSeek-V4-Flash serving uses) ona2a3(8 devices) has a precision problem: any packed prefill extent above 128 tokens produces NaN logits with real W8A8 weights, and the NaN-derived routing then faults the follow-on MTP/decode program with an AICore "VEC instruction error: the ub address out of bounds", killing the request.Reproduce with pypto-serving (hw-native-sys/pypto-serving PR #204, head
a261960— its KV-sizing ring-budget fix is required, otherwise a separate 4×ring_heappooled-arena OOM on origin/main masks this failure first):Checkpoint: convert HF
deepseek-ai/DeepSeek-V4-Flashwith pypto-serving'sscripts/convert_deepseek_v4_to_w8a8.py(procedure in pypto-servingdocs/dev/model/deepseek-v4.md).Observed — deterministic on 8 devices, per packed extent:
Sampler received non-finite logits, then AICore 507015 → empty completionReproduction environment:
85e0790(main tip; two local inert harness patches noted below)7542c36d(main, detached)0659e29b(pyptoruntimegitlink, detached)0.60be5ccb76(perruntime/pto_isa.pin)9.0.0All components match pypto
7542c36d's pin chain. Local-only patches while reproducing (inert to the repro):--save-dataflag inprefill_fwd.py's harnessmain(), and aGOLDEN_DEVICE_OUT_DIRdevice-output dump hook ingolden/runner.py— neither touches kernel code or the serving path.Diagnosis: unclear (pypto-lib kernel authoring vs toolchain) — the corruption is inside
l3_prefill_fwd's multi-tile (>128-token) walk, but pypto/simpler cannot be bisected against this pin: pypto-lib85e0790fails to compile under ptoas 0.59 at every pypto revision tried (6863c6dd,af8c15f4,106df194,8cf3f058— all with'pto.tcvt' op requires explicit tmp for non-saturating narrowing tcvt when PlanMemory is skipped), so85e0790has only ever executed on ptoas v0.60 + simpler0659e29b.Description
Evidence collected (all on the environment above):
l3_prefill_fwdemits non-finite logits for extents > 128 (host sampler warning fires immediately after prefill); the NaN activations produce garbage routing/top-k; the next program crashes withVEC instruction error: the ub address out of bounds (0x4000000000000000); the worker lane is poisoned and the request returns empty. Device plog names the faulting kernelaicore_kernel_0_mix_aic, which is simpler's merged-binary entry macro (KERNEL_ENTRY(x) = x##_0_mix_aic), so it identifies the program, not the scope;task_id/func_id 15maps via the generatedkernel_config.pytoqr_proj_seed(decode program) orqr_rms_norm_quant(mtp-prefill program, launched with a dynamict_dim/8block count) — both inmodels/deepseek_v4_flash_mtp/qkv_proj_rope.py's qr-projection/quant pipeline.--no-enable-prefix-caching), host-side chunking (single 302-token dispatch with--long-prefill-token-threshold 4096fails identically — the kernel-internal 128-token tile walk alone is sufficient),--max-model-len(260 vs 1024 identical), and all PTO2 runtime timeouts (PTO2_OP_EXECUTE_TIMEOUT_US=400000000etc. changed nothing).python models/deepseek_v4_flash_mtp/prefill_fwd.py -p a2a3 -d <ids> --num-tokens 160runs clean on random weights.golden_fn=Noneit prints[RUN] PASS (validation skipped). Dumping its device outputs (the local hook above) shows NaNs even at its default 128-token config at both extents tested (128 and 160): one fully-NaN logits row (logits[2, 8, 129280], 258560 NaN),pre_hc_hidden_outtoken row 95 fully NaN (32768/32768 elements, both ranks), plus NaN rows inkv_cache/csa_*/hca_*states. Whatever that artifact is, the golden path currently has no way to notice.2a1809f, which fails at kernel-compile on current pypto (create_tensor init_valueremoval), so85e0790is the first pin that runs end-to-end — and pypto-lib's own CI skipped itsserving-deepseekjob at85e0790(itsmodel-testschecks are red on main as of Aug 28).Possibly related: #929 (same-tree buffer-state corruption), #1043 (different — probabilistic near-tie argmax).
Host Platform
Linux (aarch64), Ascend 910 (a2a3), 8 devices
Additional Context
Found via hw-native-sys/pypto-serving#204 CI (its
k1-prefix-cacheaccuracy case is the only red test; all other extents in that matrix pass). Serving-side one-liner repro and full extent table in the Background. Happy to help narrow the faulting scope further on this machine (device access + the dumped standalone outputs are available).