Repository navigation
[Engine] STRATA_PREFILL_CPU_SHARE_BATCH=1 (opt-in): the prompt's CPU share with --batch, for a read while no slot decodes; short reads -21% to -31% - #3382
Open
Vop3p wants to merge 1 commit into
Conversation
…ath the CPU pool beside batch slots, for a read with no slot decoding The share was off whenever --batch was set (share_pool = batch <= 0). With the variable set the pool goes to the prompt path as without batch slots, and before each read the serve loop sets Prefill::set_share_blocked from the slots: a read with a slot decoding takes no share (the slots' windows use the pool), one with none does. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
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.
Problem and result
The prompt path's CPU share (
STRATA_PREFILL_CPU_SHARE) is off whenever--batchis set: generate.cpp setsshare_pool = o.batch <= 0 && !o.no_pool, so with"parallel": 2the variable has no effect. The server runs with batch slots for concurrency, so a short read there always waits on the GPU alone: below the full-streaming chunk size (stream_all_min, here 2048) a chunk copies only its routed experts over PCIe, and on this machine that wait is about half of a 1-2K-token read.With
STRATA_PREFILL_CPU_SHARE_BATCH=1the pool is handed to the prompt path as it is without batch slots, and before each read the serve loop checks the slots: a read while any slot is decoding takes no share (the slots' verify windows use the pool), a read with none does. The existing CPU-share rules then decide as before (which chunks, how many experts).Result on 2x RX 6900 XT (below), 10 interleaved cold-start pairs: real-text reads under 2,048 tokens -28.8% (median), a 1,733-token one -20.9%, conversation continuations adding 455/781 tokens -30.7%, a 34K read -2.3% (its last chunk, 1,378 tokens); reads of 2,048 tokens and more unchanged. Without the variable the default path is byte-identical.
Related discussion
None found. I could not find a stated reason for
batch <= 0in the code or history; this keeps it as the default and only adds the opt-in.Approach
share_pool = (o.batch <= 0 || share_batch) && !o.no_pool, with one line at load when the variable applies; ashare_gate()before each read (inread_part's run and before the concurrent reader starts) callsPrefill::set_share_blocked(busy > 0)from the slots'activeflags, and prints the decision for the first 4 reads.set_share_blocked()sets an atomic that the chunk's existing pool-hold test also checks (!g_share_blocked).STRATA_PREFILL_CPU_SHARE=autoor1; on a layer split it is not on by default).Validation
Environment: 2x RX 6900 XT (gfx1030, 16 GB, PCIe 4.0 x8 each), Ryzen 5 5600X (6 cores), 128 GB DDR4-3200, Ubuntu 26.04 (kernel 7.0.0), ROCm 10.0.0. Revision: main e88ee39 (v0.2.0-beta + 12 commits) and this branch on it. Built with setup.py's HIP options (
-DSTRATA_PREFILL_MMQ=ON -DSTRATA_Q6K_EXPERTS=ON -DSTRATA_MMQ_KQUANTS=ON, gfx1030, the pinned ggml, Release). Model: Qwen3.8-Flash-Next GSQ-RCO IQ3_S, layer split over both cards.Passed:
Default path byte-identical: deterministic config (
parallel1, no pipeline windows,STRATA_PREFILL_CPU_SHARE=0,STRATA_LOGPOStop-256 log-probabilities), 8 chats of real text, 4,067 scored positions: main and this branch without the variablecmpidentical.Speed:
parallel2 (--batch 2),--pipeline-windows 2 --batch-mtp,STRATA_PREFILL_CPU_SHARE=auto,STRATA_PREFILL_STREAM_MIN=2048,STRATA_HC_PERSIST=1,STRATA_HIP_PROMPT_F16=1,STRATA_SH_STREAM=1, a rocBLAS table viaSTRATA_ROCBLAS_TUNING. The same binary with and without the variable, 20 cold starts alternating A B A B; each arm sends the same 33 requests one after another (so no slot is decoding during a read): 27 single real-text prompts of 430-3,521 tokens (English prose, Chinese prose, C++), then a 34K-token conversation and 5 continuations of it adding 455-3,168 tokens.prompt_msfrom /metrics. Median over the 10 pairs of each group's mean change:e.g. a 430-token Chinese prompt 1,722 -> 1,146 ms, a 455-token continuation 1,722 -> 1,168 ms. The
=1arms printedCPU share for this read: on (0 slot(s) decoding), the others no such line; 0 stalls.ctest(STRATA_BUILD_TESTS=ON; the engine binary is the same one, sha256 unchanged): 137 tests, 131 passed. The 6 failures are the same 6 on main e88ee39 built the same way:ple_parity(needs a Q2_0 GGUF this machine does not have),hip_prefill_mmq_parity(SEGFAULT on main too),native_hadamard_test,tq_cpu_parity,tq_cpu_parity_avx2("this ggml has no trellis types"),isa_guard_check(tq_rows_avx512not listed). The branch adds no test: the change is a scheduling condition; item 2 checks it end to end (the per-read confirmation line).CUDA compile only (no NVIDIA GPU here): CUDA 13.2.2 (nvcc 13.2.86) with GCC 15.2,
-DSTRATA_ENABLE_CUDA=ON -DSTRATA_Q6K_EXPERTS=ON -DSTRATA_MMQ_KQUANTS=ON -DCMAKE_CUDA_ARCHITECTURES=86: the engine builds; the one warning in generate.cpp (line 11576, an unused variable) is there on main too, none from the changed lines.Failed: none observed.
Not run:
Prefill::set_share_blockedis defined in it, so no stub is needed - not verified by a Mac build), a single-GPU setup, Windows, other GPUs.Limits
batch <= 0condition, the CPU-share rules themselves are unchanged.Developed with an AI coding assistant; every number above was measured on the machine described here.
🤖 Generated with Claude Code