-
Notifications
You must be signed in to change notification settings - Fork 267
perf(qwen38): various DFlash2 optimizations concurrency C1-C5 #659
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
Graffioh
wants to merge
28
commits into
Luce-Org:main
Choose a base branch
from
Graffioh:codex/qwen38-gdn-replay-tile
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
28 commits
Select commit
Hold shift + click to select a range
58ca750
concurrency: add ordered burst and staged slot commits
Graffioh 24be6f5
concurrency: add fixed Qwen DFlash2 chain path
Graffioh 3d2996a
fix(concurrency): correct speculative backend contracts
Graffioh 3ce1b73
fix(concurrency): make tree commits fail closed
Graffioh f798e1c
fix(concurrency): stabilize DFlash2 promotion
Graffioh 2c2673a
fix(qwen35): stabilize tree verification through C6
Graffioh e23f5a5
fix(qwen35): preserve DFlash2 sliding-window pattern
Graffioh ed30620
fix: guard selector and GPU backend edge cases
Graffioh 514ed99
fix(concurrency): harden speculative state boundaries
Graffioh a6c8305
fix(concurrency): harden speculative validation
Graffioh 1777cff
test(paged-attn): align cyclic tree scratch
Graffioh a298272
ci: run GDN transaction preflight on NVIDIA
Graffioh f45f874
fix(dflash2): report invalid batched seeds
Graffioh 099d7a4
refactor(qwen35): simplify concurrent fixed-chain flow
Graffioh 39bc748
fix(concurrency): tighten GDN backend cleanup contracts
Graffioh b7589bb
perf(qwen35): batch draft projections across lanes for concurrency
Graffioh 2a91f93
refactor(qwen35): rename GDN journal to replay log
Graffioh 003b06a
refactor(qwen35): skip standalone graphs for batched draft state
Graffioh 4d89dcd
ci: build renamed GDN replay test
Graffioh 6b21192
ci: run renamed GDN replay preflight
Graffioh dcd2fe9
perf(draft): batch append projections across lanes
Graffioh d5770a4
chore(draft): trim append API comments
Graffioh 70cdc88
perf(draft): pack dynamic-conv projections across lanes
Graffioh 498ad21
perf(gdn): tile replay transition loads
Graffioh dbe778e
perf(qwen35): skip redundant active GDN head repeats
Graffioh f108bbe
perf(qwen35): use exact C5 draft shape
Graffioh 8ab1b9b
perf(qwen35): retain stable paged target graphs
Graffioh 62d051e
docs: mark PR 651 performance handoff status
Graffioh File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
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
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,78 @@ | ||
| # PR 651 draft batching performance follow-ups | ||
|
|
||
| > Historical planning note: PR 659 implements the batched append projections and | ||
| > packed dynamic-convolution coefficient projections described below. Keeping draft | ||
| > hidden states on the device was evaluated but is not part of PR 659; the existing | ||
| > host handoff remains intentional until a separately measured change replaces it. | ||
|
|
||
| ## Scope | ||
|
|
||
| PR 651 packs the main drafter projections across concurrent lanes. It keeps each lane's cache writes, RoPE, masks, and attention separate. | ||
|
|
||
| This note covers three follow-up optimizations that do not belong in the ownership cleanup: | ||
|
|
||
| - Batch the append projections. | ||
| - Pack the dynamic-convolution coefficient projections. | ||
| - Keep draft hidden states on the device through chain selection. | ||
|
|
||
| Treat each item as a measured change. Do not combine all three into one patch. | ||
|
|
||
| ## Keep these invariants | ||
|
|
||
| - Keep `build_draft_kv_steps()` as the shared C1-C6 implementation. | ||
| - Preserve lane-local positions, masks, cache writes, RoPE, attention, and dynamic-convolution history. | ||
| - Rebuild a cached graph when the backend or the ordered lane-state pointers change. | ||
| - Keep C1 output equivalent to the existing single-lane graph. | ||
| - Keep dummy lanes after real lanes, and discard dummy proposals. | ||
|
|
||
| ## Batch the append projections | ||
|
|
||
| `draft_kv_batch_build()` currently calls `build_draft_kv_append()` once per lane. Each call runs `draft_fuse_features()`, then the per-layer `wk` and `wv` projections. | ||
|
|
||
| Pack every lane's `ap_feat` columns before those shared-weight matrix multiplications. Split the projected columns before RoPE and `ggml_set_rows()`, because positions, destination rows, and caches remain lane-local. | ||
|
|
||
| The packed append path must preserve the fixed `a_step` width. Padded append rows must still write only to each lane's trash slot. | ||
|
|
||
| Suggested shape: | ||
|
|
||
| ```cpp | ||
| bool build_draft_kv_appends( | ||
| ggml_context * ctx, | ||
| ggml_cgraph * gf, | ||
| const DraftWeights & weights, | ||
| const std::vector<DraftKvAppendLane> & lanes); | ||
| ``` | ||
|
|
||
| Pass one lane from the normal graph and C1-C6 lanes from the batched graph. Delete the old singular builder after migrating both callers. | ||
|
|
||
| Prove the change with the existing multilane output comparison. Add cases with zero, partial, and full append counts so padding and trash-slot writes are covered. Measure draft compute separately at C1, C2, C3, C5, and C6. | ||
|
|
||
| ## Pack dynamic-convolution coefficient projections | ||
|
|
||
| `build_draft_kv_steps()` calls `draft_dyn_conv_kernel()` once per lane for both attention and MLP. The function projects normalized hidden columns with shared weights. The temporal convolution in `draft_dyn_conv_apply()` is lane-local and must remain separate. | ||
|
|
||
| Pack the normalized columns before the coefficient projection. Slice the projected coefficients back into lanes, then call `draft_dyn_conv_apply()` per lane. | ||
|
|
||
| Do not pack the convolution history or apply step. Adjacent packed columns belong to different requests and must not influence each other. | ||
|
|
||
| Verify exact lane isolation with distinct inputs and histories. Run the existing single-lane-versus-packed comparison with dynamic convolution enabled. Record kernel count and draft compute time before and after the change. | ||
|
|
||
| ## Keep draft hidden states on the device | ||
|
|
||
| The current boundary copies every lane's draft hidden block to the host in `draft_kv_batch_compute()`. `Qwen35SeqEngine::prepare_chain_drafts()` converts the host vectors to pointers. `dflash2_select_chains_batched()` then packs the candidates and uploads them to both the projection graph and the selector graph. | ||
|
|
||
| Replace that round trip with a device-resident contract. The batch graph should expose a packed hidden tensor or stable per-lane tensor views. The batched selector should accept those device tensors on the same backend. | ||
|
|
||
| Keep only token IDs, top-K scores, and final proposals as host results. Do not expose an unowned device pointer whose lifetime is shorter than either consumer graph. | ||
|
|
||
| This change crosses the draft and selector APIs, so ship it separately from append or dynamic-convolution packing. It also needs an explicit fallback when the draft and selector backends differ. | ||
|
|
||
| Verification must compare complete proposals, not only projected hidden values. Cover C1-C6, reordered active slots, bucket padding, selector-graph reuse, and graph rebuilds. Measure transfer bytes, synchronization count, selector time, and complete-round latency. | ||
|
|
||
| ## Suggested order | ||
|
|
||
| 1. Batch append projections. This extends the packing pattern already introduced by PR 651. | ||
| 2. Pack dynamic-convolution coefficient projections. This is local to `build_draft_kv_steps()`. | ||
| 3. Remove the host hidden-state handoff in its own PR. This changes ownership across the draft and selector graphs. | ||
|
|
||
| For every step, retain the previous implementation long enough to run an A/B output comparison. Delete it before merging the step. | ||
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
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
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
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
Oops, something went wrong.
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.
Uh oh!
There was an error while loading. Please reload this page.