@@ -5,12 +5,19 @@ End-to-end guide for training a **DFlash** draft model for **Qwen3-8B** on
55target and extracts hidden states on the fly). Hyperparameters are aligned to the
66SpecForge ` docs/ascend_npu/run_qwen3_8b_dflash_npu.sh ` reference run.
77
8- > ** Status (June 2026).** ✅ ** Verified end-to-end on NPU** (vllm-ascend 0.20.2rc1,
9- > CANN 9.0.0): prepare → online vLLM hidden-state extraction → FSDP DFlash training
10- > all run and produce loss + checkpoints. The ` extract_hidden_states ` path works on
11- > the vllm-ascend NPU runner. Hyperparameters align to the SpecForge ascend_npu
12- > reference (gaps in §2.1 use speculators defaults). Install: see
13- > [ ` ascend-npu-conda.md ` ] ( ./ascend-npu-conda.md ) .
8+ > ** Status (June 2026).** ⚠️ ** Partially working — DFlash training is BLOCKED on NPU
9+ > by an upstream bug.** What's verified: install, data prep, and the online vLLM
10+ > ` extract_hidden_states ` path (vLLM serves Qwen3-8B on the NPU runner and writes
11+ > hidden states; the fc dimension / layer alignment is correct). What's blocked: the
12+ > ** DFlash forward** — it uses ` flex_attention ` (` simple_flex_attention ` ), which
13+ > PyTorch rejects on NPU (`FlexAttention is only supported on CUDA, CPU or HPU
14+ > devices`, issue
15+ > [ #531 ] ( https://github.com/vllm-project/speculators/issues/531 ) , open), and its
16+ > ` @torch.compile ` fails to codegen on triton-ascend (NPU flavor of
17+ > [ #544 ] ( https://github.com/vllm-project/speculators/issues/544 ) / PR #547 ). The
18+ > training loop never completes a step. ** EAGLE3 and PEAGLE share the same flex
19+ > blocker; only MTP uses eager attention and could train on NPU today.** See §9.
20+ > Install: [ ` ascend-npu-conda.md ` ] ( ./ascend-npu-conda.md ) .
1421
1522## 1. Prerequisites
1623
@@ -216,7 +223,10 @@ appended; that field name is a vLLM naming artifact, the `method` is still
216223> an absolute ` $HS_DIR ` in both terminals removes all cwd ambiguity; a mismatch
217224> silently stalls online training.
218225
219- ## 6. Step 3 — train the DFlash draft (FSDP) ✅ verified
226+ ## 6. Step 3 — train the DFlash draft (FSDP) ⚠️ blocked on NPU (see §9)
227+
228+ The command below is correct (hyperparameters + layer alignment), but on NPU it
229+ currently crashes in the ** first forward** before any step completes — see §9.
220230
221231``` bash
222232# terminal 2, 6 training cards (2-7); vLLM holds 0,1. TASK_QUEUE_ENABLE=2 ok here
@@ -278,3 +288,39 @@ online path is confirmed or ruled out on NPU.
278288` ./output/qwen3-8b-dflash-npu/checkpoints/<epoch>/ ` holds a self-contained
279289speculator (` config.json ` , ` model.safetensors ` , optimizer/scheduler state). Each is
280290deployable in vLLM. (Qwen3 draft vLLM-deploy compatibility — see §2 note ².)
291+
292+ ## 9. ⚠️ Known blocker: DFlash forward on NPU
293+
294+ The DFlash draft forward fails on NPU for two compounding reasons (neither is a
295+ config error):
296+
297+ 1 . ** ` flex_attention ` is not supported on NPU.** DFlash forces
298+ ` simple_flex_attention ` (` models/dflash/core.py ` ), and PyTorch's ` flex_attention `
299+ raises `FlexAttention is only supported on CUDA, CPU or HPU devices. Found input
300+ tensors on npu device` — tracked in
301+ [ #531 ] ( https://github.com/vllm-project/speculators/issues/531 ) (open). ** EAGLE3
302+ and PEAGLE force the same ` simple_flex_attention ` , so they're blocked too.**
303+ 2 . ** ` @torch.compile ` on the forward fails to codegen on triton-ascend.** With
304+ ` block_size=16 ` the generated ` copy_full_slice ` kernel dies with
305+ ` NoTritonConfigsError: ... Cannot broadcast [8,16] vs [8,1] ` (NPU flavor of
306+ [ #544 ] ( https://github.com/vllm-project/speculators/issues/544 ) / PR #547 ).
307+ ` export TORCHDYNAMO_DISABLE=1 ` makes ` @torch.compile ` a no-op (eager forward) and
308+ gets past this — but then you hit blocker #1 .
309+
310+ ** Algorithm support on NPU (by attention impl):**
311+
312+ | Algorithm | Attention | NPU today |
313+ | ---| ---| ---|
314+ | DFlash / EAGLE3 / PEAGLE | ` simple_flex_attention ` | ❌ blocked (#531 ) |
315+ | MTP | ` eager ` (` models/mtp/core.py ` ) | ✅ viable (no flex) |
316+
317+ ** Options:**
318+ - ** Train MTP instead** — uses eager attention, no flex. Different algorithm (needs
319+ a native MTP head + ` --from-pretrained ` ), so not a like-for-like DFlash↔SpecForge
320+ comparison, but it actually trains on NPU now.
321+ - ** Patch DFlash to an eager / dense-mask attention path** — what #531 needs: replace
322+ the flex ` BlockMask ` (` create_block_mask ` ) with a materialized dense additive mask
323+ and route through ` eager_attention_forward ` , plus ` TORCHDYNAMO_DISABLE=1 ` .
324+ Non-trivial (mask formats differ) but feasible on an editable install; a real
325+ upstream contribution.
326+ - ** Track #531 / PR #547 ** for an upstream fix.
0 commit comments