fix(engine): generate waits on own request_id + chat enable_thinking - #163
fix(engine): generate waits on own request_id + chat enable_thinking#163bakon11 wants to merge 1 commit into
Conversation
efaf703 to
494584f
Compare
|
Pushed head with VT_CHAT_ENABLE_THINKING + VT_SERVER_VERBOSE documented in docs/ENVIRONMENT.md. Local gates green: doc-checkpoint, public-doc-tables, readme-structure, pr-size, env-doc, device-leakage. Please re-run CI if the previous run was on a mid-force-push SHA. FOLLOWING_AGENTS_PROTOCOL |
4ff9887 to
a43b442
Compare
76a1ca2 to
4807d41
Compare
LLMEngine::generate waits only until this request_id finishes. Chat enable_thinking via VT_CHAT_ENABLE_THINKING; chat_template.jinja sidecar. Docs: STATUS, BENCHMARKS, USAGE, ENVIRONMENT. FOLLOWING_AGENTS_PROTOCOL Following-Agents-Protocol: true AI-Assisted: true Assisted-by: Hermes:grok-4.5 [Hermes]
4807d41 to
e769cb9
Compare
CI status noteLocal gates on this PR head are green:
Build jobs (cpu/vulkan/sanitize) should still be the signal for this change; please don’t block merge solely on that abandoned-ACTIVE assertion while main is in the same state. FOLLOWING_AGENTS_PROTOCOL Following-Agents-Protocol: true |
localai-bot
left a comment
There was a problem hiding this comment.
Approved. This is a real bug with the right fix.
LLMEngine::generate() looped on has_unfinished_requests() — a GLOBAL predicate — so a blocking offline generate could not return while any other request was still in flight. Your comment names the failure exactly: a concurrent chat/async job pins every blocking generate indefinitely. Filtering step_outputs by out.request_id != request_id and breaking on this request's own finished is the correct scope, and it matches what upstream's per-request driver semantics imply.
The idle_steps / kMaxIdleSteps guard reads as belt-and-braces rather than the mechanism, which is the right instinct for a loop that used to be able to hang — max_tokens should always trip first, and aborting the request rather than spinning is the safe failure. Worth a follow-up only if it ever actually fires.
CI: everything green except agent-record, which is a process gate. Per operator instruction I am merging and carrying that myself.
|
Closing as already landed — with thanks, because the fix in here was real and it is now on The core change, // Offline driver for ONE request. CRITICAL: wait only until *this* request_id
// finishes — not has_unfinished_requests() globally. Otherwise a concurrent
// chat/async job (e.g. huge Hermes SOUL) pins every blocking generate forever.It rode in with your other merged work. That was a genuine bug — a blocking offline What made me close rather than merge: this branch is now behind If any part of this PR did not make it across — the
|
Summary
Generic OpenAI-server / engine fixes found while serving Gemma-4 for Hermes. Not Gemma-specific — helps any multi-request serve path.
1.
LLMEngine::generatehang under concurrent loadgenerate()looped onhas_unfinished_requests()globally. A second unfinished request (e.g. long streaming chat) blocked every blockinggenerate()forever after prefill.Fix: wait only until this
request_idfinishes (with idle-step safety abort).2. Chat template
enable_thinkingHF/vLLM parity: pass
enable_thinkinginto minja (default false). Server flags:--enable-thinking/--no-enable-thinkingGemma-4 jinja emits an empty thought block when thinking is off (correct HF behavior).
3.
chat_template.jinjasidecar load(from earlier small commit on this branch) Load sibling
chat_template.jinjawhentokenizer_config.jsonhas no inline template.Test plan
max_tokenscompletesRelation to #154
Split out of the Gemma4 MoE ROCm campaign so this can land without the ROCm device-leakage rework. #154 will stay focused on ops/Backend registration per review.
FOLLOWING_AGENTS_PROTOCOL
Assisted-by: Hermes:grok-4.5 [Hermes]