perf(qwen36): add SpecLA factor-capture speculative decoding - #606
Conversation
27417ca to
5f38668
Compare
|
@cubic-dev-ai review this PR |
@Graffioh I have started the AI code review. It will take a few minutes to complete. |
There was a problem hiding this comment.
1 issue found across 33 files
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="server/src/qwen35/qwen35_dflash_target.cpp">
<violation number="1" location="server/src/qwen35/qwen35_dflash_target.cpp:609">
P2: The SpecLA bank-rotation / `specla_compact_fused` / `specla_flush_raw_fused` logic is copied nearly verbatim between this file and `server/test/test_dflash.cpp`. `rollback_to_tree` (walked_sibling compaction + `current_bank`/`old_pending_bank` rotation + `pending_count` update), `finish_speculative_state` (bank selection via `specla_pending_bank` + `specla_flush_raw_fused`), and `rollback_to_specla` (bank toggle + count) each have a hand-maintained mirror in the bench harness. These are the two most state-sensitive routines in the PR; any divergence between the production target and the harness (e.g. the `ne` bounds, channel mapping, or bank-toggle logic) silently changes acceptance behavior. Pull the shared commit/flush helpers into a common function (e.g. in `specla_commit_cuda.h/.cu`) and have both call sites invoke it.</violation>
</file>
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
e7dc8f0 to
c775f9e
Compare
|
@cubic-dev-ai review this PR |
@Graffioh I have started the AI code review. It will take a few minutes to complete. |
There was a problem hiding this comment.
All reported issues were addressed across 36 files
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
c775f9e to
7ec0e54
Compare
7ec0e54 to
8d9c77a
Compare
8d9c77a to
3db9829
Compare
There was a problem hiding this comment.
All reported issues were addressed across 36 files
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
3db9829 to
c8889ab
Compare
c8889ab to
5da798e
Compare
There was a problem hiding this comment.
All reported issues were addressed across 37 files
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
5da798e to
7824c6b
Compare
7824c6b to
2782286
Compare
Resolves the conflicts with SpecLA (#606) and the packed concurrent prefill work (#595): - SSM_CONV op_params[0]: 1 stays the SpecLA heavy-light conv, the dflash fused conv step now uses 2; the CUDA dispatcher and supports_op handle both. - GDN raw-gate mode no longer uses src[8]/op_params[2] (compact-decode slot ids and the SpecLA marker): the loader builds one f32 [dt_bias | A] tensor per DeltaNet layer (TargetLayer::ssm_gate_ba, own small buffer) and ggml_gated_delta_net_set_raw_gates() attaches it as src[9] with op_params[10] = 1. - gated_delta_net.cu launchers carry both the active-slot arguments and the raw-gate parameters. - build_delta_net_block keeps main's token-axis segment structure; the stacked (z|qkv) and (beta|alpha) projections, the fused conv step, raw gates, single l2_norm over q|k and the head-broadcast shortcut apply on the plain single-sequence chain path only (ragged, compact-decode, SpecLA and chunked paths take main's materialized ops). - MMQ tiles: Q4_K keeps main's 128x64 (LUCEBOX_RDNA_MMQ_Y); IQ4_XS, Q5_K, Q6_K, Q8_0 and the ROCmFPX formats keep the 64x64 small tile. - Spec loop: DSpark Markov top-k stays available inside the non-conditional DDTree branch; SpecLA's conditional-draft path and draft-KV flag are preserved. Verified on lucebox8 (R9700): AR 34.6 tok/s, DFlash2 110/54/115 (code/prose/mixed), DSpark 48/32/40.
Current gain over
mainQwen3.6-27B Q4_K_M target, Q8_0 DFlash draft, DDTree budget 22, top-k 4,
tau=6, ten HumanEval-style prompts, and 128 generated tokens:mainSpecLA gain over current
main: +8.2%.Paper: https://arxiv.org/abs/2607.16673
CLI
The normal entry point is one flag:
--speclaenables speculative linear-attention verification when the loaded target and placement support it. SpecLA is the verification/state-management mode; it is not an alias for a particular proposal algorithm.For the Qwen3.5/Qwen3.6 dense path implemented in this PR, the runtime currently:
tau=6;This separation is intentional. A future Qwen3.8 DSpark implementation can provide candidates and parent topology behind the same
--speclaflag without changing the user-facing CLI. That DSpark adapter and its target-specific recurrence/factor capture are not part of this PR.Supported and permitted combinations
The path in this PR is supported for a monolithic Qwen3.5/Qwen3.6 dense target on one local device. It has been built and parity-tested on HIP.
The current Qwen adapter requires:
--draft DRAFT.gguf;--speclaenables automatically;Setup-dependent overrides remain available:
--specla--ddtree-budget N--ddtree-tau T--specla-top-k K--draft-swa NThe environment variables
DFLASH_SPECLA=1andDFLASH_SPECLA_TOPK=Kremain compatibility controls for non-CLI harnesses.DFLASH_SPECLA_CONDITIONAL_DRAFT=1andDFLASH_SPECLA_FUSED_COMMIT=0are advanced experiment/debug controls, not normal launch requirements.Rejected or unavailable combinations
--specla --no-fast-rollbackis rejected because SpecLA requires the rollback/state path.--specla-top-kwithout--speclais rejected.test_dflashharness rejects--specla --seq-verify; sequential verification cannot exercise the SpecLA tree path.--draft.--kvflash <tokens|auto>cannot use SpecLA factor migration. The server warns, reports SpecLA off, and falls back to ordinary DDTree verification.--ddtreemode remains independent.Paper mapping
The paper requires scored speculative candidates and parent topology, not DDTree specifically. A chain is a degenerate tree. DDTree is simply the proposal adapter connected for Qwen3.6 today; DSpark can be connected later if it supplies the required candidate/topology contract and the target has a compatible SpecLA recurrence and factor-capture implementation.