[Spec] Move forward timeout before verify to fix Eagle v1 filter mismatch#18760
Merged
[Spec] Move forward timeout before verify to fix Eagle v1 filter mismatch#18760
Conversation
Contributor
|
Warning You have reached your daily quota limit. Please wait up to 24 hours and I will start processing your requests again! |
Collaborator
Author
Reproductionpython3 -m sglang.launch_server --model meta-llama/Meta-Llama-3.1-8B-Instruct --host 0.0.0.0 --port 23333 --speculative-draft-model lmsys/sglang-EAGLE-LLaMA3-Instruct-8B --speculative-algorithm EAGLE --speculative-num-steps 5 --speculative-eagle-topk 1 --speculative-num-draft-tokens 6 --dtype float16import time
import threading
import requests
URL = "http://localhost:23333/v1/chat/completions"
def send(tag, max_tokens):
try:
r = requests.post(URL, json={
"model": "default",
"messages": [{"role": "user", "content": "Write a long story."}],
"max_tokens": max_tokens,
}, timeout=30)
print(f"[{tag}] {r.status_code}")
except Exception as e:
print(f"[{tag}] {e}")
# Wave 1: old forward_entry_time — will timeout after 3s
threads = [threading.Thread(target=send, args=(f"old-{i}", 512)) for i in range(32)]
for t in threads: t.start()
# Wait for wave 1 to enter decode
time.sleep(2)
# Wave 2: new forward_entry_time — will NOT timeout yet
threads2 = [threading.Thread(target=send, args=(f"new-{i}", 512)) for i in range(16)]
for t in threads2: t.start()
for t in threads + threads2: t.join() |
Collaborator
Author
|
/tag-and-rerun-ci |
0f1be09 to
e0c304a
Compare
Collaborator
Author
|
test_abort.py passed, and other failures are unrelated. |
Johnsonms
pushed a commit
to Johnsonms/sglang
that referenced
this pull request
Feb 14, 2026
2 tasks
This was referenced Mar 1, 2026
magicYang1573
pushed a commit
to magicYang1573/sglang
that referenced
this pull request
Mar 9, 2026
Wangzheee
pushed a commit
to Wangzheee/sglang
that referenced
this pull request
Mar 21, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Motivation
Fixes
ValueError: length of new_indices != length of topk_pin Eagle speculative decoding v1.Related: #14742, #17831
Root Cause
Forward timeout was checked in
process_batch_result_decode, which runs AFTER verify has already settopk_pto N-K entries. The timeout setreq.to_finishandcheck_finished()immediately converted it tofinished_reason, causing M additional requests to finish. The next iteration'sfilter_batch(v1_spec_info_filtered=True)then found N-K-M active requests buttopk_pstill had N-K entries — length mismatch.Abort doesn't have this problem because it only sets
to_finish(inprocess_input_requests), andfilter_batchonly checksfinished_reason. The pendingto_finishis caught by verify'scheck_finished()in the next forward pass, keeping it consistent withtopk_p.Fix
process_batch_result_decode/process_batch_result_prefilltoget_next_batch_to_run(), next to_abort_on_queued_timeout(). Forward timeout now follows the same pattern as abort: only setto_finish, let verify'scheck_finished()handle conversion.forward_draft_extend—req.finished()always returned False there sincecheck_finished()was never called before that point.