Repository navigation
feat(qwen4exp): 262K context for four requests in split mode, KV of some layers on the Strix - #833
Merged
Merged
Conversation
ggml_backend_cuda_buffer_cpy_tensor queued its peer copy on the per-thread stream of whichever device was current. On ROCm a copy from an R9700 to a Strix Halo iGPU queued on the destination's stream completes without writing, so the scheduler's copies of graph inputs to the other device (row indices, positions, masks) arrived as zeros. It now sets the source device first, as ggml_backend_cuda_cpy_tensor_async queues its copy on the source's stream. Split serving never sent a graph input to the expert device until the next change, which runs some attention layers there. test_cuda_copy_batch gains cross_device_tensor_copy (skipped below two devices). On an R9700 + Strix Halo it reads 0 0 0 0 without the fix and 19 20 21 22 with it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… when the R9700 is full `--max-ctx auto` lowered the context once the R9700 could not hold every slot's cache beside the dense weights: four requests at once got 131,072 tokens. A miss now first moves the last full-attention layers' K/V and indexer rows to the expert device, as few layers as cover the shortfall while that device holds them, and runs those layers' attention there (input projections through the output projection). The context shrinks only once no more layers can move. - Qwen4ExpCache::remote_layers: those rows live in a second buffer on the expert device; snapshots save and restore them with the rest. - move_qwen4exp_attention moves the layers' attention and indexer weights. - Qwen4ExpLayerBuilder::on_cache_device pins the nodes a layer's attention adds to the expert device (single-sequence, verify, pipelined prompt and multi-slot builders); qwen4exp_pin_split places them. - The chunk plan counts the rows on the target only and reports one layer's rows across slots (Qwen4ExpChunkPlan::layer_bytes). - The QSA prefix bootstrap pools each layer on the device holding its rows. R9700 + Strix Halo, Manage's split launcher, four slots: 262,144 tokens with 7 of 12 layers moved, 3.9 GiB left on the R9700. Outputs repeat run to run and match alone and together (4 of 4); a resent 16K prompt prefills in 0.25 s instead of 11.0 s with the same reply; three facts hidden in a 158,927-token prompt are all recalled; a 158,848-token prompt completes beside three short requests. A request alone decodes at 45.9 tok/s and four together at 68.6, against 59.3 and 78.3 at 131,072 tokens with every row on the R9700. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
davide221
commented
Oct 9, 2026
davide221
left a comment
Contributor
Author
There was a problem hiding this comment.
Code review
No issues found. Checked for bugs and logic errors in the changed code.
Reviewed cb6116c6 · 1 candidate issue checked, kept at ≥70% confidence · add the code-review label to review again
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
In split mode, Qwen3.8-Flash-Next now keeps its full 262,144-token context with four requests at once. When the R9700 runs out of memory, some attention layers keep their KV cache on the Strix Halo instead of the server cutting the context. Before this,
--max-ctx autostopped at 131,072 tokens for four slots.Changes
fix(ggml-cuda): copy between two devices on the source's stream.
ggml_backend_cuda_buffer_cpy_tensorqueued its peer copy on the per-thread stream of whichever device was current. On ROCm, a copy from the R9700 to the Strix Halo iGPU queued on the destination's stream completes without writing anything.ggml_backend_cuda_cpy_tensor_asyncalready does.test_cuda_copy_batchgainscross_device_tensor_copy, which needs two GPUs and skips otherwise. On an R9700 + Strix Halo it reads0 0 0 0without the fix and19 20 21 22with it.feat(qwen4exp): attention layers' KV on the Strix when the R9700 is full.
Qwen4ExpCache::remote_layerskeeps those rows in a second buffer on the expert device. Prefix snapshots save and restore them with the rest.move_qwen4exp_attentionmoves those layers' attention and indexer weights.Qwen4ExpLayerBuilder::on_cache_devicepins the nodes a moved layer's attention adds. It covers the single-sequence, verify, pipelined-prompt and multi-slot builders.layer_bytes), so the fit knows how many layers to move.docs/QWEN4EXP.mdand the profile description cover it.Measured
Setup: R9700 + Strix Halo (192 GB), UD-Q4_K_XL, Manage's split launcher, four slots, adaptive MTP, greedy.
At 262,144 tokens:
The two layouts give the same reply on 2 of 4 prompts. The other 2 diverge at a near tie, one at the first token, because those layers' attention runs on a different GPU. Both sets of replies are coherent.
The context costs speed: about 23% for a request alone and 12% for four together, from the extra GPU-to-GPU hops of the moved layers.
Tests
test_server_unittest_cuda_copy_batchtest_qwen4exp_prefix_cachetest_qwen4exp_seq_engine(exact distinct slots)Built for gfx1151 + gfx1201.
🤖 Generated with Claude Code