[Bugfix] Bound the grammar-compile thread pool and expose SGLANG_GRAMMAR_COMPILE_MAX_WORKERS - #32085
anencore94 wants to merge 1 commit into
Conversation
|
Caution The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased. |
|
Caution The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased. |
9a7b898 to
0475995
Compare
|
@hnyls2002 — small self-contained fix for a production incident: I've just rebased onto main — the earlier red |
…MAR_COMPILE_MAX_WORKERS BaseGrammarBackend creates its grammar-compilation pool as a bare ThreadPoolExecutor(), which defaults to min(32, os.cpu_count() + 4) workers. os.cpu_count() is not cgroup-aware, so inside a container with a CFS quota (e.g. a Kubernetes pod with cpu limit 6 on a 172-core host) the pool is sized for the host, not the quota. Since each compile can additionally spawn the backend's internal threads (xgrammar defaults to max_threads=8 per compile), a burst of distinct schemas can put dozens to hundreds of CPU-bound threads inside the scheduler process, sustain CFS throttling, and stall the decode loop of already-running requests. Cap the pool at min(cpu_count // 2, 8) and expose SGLANG_GRAMMAR_COMPILE_MAX_WORKERS as an operator override (0 = auto). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: Jaeyeon Kim <anencore94@gmail.com>
7187249 to
0b89cd2
Compare
|
Rebased onto the latest On the red checks: they're all @hnyls2002 @DarkSharpness @JustinTong0323 — recap of the fix: This is the same class of fix as vllm-project/vllm#49461, which is carrying the |
|
Following the merge process in MAINTAINER.md: this PR never got past step 2. No Merge Oncall was ever assigned (the assignee list is empty), and without step 3 the Step 4 says the author may ping other related Merge Oncalls when the assigned one is unresponsive, so per the Scheduler area: @merrymercy @hnyls2002 @cctry — could one of you assign an oncall and add |
Motivation
Fixes #32084
BaseGrammarBackendcreates its grammar-compilation pool as a bareThreadPoolExecutor(), which defaults tomin(32, os.cpu_count() + 4)workers.os.cpu_count()is not cgroup-aware, so inside a container with a CFS quota (e.g. a Kubernetes pod withcpulimit 6–12 on a 172-core GPU node) the pool is sized for the host, not the quota. Each compile can additionally spawn the grammar backend's internal threads (xgrammar defaults tomax_threads=8per compile call), so a burst of distinct guided-JSON schemas can put up to ~256 CPU-bound threads inside the scheduler process, sustain CFS throttling, and stall the decode loop of already-running requests.We measured this failure class in production on the vLLM side of our fleet (identical root cause, 6-core-limit pod on a 172-core host): CFS throttle ratio ≈ 1.00 sustained for minutes during guided-JSON bursts, inter-token latency collapsing 7–9 ms → 68–93 ms with the GPU nearly idle. Details: vllm-project/vllm#49460 (companion fix: vllm-project/vllm#49461).
Modifications
python/sglang/srt/constrained/base_grammar_backend.py: addget_grammar_compile_max_workers()— sizes the pool asmax(1, min(cpu_count // 2, 8)), withSGLANG_GRAMMAR_COMPILE_MAX_WORKERS(0 = auto) as an operator override — and use it forBaseGrammarBackend.executor.python/sglang/srt/environ.py: addSGLANG_GRAMMAR_COMPILE_MAX_WORKERS = EnvInt(0).test/registered/unit/constrained/test_base_grammar_backend.py: addTestGrammarCompileMaxWorkers— cap table across CPU counts (1 → 172), default-to-host-count path, env override, 0 = auto, ≥1 floor, and thatBaseGrammarBackend.executoris bounded.Behavior is unchanged on small hosts (≤16 cores: same or nearly same worker count as before); on many-core hosts the pool shrinks from 32 to 8, which also reduces the duplicate-compile fanout noted in #32084.
Accuracy Tests
Not applicable — no change to model outputs; only thread-pool sizing.
Speed Tests and Profiling
No change to the compile path itself; per-compile parallelism (xgrammar
max_threads=8) is untouched. On CFS-limited containers this strictly reduces oversubscription; on unlimited many-core hosts, peak concurrent compiles drop from 32 to 8 (override available viaSGLANG_GRAMMAR_COMPILE_MAX_WORKERS).Checklist
🤖 Generated with Claude Code
CI States
Latest PR Test (Base): ❌ Run #32624797750
Latest PR Test (Extra): ❌ Run #32624797604
Latest PR Test (AMD ROCm 7.2): ❌ Run #32624797871