[olmoe] Engine dies on prefill > ~1024 tokens with default cache cap — reload storm saturates the eviction loop
Version: v1.10.1 · Engine: c/olmoe.c · Model: OLMoE-1B-7B int8 (5 shards, 7.41 GB container) · Gateway: coli serve (OpenAI-compatible API)
Summary
With the default implicit cache cap (implicit_cap=8 slots/layer for olmoe, family_registry → openai_server.py:cap_for_arch), any chat completion whose prompt exceeds ~1024 tokens (~4 000+ characters) kills the engine process mid-prefill. The gateway survives and returns HTTP 500 (or the client connection breaks). With --cap 64 (all 64 experts/layer resident), the exact same request completes normally — which both isolates the defect to the cache/eviction path and provides a workaround.
Reproduction (minimal)
# 1. Start the gateway with defaults (implicit cap 8 for olmoe)
coli serve --model <model-dir> # port 8000
# 2. Send a ~5 000-char (~1 250 token) user prompt
curl http://127.0.0.1:8000/v1/chat/completions \
-H 'Content-Type: application/json' \
-d '{"model":"olmoe-colibri",
"messages":[{"role":"user","content":"<~5000 chars of any text> … Answer in one sentence: what is the text about?"}],
"max_tokens":60, "stream":true}'
# Expected: engine process dies mid-prefill; gateway returns 500 / connection failure.
# 3. Same request with --cap 64: completes (TTFT ~133 s on an i5-7300HQ, then 4.5 tok/s decode).
Evidence — bisect on prompt length (same model, same machine)
| Prompt |
Outcome |
| ~4 000 chars / ~1 000 tokens |
completes (TTFT 172-183 s — the reload storm is already visible) |
| 6 000 chars |
fetch failed (engine dead, connection reset) |
| 6 789 chars |
HTTP 500 (engine dead, gateway reports) |
Threshold is stable at ~1024 prefill tokens; repeated runs alternate between the two client-visible failure modes.
Root cause hypothesis (documented upstream, not new)
chat_olmoe.sh — the engine's own reference script — already warns:
« This engine doesn't dedupe repeated expert picks within a single prefill batch,
so a too-small cache causes constant reload storms; caching every expert
sidesteps that entirely. »
With cap 8, a long prefill cycles far more distinct experts than 8 slots/layer can hold. The eviction loop's last-resort branch (« every slot in-flight ») then saturates and the engine dies. Our measurements corroborate the storm mechanism directly:
- cap 8, short prompt: decode ~2.0 tok/s, warm TTFT ~9 s — the cache is too small for the working set even before the crash zone.
- cap 64, same session: decode 3.9-4.5 tok/s, warm TTFT 1.9-2.5 s, and the crash zone prompt completes (1 385-token prefill, TTFT ~133-153 s across two sessions).
- Boundary, from the full matrix: cap 8 dies on the long leg in 4/4 cells; cap 32 survives it in 4/4 cells but at ~1.9 tok/s decode and ~237 s prefill — the defect sits between cap 8 and cap 32, and the useful performance sits at cap 64.
(Method note: the serve-mode turn breakdown reports expert_disk_s = 0.0 uniformly — including on the slow cap-32 cells — so that field is not usable as reload-storm evidence in serve mode; the crash boundary and the performance cliff above carry the evidence.)
Full 12-point matrix (cap 8/32/64 × PILOT 0/1 × CTX 2048/4096) attached in the measurement report (#1441) — the crash reproduces on every cap-8 cell (4/4) and on no other cell; cap 32 survives the same prompt but at half the decode rate (~1.9 tok/s vs 3.9 at cap 64) and double the prefill time (~237 s vs ~153 s), which places the defect boundary between cap 8 and cap 32 and the performance cliff between 32 and 64 (the all-experts-resident threshold).
Environment
- CPU i5-7300HQ (4c/4t, AVX2), 16 GB RAM, CPU-only, Windows x64.
colibri v1.10.1, OLMoE-1B-7B int8, dense 953 MB + 64 experts/layer × 16 layers (6.46 GB experts, 6.31 MB/expert), KV fp32.
- Freshness at filing time: upstream current release is v1.10.2 —
c/olmoe.c is byte-identical between the v1.10.1 and v1.10.2 tags (direct diff) — the defect path is unchanged in the current release.
Suggested directions (happy to prototype any of them)
- Dedupe expert picks within a single prefill batch (the storm's fuel) — the fix
chat_olmoe.sh implies.
- Bound the in-flight set / add backpressure instead of the last-resort « every slot in-flight » eviction, so a saturated cache degrades latency rather than killing the process.
- Document the interaction: long prefills × small caps = crash zone, with
--cap 64 (or a cap sized to experts/layer) as the workaround.
(3) can ship today; (1) is the real fix; (2) is the defensive layer.
Conçu dans Électra et piloté par Super Z GLM 5.3 — mesure protocole C6, journal reproductible.
[olmoe] Engine dies on prefill > ~1024 tokens with default cache cap — reload storm saturates the eviction loop
Version: v1.10.1 · Engine:
c/olmoe.c· Model: OLMoE-1B-7B int8 (5 shards, 7.41 GB container) · Gateway:coli serve(OpenAI-compatible API)Summary
With the default implicit cache cap (
implicit_cap=8slots/layer for olmoe,family_registry→openai_server.py:cap_for_arch), any chat completion whose prompt exceeds ~1024 tokens (~4 000+ characters) kills the engine process mid-prefill. The gateway survives and returns HTTP 500 (or the client connection breaks). With--cap 64(all 64 experts/layer resident), the exact same request completes normally — which both isolates the defect to the cache/eviction path and provides a workaround.Reproduction (minimal)
Evidence — bisect on prompt length (same model, same machine)
Threshold is stable at ~1024 prefill tokens; repeated runs alternate between the two client-visible failure modes.
Root cause hypothesis (documented upstream, not new)
chat_olmoe.sh— the engine's own reference script — already warns:With cap 8, a long prefill cycles far more distinct experts than 8 slots/layer can hold. The eviction loop's last-resort branch (« every slot in-flight ») then saturates and the engine dies. Our measurements corroborate the storm mechanism directly:
(Method note: the serve-mode turn breakdown reports
expert_disk_s = 0.0uniformly — including on the slow cap-32 cells — so that field is not usable as reload-storm evidence in serve mode; the crash boundary and the performance cliff above carry the evidence.)Full 12-point matrix (cap 8/32/64 × PILOT 0/1 × CTX 2048/4096) attached in the measurement report (#1441) — the crash reproduces on every cap-8 cell (4/4) and on no other cell; cap 32 survives the same prompt but at half the decode rate (~1.9 tok/s vs 3.9 at cap 64) and double the prefill time (~237 s vs ~153 s), which places the defect boundary between cap 8 and cap 32 and the performance cliff between 32 and 64 (the all-experts-resident threshold).
Environment
colibri v1.10.1, OLMoE-1B-7B int8, dense 953 MB + 64 experts/layer × 16 layers (6.46 GB experts, 6.31 MB/expert), KV fp32.c/olmoe.cis byte-identical between the v1.10.1 and v1.10.2 tags (direct diff) — the defect path is unchanged in the current release.Suggested directions (happy to prototype any of them)
chat_olmoe.shimplies.--cap 64(or a cap sized toexperts/layer) as the workaround.(3) can ship today; (1) is the real fix; (2) is the defensive layer.
Conçu dans Électra et piloté par Super Z GLM 5.3 — mesure protocole C6, journal reproductible.