feat: add DFlash block-diffusion speculative decoding on npu device.#1886
feat: add DFlash block-diffusion speculative decoding on npu device.#1886ustcfy wants to merge 1 commit into
Conversation
There was a problem hiding this comment.
Code Review
This pull request introduces the 'DFlash' speculative decoding algorithm, implementing the DFlashWorkerImpl and DFlashQwen3Model to support block-diffusion speculative decoding. Key changes include skipping tokenizer initialization for draft engines, handling non-causal draft queries eagerly, and materializing target hidden states into the draft's KV cache. The code review feedback highlights opportunities to improve robustness and performance, specifically by resolving inconsistent null-pointer checks in DFlashWorkerImpl::init_model, investigating the performance bottleneck of stream synchronization in AclGraphExecutorImpl::replay, marking DFlashQwen3ModelImpl as final per the style guide, and fixing a signed/unsigned comparison warning in Qwen3MoeModelImpl.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
There was a problem hiding this comment.
Pull request overview
This PR introduces NPU-side DFlash (block-diffusion) speculative decoding for Qwen3 targets, including a dedicated draft model path that can materialize context K/V from captured target hidden states, plus ACL-graph support for DFlash chunked-prefill verify and several correctness guards/fixes around auxiliary hidden capture and persistent attention masks.
Changes:
- Add DFlash draft model + context-K/V materialization helper, and wire a new
DFlashWorkerImplspeculative worker into runtime/engine/model registry. - Extend ACL graph execution and persistent-parameter handling to support DFlash chunked-prefill verification and correct persistent attention-mask reuse.
- Update speculative config/options/tokenizer handling to support draft engines and the new
"DFlash"algorithm.
Reviewed changes
Copilot reviewed 25 out of 25 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| xllm/pybind/args.py | Expose DFlash as a CLI speculative algorithm option. |
| xllm/models/models.h | Register/include the new NPU DFlash Qwen3 model header. |
| xllm/models/llm/npu/qwen3.h | Enable aux-hidden capture for Eagle3/DFlash targets; add chunked-prefill attn-mask sourcing; add capture count guard; add overridable mask builder. |
| xllm/models/llm/npu/qwen3_moe.h | Same aux-hidden capture gating/guarding for Qwen3-MoE targets. |
| xllm/models/llm/npu/qwen3_dflash.h | New DFlash draft model impl (Qwen3-based) + registry/args loader; custom non-causal mask override. |
| xllm/models/llm/npu/dflash_context_kv.h | New helper to project captured target hidden into per-layer draft K/V cache (fc→norm→fused KV linear→k_norm+RoPE→scatter). |
| xllm/models/CMakeLists.txt | Ensure models link NPU xllm_ops needed by new scatter ops. |
| xllm/core/util/utils.h | Add helpers for DFlash draft model-type detection and “aux-hidden-capturing” algorithm whitelist. |
| xllm/core/runtime/worker.cpp | Instantiate DFlashWorkerImpl when --speculative_algorithm=DFlash. |
| xllm/core/runtime/worker_impl.cpp | Fix graph-prepare guard for speculative workers; adjust tokenizer usage for draft engines; add DFlash layers_to_capture plumbing from draft config. |
| xllm/core/runtime/spec_input_builder.h | Declare build_validate_tensors_from_block for block drafters (DFlash). |
| xllm/core/runtime/spec_input_builder.cpp | Add shared scatter_selected_to_dense helper; implement build_validate_tensors_from_block. |
| xllm/core/runtime/options.h | Add Options::is_dflash() helper keyed on the configured algorithm string. |
| xllm/core/runtime/eagle3_worker_impl.cpp | Add cp_size>1 guard for aux-hidden-based draft driving (EAGLE-3). |
| xllm/core/runtime/dflash_worker_impl.h | New DFlash speculative worker interface. |
| xllm/core/runtime/dflash_worker_impl.cpp | New DFlash speculative worker implementation (draft query/build/validate/materialize context K/V/caching). |
| xllm/core/runtime/CMakeLists.txt | Build and link the new DFlash worker implementation. |
| xllm/core/runtime/acl_graph_persistent_param.cpp | Add DFlash chunked-prefill support and fix persistent attn-mask tail reuse correctness. |
| xllm/core/runtime/acl_graph_executor_impl.cpp | Add DFlash graph keys + chunked-prefill handling + eager fallbacks for non-causal draft query and context-K/V phase. |
| xllm/core/layers/common/attention_metadata_builder.cpp | Allow ACL graph path for block-diffusion chunked-prefill metadata. |
| xllm/core/framework/model/model_input_params.h | Add write_context_kv embedding flag and DFlash graph flags (is_block_diffusion_graph, causal). |
| xllm/core/framework/config/speculative_config.cpp | Document DFlash in the supported algorithm flag help text. |
| xllm/core/distributed_runtime/worker_server.cpp | Block spawned-worker mode for aux-hidden speculative workers (Eagle3/DFlash). |
| xllm/core/distributed_runtime/speculative_engine.cpp | Allow graph on draft engine for DFlash; remove draft/target tokenizer compatibility checks. |
| xllm/core/distributed_runtime/llm_engine.cpp | Skip tokenizer initialization for draft engines; guard vocab-size checks accordingly. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
7dc8aa2 to
0540cf7
Compare
|
感谢 @gemini-code-assist 的 review。已在 commit 1. 2. 3. 4. |
|
感谢你的详细回复和对这些技术细节的深入说明。你对 关于 既然该 PR 已经涵盖了核心的 DFlash 投机解码逻辑及相关的正确性修复,期待后续在设备侧 event wait 等优化方向上的进一步探索。感谢你对代码质量的严谨把控。 |
0540cf7 to
a8469cb
Compare
a8469cb to
0c8c70c
Compare
| return false; | ||
| } | ||
| } | ||
| // Modern speculative algorithms (MTP / EAGLE / EAGLE3 / DFlash) drive the |
There was a problem hiding this comment.
The vocabulary in eagle3 might be inconsistent with the original model? Therefore, eagle3_worker_impl now has a map operation.
| @@ -0,0 +1,345 @@ | |||
| /* Copyright 2026 The xLLM Authors. All Rights Reserved. | |||
There was a problem hiding this comment.
Is it necessary to create a separate file in this model directory specifically for DFlash?
d4c5517 to
bb51c5d
Compare
5fdf3d0 to
e1296d4
Compare
4d95ac3 to
99e0722
Compare
9a3dc1e to
b582085
Compare
描述
在 NPU/ATB 后端引入 DFlash(block-diffusion)投机解码。draft 用 target 捕获的中间层 hidden,一次非因果前向并行产出一整块候选 token;target 用共享的 rejection sampler 一次性验证整块,取最长匹配前缀 + 1 个 bonus token。
支持的 target:
qwen3.h/qwen3_moe.h打开。model_type=DFlashDraftModel),不论 target 是 dense 还是 MoE,draft 自身从不跑 expert。核心组件:
DFlashWorkerImpl(runtime):prepare_query_inputs/run_decode_draft/run_validate/write_context_kv/write_target_context_to_cache,与 MTP 解耦。DFlashQwen3ModelImpl:fc→ RMSNorm → fused per-layer K/V linear → per-layer k_norm + RoPE → scatter。权重加载跨 checkpoint 分片累积后再融合成 layer-major 的 fused K/V 权重。DFlashQwen3draft 模型 +REGISTER_CAUSAL_MODEL(DFlashDraftModel, ...)注册。dflash_worker_impl.cpp)与 EAGLE-3(eagle3_worker_impl.cpp)拒绝 context parallelism(cp_size > 1),否则会把错误的(lm_head-gathered)hidden 喂给 draft。use_sliding_window=true被 xLLM NPU FIA silently 忽略(aclnnFIA hard-codepre_tokens=INT_MAX)。本 PR 不加 fail-fast 阻断,与主流框架一致——真正的 SWA 支持是独立 track。顺带修复的正确性问题:
qwen3_moe.hforward 返回 aux hidden 前补CHECK_EQ(capture_idx, layers_to_capture_set_.size())(与qwen3.h对齐),使越界的target_layer_id快速失败,而不是把未初始化内存喂给 draft。enable_opt_validate_probs),使共享 rejection sampler 及其 fused kernel 恒收到dim==3的 probs;与 selected-only 输出分布等价。dense scatter 在build_validate_tensors_from_block中内联,与 MTPbuild_validate_tensors语义一致。相关 Issue
变更类型
验证
数据集 gsm8k、greedy、
num_speculative_tokens=15、block_size=16、20 prompts、concurrency=1:主二进制
python setup.py build --device npu编译通过。Reviewer Notes
num_seq × (num_spec+1)行数会桶化成多个 shape 档,capture + padding 开销盖过 launch 节省。近期实测吞吐相对 eager 大致为 C=1/4/16 −0.5% / −4% / −3%,中并发 C=32/64/128 −3% / −13% / −7%(acl_graph_decode_batch_size_limit默认 16,batch>16 触发 fallback eager 但仍付 capture-attempt 开销)。盈利化需要固定-shape 的 verify capture(uniform-decode 做法),是独立工作,不在本 PR。kv_len),这是正确性要求的 fallback。Followups