Repository navigation
Conversation
Capture Python DSpark context projection and KV writes during startup, then replay compact or borrowed Slot bindings without runtime capture. Reuse the device-state task pipeline for fixed-width DSpark proposals and preserve its Markov sampling semantics. Admit DP=1, single-request capacity explicitly, and warm both final Slot bindings independently from target verification graphs. Cover startup ordering, prepared graph parity, changing KV lengths, rejected context slots, and state continuation with focused native and Python tests.
PixelFlat
requested review from
DongheJin,
DragonFive,
JimHsiung,
Kang-Meng,
XuZhang99,
liutongxuan,
xiao-yu-chen,
yingxudeng and
zhang-minchao
as code owners
October 12, 2026 11:08
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
Hide internal torch_npu_kernels symbols at the parent CMake target to prevent incompatible OpParamCache definitions from binding across xLLM and libop_plugin_atb. Keep the submodule source and revision unchanged. Add FP16 and BF16 repeated KV cache-write regressions covering valid and masked slots with torch_npu loaded.
XuZhang99
approved these changes
Oct 12, 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.
Description
Capture Python DSpark context KV updates in ACL graphs and reuse the existing task execution pipeline for DSpark decoding.
Capture context projection, normalization, RoPE, and KV scatter during startup on a private capture stream. Compact execution warms all accepted-row buckets; pipeline execution warms both final Slot bindings with no-write cache slots.
Replay the pipeline's borrowed target hidden states, positions, and cache-slot views directly. Keep rejected-row masking, context writes, and next-round state handoff on the ordered device stream instead of compacting and uploading accepted rows through the host.
Add DSpark-specific fixed-width draft bindings and anchor-row sampling while preserving the sequential Markov bias dependency between proposals. Keep target verification, draft forward, and context update graphs distinct.
Keep the prepared draft's FIA capacity constant while reading live device KV lengths. Missing startup bindings fail explicitly; only declared out-of-capacity queries take the existing eager path, without runtime capture or exception fallback.
Isolate internal ATB cache symbols in the parent
third_party/CMakeLists.txtso KV writes cannot bind to incompatibletorch_npuplugin cache definitions. Include the FP16/BF16 regression test; no submodule source or revision changes are needed.Task pipeline admission is currently limited to DP=1 and single-request capacity (
max_seqs_per_batch=1). The existing non-pipeline DSpark DP graph path remains available. This PR does not change target quantization or weight-loading formats.Related Issues
Follow-up optimization to #2440 and #2473.
Change Type
Validation
On Linux ARM64 / Ascend NPU, the implementation branch passed:
python setup.py build --device npu --tilelang-jobs 4.atb_cache_isolation,context_kv_acl_graph,model_executor,qwen3_dflash,qwen3_dspark,decode_acl_graph,prepared_acl_graph,eplb_runtime_bridge, andnpu_paged_attention.RuntimeError: Invalid argument) and passed with the included fix.These NPU results were collected before rebasing and consolidating the PR onto current
main. The validation build included the ATB cache symbol-isolation fix, now included in this PR as a separate bugfix commit. The consolidated PR head passed changed-file pre-commit checks, including clang-format 20.1.6; it has not received a fresh NPU rerun. This is focused validation, not a claim that the completepython setup.py testsuite passed.Performance
All cases use the same GLM-5.2 static W8A8 target, Python model implementation, TP=16 / DP=1 / EP=1, ACL graphs, and asynchronous scheduling. DSpark always uses seven draft steps; MTP uses three steps with task pipeline enabled. The DSpark columns compare recorded configurations at the corresponding implementation stages. One unchanged ShareGPT request with 1,868 input tokens and 128 output tokens, concurrency 1, explicit
temperature=0, two warmup requests followed by five non-profiled measurements. Memory settings were unchanged between cases.The DSpark baseline already enables target/draft graphs and asynchronous scheduling, but uses eager context KV updates and no task pipeline. The middle DSpark column enables context KV graphs without task pipeline; the final DSpark column enables both optimizations.
Acceptance rate is the mean of the five per-request rates. Accepted draft tokens per round is total accepted draft tokens divided by total draft rounds; it excludes the target correction/bonus token.
DSpark TPOT changed from 16.10 ms to 13.56 ms in these five-run means (15.8% lower). Acceptance and draft-round counts also vary, so these separately collected results do not isolate the causal contribution of each optimization or establish a universal speedup. Full-model dynamic W8A8 validation and DSpark task pipeline with DP>1 are outside this validation scope.
Timeline Evidence
Each trace is a separate single HTTP request after warmup, captured on rank 0/device 0. Steady decode analysis excludes the initial boundary and final incomplete round. The three DSpark traces contain 44, 43, and 39 complete steady rounds respectively. These profiled intervals are diagnostic data, separate from the five-request non-profiled performance table.
Context is inside the graph: the optimized device trace repeatedly shows
draft -> target -> contextgraph launches. Betweengreedy_prefix_verify_kerneland the next draft, one independentMODEL_EXECUTEis followed by context MatMul, RMSNorm and RoPE operations, then fivereshape_and_cache_200000000kernels. The latest trace records 41 draft, 41 target, and 41 context graph executions. All 16 ranks warm two borrowed context bindings; startup capture counters remain unchanged during serving.For a concrete optimized interval, relative to the first timestamped
Xevent, verification starts at 821.8435 ms, the contextMODEL_EXECUTEstarts at 821.88375 ms, context computation runs from 821.88825 to 822.29875 ms, and the next draft starts at 822.3685 ms. The control event's 3.46 us duration is not the context graph's execution time.Reduced state-handoff bubble: versus context-graph-only execution, the post-verify interval decreases from 3.750 to 0.520 ms. The recorded compute/copy union occupies 0.787 and 0.488 ms respectively; subtracting that union leaves approximately 2.963 versus 0.031 ms uncovered within the selected window. Recorded host API starts in this window change from about 28.0
Node@launch, 8.0 synchronous copies, 19.9 asynchronous copies, and 10.0 stream synchronizations per round to zero for those categories. Pipeline host preparation can occur earlier: this does not mean all host work or every device bubble has disappeared.Intervals include dependent device work, not just idle time. Work envelopes must not be summed across overlapping streams; the uncovered interval is a recorded-task gap proxy, not a measurement of every rank's utilization. Phases are identified by actual attention/context kernels, not Model Id. Analysis used JSON events; Perfetto UI inspection was not performed.
The latest MTP3 trace has about 1.626 ms summed draft work across three forwards versus DSpark's 1.435 ms single draft forward. Its target work envelope is 33.883 ms versus DSpark's 38.381 ms: the remaining difference in this observation is predominantly wider target verification, not a slower DSpark draft.
Pull Request Checklist
mainat submission time.python setup.py build testrerun on the consolidated PR head.Reviewer Notes
Please focus on final Slot binding lifetimes and stream ordering, no-write startup context warmup, DSpark's N-row draft versus N+1-row verification contract, and preservation of Markov proposal sampling. The prerequisite ATB cache isolation is included as a separate commit. It changes parent-repository target visibility only; the
torch_npu_opssubmodule remains unchanged.Summary by CodeRabbit