Repository navigation
Add a sweep_next profile that finds the peak rate with a ramp - #1295
theminjunchoi wants to merge 7 commits into
Conversation
The ramp strategy starts at a given rate and doubles it every interval, with no upper bound, so finding a server's peak doesn't need a guess at its capacity up front. The saturation constraint decides when to stop it. While the server keeps up, completions over a window match what was sent one latency earlier. When they fall more than 25% short, it stops sending, lets the requests in flight finish for three latencies, and records the highest completion rate seen over a window. It stops judging once another constraint ends queuing, since the requests that one cancels never complete. Signed-off-by: MinJun Choi <mj04300017@gmail.com>
Add a peak_detection option to sweep. The default keeps the fixed concurrency throughput step. With "ramp", the sweep runs a ramp sized from the synchronous step instead: it starts at the synchronous rate, doubles every four synchronous latencies (at least two seconds), and stops through the saturation constraint. The peak becomes the top of the range and is recorded as a profile conclusion. If something else, like --max-seconds, ends the ramp before the server saturates, the peak is only a lower bound, so the console warns about it. The default concurrency cap of 512 only applies to a ramp when set explicitly. Signed-off-by: MinJun Choi <mj04300017@gmail.com>
Check the ramp's send schedule and doubling, and replay a ramp against a server with fixed capacity: nothing triggers while it keeps up, saturation is detected past capacity, the peak lands within 10% of it, and requests cancelled by another constraint don't count as saturation. Cover sweep sizing, the peak fallbacks, the concurrency cap and the console summary. Assisted-by: Claude Code claude-opus-5-5 Signed-off-by: MinJun Choi <mj04300017@gmail.com>
Run a ramp sweep against a mock server with a fixed number of slots: the ramp saturates it, its peak lands near capacity and sizes the constant step, and a short --max-seconds is reported as not saturated. Assisted-by: Claude Code claude-opus-5-5 Signed-off-by: MinJun Choi <mj04300017@gmail.com>
0252ba5 to
28e2941
Compare
|
Just a quick update. Still working through our backlog of PRs so have not had too much time to evaluate this. Just looking through the code it seems good; though I was kinda thinking we completely remove the throughput mode assuming this works out. Maybe it is better to leave it for now until we are sure this is an improvement across all use-cases. Or alternatively maybe copy the old sweep and rename this to
When I find some time I'll try to answer those questions. Though if you do split this off from the old sweep I would be less concerned about getting these answered before merge. |
Keep sweep exactly as it was and put the ramp version in a new sweep_next profile instead of behind a peak_detection option. sweep_next runs the synchronous step, then the ramp, then the interpolated async steps, and has no concurrency cap unless one is set. Signed-off-by: MinJun Choi <mj04300017@gmail.com>
Restore the original sweep tests, move the ramp cases to a sweep_next test file, and run the e2e ramp sweep with kind=sweep_next. Assisted-by: Claude Code claude-opus-5-5 Signed-off-by: MinJun Choi <mj04300017@gmail.com>
Signed-off-by: MinJun Choi <mj04300017@gmail.com>
|
@sjmonson Thanks! I split it off as |
Summary
Sweep finds its top rate with a throughput step fixed at 512 concurrent requests. That's off in both directions: a small server queues the requests and reports inflated latency, and a large one tops out below its capacity. In my runs that meant a TTFT p95 of ~27s on a small server, and ~128 req/s against a real ~176 on a large one.
This adds a
sweep_nextprofile, following the discussion in #1248 and #564. It runs like sweep, but instead of the throughput step it starts a ramp at the synchronous rate and doubles it until the server falls behind, and the highest completion rate it reached becomes the top of the range. On the llm-d simulator and the mock server it landed within ~7% of capacity. As suggested in the review, sweep itself is untouched, so the two can be compared side by side before deciding whether to replace it.Details
AsyncRampStrategy: the rate doubles everydoubling_interval, with no upper bound.RampSaturationConstraint: stops sending once completions fall more than 25% short of what was sent one latency earlier, keeps measuring for three latencies, and reports the peak completion rate.sweep_nextsizes the ramp from the synchronous step (doubling every four latencies, at least 2s) and records the peak as asweep_rampconclusion. It has no concurrency cap unless you setmax_concurrency.--max-secondsends the ramp before the server saturates, the console warns that the peak is only a lower bound.benchmark.md.I didn't use over-saturation detection as I'd planned in #564. On a server that slows down gradually, TTFT doubles well before saturation, so it stopped the ramp at ~60% of capacity.
The tradeoff is time. The ramp needs about log2(capacity × latency) doublings, so a server holding ~1000 requests at ~2s each took ~90s. Happy to expose the constants or change the defaults if you'd like.
This is stacked on #1262, since the e2e tests need the mock server to actually saturate. I'll close #1248 in favor of this one.
Test Plan
lint-check,type-check,test-unit(3,692 passed),test-integration(34) andtest-e2e(16) pass on Python 3.10. After the split,test-unit(3,799 passed),type-checkand the sweep_next e2e tests pass again on Python 3.12.sweep_nextrun saturates it and the constant step uses its peak, and a 2s step limit is reported as not saturated.Related Issues
Use of AI
git log
commit 04d8836
Author: MinJun Choi mj04300017@gmail.com
Date: Mon Oct 12 15:57:02 2026 +0900
commit 853ef63
Author: MinJun Choi mj04300017@gmail.com
Date: Mon Oct 12 15:57:03 2026 +0900
commit b64ca68
Author: MinJun Choi mj04300017@gmail.com
Date: Mon Oct 12 15:57:03 2026 +0900
commit 28e2941
Author: MinJun Choi mj04300017@gmail.com
Date: Mon Oct 12 15:57:03 2026 +0900
commit 101f3dc
Author: MinJun Choi mj04300017@gmail.com
Date: Tue Oct 20 09:55:22 2026 +0900
commit 115a3f1
Author: MinJun Choi mj04300017@gmail.com
Date: Tue Oct 20 09:55:22 2026 +0900
commit 1e64de6
Author: MinJun Choi mj04300017@gmail.com
Date: Tue Oct 20 09:55:22 2026 +0900
Assisted-by: Claude Code claude-opus-5-5
Signed-off-by: MinJun Choi mj04300017@gmail.com