Skip to content

fix: send SSE headers before prefill and beat during it - #735

Open
Javinator9889 wants to merge 1 commit into
ROCm:mainfrom
Javinator9889:fix/sse-headers-during-prefill
Open

Javinator9889 wants to merge 1 commit into
ROCm:mainfrom
Javinator9889:fix/sse-headers-during-prefill

Conversation

@Javinator9889

Copy link
Copy Markdown

Fixes the fourth defect in #733.

HttpSession::write_streaming_response sends the HTTP headers on its first
call
, and in the streaming chat path that call cannot happen until the first
token is generated — insert() runs to completion first.

For a large prompt that is minutes during which the client receives zero bytes,
not even response headers
. It cannot distinguish a working server from a dead
one, so it times out and retries, and the retry queues behind the request still
running.

This emits an SSE comment before prefill and every five seconds during it. Lines
beginning with : are comments that clients ignore, but they put the headers on
the wire and keep the connection demonstrably alive. is_cancelled() is already
invoked once per prefill chunk, so it carries the heartbeat with no new plumbing.

Measured on qwen3.5:9b with a 9038-token prompt:

before after
time to first byte 23.2s (the whole prefill) 0.002s

The answer, the usage chunk and the [DONE] terminator are unchanged; three
heartbeats arrived before the first content chunk.

This does not make prefill faster — it stops the client concluding the server is
dead while it works.

write_streaming_response() sends the HTTP headers on its first call, and in
the streaming chat path that call cannot happen until the first token is
generated -- insert() runs to completion first. On a long prompt that is
minutes during which the client receives zero bytes, not even response
headers, and cannot distinguish a working server from a dead one. It times
out and retries, and the retry queues behind the request still running.

Emit an SSE comment before prefill and every five seconds during it. Lines
starting with ':' are comments that clients ignore, but they put the headers
on the wire and keep the connection alive. is_cancelled() is already invoked
once per prefill chunk, so it carries the heartbeat with no new plumbing.

Measured on qwen3.5:9b with a 9038-token prompt: time to first byte drops
from the full prefill (23s) to 2ms. Answer, usage chunk and [DONE] unchanged.

Refs ROCm#733
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant