ProprietaryLegal's picture
PLI Labs public snapshot 2026-10-28 (history squashed)
1e251f3
|
Raw History Blame Contribute Delete
6.22 kB

Startup warm-up (OPS1, reviewed patch; not deployed)

The old helper requested 32 tokens but did not require them. MEASURED: /opt/dsv41/campaigns/DSV41-OFFLOAD/K1-production/start.log records 5.629 s, 5,041 prompt tokens and 1 completion token. Its raw completion request has effective explicit max=32, default min=0, ignore_eos=false, no explicit stop. The installed completion protocol merges generation-config stop IDs. EOS or a default stop is a plausible explanation, not a confirmed cause: the old helper discarded finish_reason, stop_reason, text and metrics.

Read-only docker logs on sparkhead (container started 20:46:08Z on October 23) confirms deepseek_v41 tokenizer, reasoning and tool parsers, TP2 target, max_model_len 327680, max_num_seqs 4, max_num_batched_tokens 4096, speculative k=5 for B1/B2 and k=4 for B3/B4, process proxy and remote pair connection. Raw /v1/completions does not apply chat templating or invoke chat reasoning/ tool output parsers. The old response's raw token IDs, EOS/stop reason, reasoning count and attributable worker-round count are unavailable. Completion usage is not visible-answer usage or a worker-round count. Do not infer any of them from the nominal 32-token budget or unrelated request logs.

The local read-only engine snapshot supports min_tokens and ignore_eos in vllm/entrypoints/openai/completion/protocol.py:to_sampling_params, and exposes finish_reason/stop_reason from the actual RequestOutput in completion/serving.py. Per-request speculative metrics are emitted only when enabled in the engine; missing metrics and reasoning counts are reported as null, never zero.

Patch and limits

warmup_serve.sh keeps the current start.sh interface; its new stdlib-only warmup.py issues internal raw completions with min=max=32, ignore_eos=true, no explicit stops, greedy sampling, priority 20. The current main start.sh already invokes the wrapper after async startup. No start.sh/env edit or server sampling-default change is needed. Its one-token response is now an error, with sanitized counts and finish/stop reasons. Generated text/IDs are never printed or saved. There is no separate hidden reasoning budget: at most 32 completion tokens per request, including any reasoning-like continuation.

Four bounded waves request B1/B2/B3/B4 (ten requests, 320 completion tokens maximum). B1 has a unique synthetic prefix and roughly the previous 5K size (ESTIMATED); returned prompt count must exceed4096 and reported cached count must be zero. B2/B3/B4 use short synthetic prompts, so long serial prefills do not consume the whole32-token decode interval before other streams can join. Barrier-released clients target both live depth bands. Client concurrency is not proof of engine batch shape: request completion skew, chunked prefill and adaptive verification can produce smaller shapes or tail rows. Long-context attention, every verification depth and future B6/B8 are not covered by this startup sequence. Time bounds: each socket operation waits at most the time left of a 90 s helper deadline (and never more than 60 s); a wave never starts after the deadline and a run that finishes late fails; warmup_serve.sh ends the whole process at 95 s (timeout --kill-after=5s, overridable by WARMUP_HARD_S) because a trickling read or a waiting worker thread can outlive the helper's own deadline. Any of these is a failure, which start.sh reports as its existing WARN; with the last K1 start at 432 s the warm-up cannot reach K1's 600 s start guard.

Before every wave, both request gauges must exist and be zero, otherwise the helper refuses. This is an additional guard, not a producer lock or a preemption guarantee. Coordinator must keep D2/local-law and other producers paused behind HOLD throughout startup and warm-up. An already submitted wave has a bounded token budget; no later wave starts if other work remains. The main caller preserves its existing WARN-on-failure behavior, so inspect warm-up completion records before releasing HOLD; service readiness alone does not establish warm-up success.

Qualification / application (coordinator only)

  1. Review/cherry-pick this item from offload/ops1 into the intended production branch. This lane did not deploy, request, restart or benchmark anything. Preserve K1's saved dsv41.env/start.sh hashes; this patch changes neither.
  2. CPU: CUDA_VISIBLE_DEVICES='' python3 -m unittest discover -s offload/launch/tests -p test_warmup.py -v; bash -n offload/launch/warmup_serve.sh.
  3. In the next exclusive startup window, save fresh x86host worker status and proxy counters before warm-up and immediately after it, with matching pid/session, timestamps and no foreign traffic. Worker steps delta measures actual worker RPC steps; drafted_requests delta counts per-request proposals. Engine per-request num_spec_steps is a verification boundary, not necessarily a worker RPC boundary. Do not mix them or rely on the proxy's 1024-round periodic stats to resolve a 32-token request. Missing/stale data leaves that check incomplete. Existing status is written on a timer; wait for a fresh timestamp before reading each snapshot.
  4. Require all ten responses to return completion_tokens=32, finish_reason=length, stop_reason=null; record actual prompt counts and cached tokens separately. Correlate worker graph (B,k,n_out) and target verify-row dispatch/capture records for B1/B2 k5 and B3/B4 k4, including smaller acceptance tails. If shapes are not observed, add a bounded coordinator-only shape test; do not lengthen hidden reasoning or claim the wave size proves capture coverage.
  5. Compare the first subsequent short/32K request and B3/B4 burst with later warm bursts (TTFT, visible-answer timing, worker rounds, failure/watchdog deltas). Existing semantics/greedy regressions still apply. Reject startup timeout regressions. Keep long-prefill first-use qualification separate.
  6. Roll back only offload/launch/warmup_serve.sh and the added helper to the parent revision if needed; K1 manage.py restore and service changes are coordinator-only and not part of this patch.