Price a prefill call's 204 ms fixed cost - #307
Merged
Merged
Conversation
The serving page establishes that TTFT grows 407-422 ms a request with the
width of a wave, but not what that slope is made of. Three manipulations
separate it, all at one slot so nothing queues:
- holding the prompt at 3703 or 1242 tokens and cutting
--prefill-token-budget to force 1/2/4/8 calls, which gives 164-245 ms an
extra call at constant total tokens and a joint fit of
TTFT = 204.2 ms * n_calls + 577.4 us * tokens + 27.7
- nine one-call length points from 67 to 3703 tokens, whose intercept is
205.7 ms (190.7 without the 115-token point), slope 599.1 us
- the page's own pf128 row, re-read through its bimodal structure: two extra
calls a request move mean TTFT by 30.1x the per-call cost, so 6195.4 ms is
205.7 ms a call
So a 325-token prefill costs 411 ms and 204 of it is paid before the first
token-dependent FLOP. Removing the collectives outright does not touch it
(881.2 -> 885.2 ms server-side prefill with the IPC all-reduce no-opped), so
it is not the 276.8 ms the profiler attributes to tp_all_reduce.
That prices the engine's "merging prompts would buy ~1.06x" comment, which is
the same arithmetic at 2048 tokens where the fixed term is 15% of a call. At
the ladder's 322-token prompts it is 52%, and merging L16's wave into one
5162-row forward takes TTFT from 6640 ms to 3.3-3.4 s and prefill from 40.5 to
~80 TFLOP/s on four cards -- 1.9-2.0x, not 1.06x. The comment now scopes its
own number instead of quoting it unqualified.
scripts/run_serving_sweep.sh gains a `prefill` subcommand so both sweeps are
reproducible without the ad-hoc drivers they were run from.
Co-Authored-By: Claude Opus 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.
Summary
serving_throughput_scaling.mdestablishes that TTFT in the ladder grows407-422 ms per request of wave width, and names the cause —
batch_prefillrunsits requests one at a time. It never prices what a call costs, so the merge that
would fix it is quoted only as the
~1.06xin the engine's own comment.This measures the decomposition. A prefill call costs 204 ms before it costs
anything per token, and 577-599 us per token after that. At the ladder's
322-token prompts the fixed term is 52% of the call, so merging
L16's wave intoone 5162-row forward is worth 1.9-2.0x on TTFT and the same on prefill
TFLOP/s (40.5 -> ~80 on four cards), not 1.06x.
Implementation details
Three manipulations, all at one slot with
--request-rate infso nothing queuesand TTFT is the server's own prefill:
and cut
--prefill-token-budgetto force 1/2/4/8 calls. Each extra call is164-245 ms; the joint fit is
TTFT = 204.2 ms x n_calls + 577.4 us x tokens + 27.7.above the prompt, so every point is exactly one call: intercept 205.7 ms
(190.7 excluding the 115-token point), slope 599.1 us, residuals within
±81 ms. The real token counts are the engine's
prompt_tokens=, not theharness's nominal length.
pf128row, re-read. It adds two calls to each of 16requests for 6195.4 ms of mean TTFT. Under the bimodal structure the page
already established — one short first request, fifteen that wait for the whole
wave — a per-call cost
kmoves the mean byk x (32 x 15/16 + 2 x 1/16) = 30.1k, so 6195.4 ms is 205.7 ms a call.The negative control rules out the collective:
POCKET_ASCEND_IPC_ALLREDUCE_SKIP=1makes all 129 all-reduces a pass a no-op and moves the server's prefill for a
1242-token prompt from 881.2 to 885.2 ms. The 276.8 ms the profiler attributes to
tp_all_reduceis latency the ranks absorb, not serialized work.Two consequences recorded:
qwen_engine.cpp:5091now says the
~1.06xis specific to 2048-token prompts and points at the ~2xthe ladder's short prompts are worth. The old number was the right arithmetic
for the saturation sweep's question, so it is scoped rather than deleted.
segmented recurrent state in the 48 linear-attention layers and a block-diagonal
mask in the 16 full-attention layers. Without the mask a 5162-row forward
spends 16x on the dense attention matrix what sixteen 322-row forwards spend in
total.
scripts/run_serving_sweep.shgains aprefillsubcommand that reproduces bothsweeps; the four ladder rows the decomposition is checked against are
ladder'sL1/L4/L16/L32.Testing status
mkdocs build --strictpasses; the two new intra-page anchors resolve togenerated ids.
bash -n scripts/run_serving_sweep.shpasses, andprefillwas dry-run with astubbed
pointto confirm the 16 tags and their per-point--prefill-token-budget.--json-outrecords and the engine's ownprompt_tokens=, never from the console table.4fc72a1; the onlycpp_engine/diff across that range isthe bench's
+20phase-profile lines, and the re-run reproduces the page's ownL1intercept to 1% (511.7 ms against 517 ms).cards, so the whole record is TP4.
🤖 Generated with Claude Code