Skip to content

Prefix caching + DFlash2 kills the engine on the first request at c=1, which makes the SGLang-compat lpm scheduler unreachable #2042

Description

@localai-bot

Enabling prefix caching kills the engine on the first request when DFlash2
speculative decode is on — at concurrency 1, where the identical binary serves 8/8
with prefix caching off.

engine-fatal: EngineCore busy loop threw: vt: propose_drafts_block: context position
  discontinuity (accumulation out of sync with the target's committed positions)
  at /src/src/vllm/v1/worker/gpu/runner.cpp:2959

Every subsequent request returns 500 [request submitted to a stopped AsyncLLM]. The
rung reads ok=0 failed=8.

Measured

3d895a202 (PR #2010), sm_121a, artifact-gated: vllm-server 101,151,128 B,
flash_fwd=1792, SpecDecodeFA2Bf16=1. dgx:gpu0 (GB10), idle under an rc lease.
--num-blocks 3744 --max-num-seqs 16 --max-model-len 8192, DFlash2 k=8,
vllm bench serve --dataset-name random --backend openai-chat, 1024 in / 512 out.

prefix caching c=1 c=2 c=4
--no-enable-prefix-caching OK 24.84 out tok/s, 8/8 OK 40.11, 8/8 OK 59.13, 16/16
--enable-prefix-caching --scheduling-policy lpm VOID, ok=0 failed=8 not reached not reached

illegal memory access 0, stream is capturing 0 — this is the position invariant
refusing, not #2028 and not #2029.

Mechanism

With APC on, a request whose prefix is served from cache has its committed positions
begin at the cached prefix length, not at 0. The DFlash2 draft context starts its
accounting at 0 for a new request, so the invariant comparing
step.positions[rows[0]] against the accumulated ctx_len fails on the first
propose. The draft path assumes positions start at zero; prefix caching breaks that
assumption.

Consequence: a shipped SGLang-compat capability is unreachable

ENG-SGLANG-BEHAVIOR-FLAG SW1 exposes --scheduling-policy lpm (SGLang alias
--schedule-policy), cache-aware longest-prefix-match admission ordering. Per
src/vllm/entrypoints/openai/server_main.cpp:1266-1275, lpm needs prefix caching to
have any effect
and degrades to fcfs without it. Since prefix caching cannot be
enabled alongside DFlash2, lpm is unreachable in any speculative configuration — the
flag parses, the server boots, and the feature can never do anything. This was its
first-ever load test.

It also means our benchmark's --no-enable-prefix-caching is forced, not a choice,
while the SGLang arm it is compared against runs its radix cache enabled (their flag is
--disable-radix-cache; --disable-radix-attention does not exist upstream and is our
alias only). That asymmetry cannot currently be closed from our side.

Not diagnosed

Whether prefix caching works with speculation OFF is being measured now and will be
posted here; that control separates "APC is broken" from "the APC x DFlash2 interaction
is broken".

Whether the invariant is the DEFECT or the DETECTOR is also open: it may be correctly
refusing a genuinely inconsistent state, in which case the repair is in the draft
context's position accounting, not in the check.

Found while running the first load test of the SW1 lpm path during #2028 ladder work.
Not fixed in flow: it needs its own spec and touches the draft accounting that #2010
just changed.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions