Skip to content

perf(qwen35): batch draft projections across lanes for concurrency - #651

Open
Graffioh wants to merge 12 commits into
Luce-Org:qwen38-dsparkfrom
Graffioh:codex/draft-projection-batching
Open

perf(qwen35): batch draft projections across lanes for concurrency#651
Graffioh wants to merge 12 commits into
Luce-Org:qwen38-dsparkfrom
Graffioh:codex/draft-projection-batching

Conversation

@Graffioh

@Graffioh Graffioh commented Aug 23, 2026

Copy link
Copy Markdown
Contributor

Stack

This PR contains the exact current #642 history through 308f630f, followed by two separate commits:

  1. bb65ab93perf(qwen35): batch draft projections across lanes for concurrency
  2. f1c85e05refactor(qwen35): rename GDN journal to replay log

The projection commit is patch-equivalent to the original 98896bf8; its object ID changed only because the stack moved onto the current #625 and #642 heads. The replay-log rename stays separate, so the performance change is not folded together with unrelated cleanup.

Summary

  • Batch shared draft dense projections across active lanes.
  • Keep convolution, cache updates, RoPE, masks, positions, attention, and draft KV state lane-local.
  • Use one builder for C1 through C6, without a runtime switch or duplicate execution path.
  • Include the backend in the cached graph replay key.
  • Inherit qwen35: batch DFlash2 decode for Qwen3.8-27B concurrency #642's metadata-preserving DFlash2 sliding-window handling. The tested Qwen3.8 draft reports SWA layers: 5/5 (window=2048).

The previous path ran each lane's dense draft backbone in a separate graph. The packed path combines projection columns and removes repeated MMQ launches without sharing lane state.

Projection A/B

This matched A/B isolates the unchanged #651 projection patch against its #642 parent. Warm medians exclude the first speculative round; each run generated a fixed 64-token output.

GPU C Draft compute, ms Complete round, ms
R9700 1 5.864 -> 5.864 (-0.0%) 62.161 -> 62.107 (-0.1%)
R9700 2 11.622 -> 8.498 (-26.9%) 74.153 -> 70.951 (-4.3%)
R9700 3 17.424 -> 11.392 (-34.6%) 96.811 -> 90.871 (-6.1%)
Strix Halo 1 12.129 -> 12.120 (-0.1%) 137.892 -> 138.107 (+0.2%)
Strix Halo 2 24.039 -> 15.341 (-36.2%) 166.877 -> 158.065 (-5.3%)
Strix Halo 3 36.378 -> 19.665 (-45.9%) 224.446 -> 209.150 (-6.8%)

C1 is neutral. C2 and C3 reduce complete-round latency by 4.3% to 6.8%. The R9700 C3 rocprof trace reduced MMQ launches from 336 to 196 (-41.7%) and MMQ device time from 11.938 ms to 6.103 ms (-48.9%).

Verification

The refreshed Qwen3.8 concurrency matrix is reported on #642. #654 is stacked on this PR and adds sampled concurrent speculation.

@Graffioh Graffioh changed the title perf(qwen35): batch draft projections across lanes perf(qwen35): batch draft projections across lanes for concurrency Aug 23, 2026
@Graffioh
Graffioh force-pushed the codex/draft-projection-batching branch from c136c86 to 98896bf Compare August 24, 2026 06:36
@Graffioh
Graffioh force-pushed the codex/draft-projection-batching branch 2 times, most recently from 9608985 to fae03e7 Compare August 24, 2026 09:17
@Graffioh
Graffioh force-pushed the codex/draft-projection-batching branch 3 times, most recently from f1c85e0 to 21b3aef Compare August 24, 2026 13:28
Restore the paged-attention C ABI through a separate tree entry point. Reject unsupported GDN variants, initialize root-only chain trees, and size draft metadata from graph capacity.
Keep GDN journals inside the result buffer, restore the 10-source tensor layout, validate every tree destination before mutation, and allow selector widths that use the CPU top-k fallback.
Add fixed-width DFlash2 concurrent decoding for Qwen3.8 and batch the shared dense draft projections across active lanes.

Keep convolution, cache updates, RoPE, masks, and attention lane-local. Preserve transactional state promotion and fixed-chain validation through C6.
@Graffioh
Graffioh force-pushed the codex/draft-projection-batching branch from 21b3aef to e272492 Compare August 24, 2026 13:33
@Graffioh
Graffioh marked this pull request as ready for review August 24, 2026 17:37

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 64 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/test/test_batched_gdn.cpp">

<violation number="1" location="server/test/test_batched_gdn.cpp:73">
P2: In test_cpu_gdn_support_matrix the active op is built with n_tokens=2 yet active_slots has only 1 element. GGML construction asserts the active-slot ids tensor matches n_tokens*n_seqs (as run_gdn does with n_seqs for n_tokens==1, and as the sibling tree/tree_persist helpers assert), so on the --cpu path this GGML_ASSERT aborts the test instead of printing the support-matrix result. Size active_slots to n_tokens.</violation>
</file>

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread server/src/common/dflash_draft_kv.h
Comment thread server/src/common/dflash2_batch.cpp
Comment thread server/src/qwen35/concurrency/qwen35_seq_engine.cpp
Comment thread server/deps/llama.cpp/ggml/src/ggml-cuda/gdn-replay-log.cu
Comment thread server/src/common/dflash2_head.cpp
Comment thread server/deps/llama.cpp/ggml/include/ggml.h Outdated
Comment thread server/test/test_paged_kv_pool.cpp
Comment thread server/test/test_draft_topk_cuda.cpp
Comment thread server/test/test_gdn_replay_log.cpp
Comment thread server/test/test_draft_swa_multilane.cpp
Validate singleton selector vocabularies and token IDs before codebook gathers. Reject unsupported GDN output layouts on Vulkan, and use overflow-safe ceil division in paged attention.
Preserve paged-KV allocation order across rollback and destroy draft graphs before park frees their weights.

Reject invalid GDN replay layouts and malformed SWA metadata. Exercise both grouped and scalar GDN dispatch paths.
# Conflicts:
#	server/src/draft/draft_gguf_loader.cpp
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant