Fix condition for streaming output_ids in tokenizer manager (#13759)

Signed-off-by: Xinyuan Tong <xinyuantong.cs@gmail.com>
Co-authored-by: Chang Su <chang.s.su\n@oracle.com>
Co-authored-by: Xinyuan Tong <115166877+JustinTong0323@users.noreply.github.com>
Co-authored-by: Xinyuan Tong <xinyuantong.cs@gmail.com>
This commit is contained in:
Lianmin Zheng
2025-11-29 13:56:15 -08:00
committed by GitHub
parent d7cb08c5be
commit 155a9e7237
6 changed files with 72 additions and 30 deletions

View File

@@ -578,6 +578,8 @@ def run_benchmark(server_args: ServerArgs, bench_args: BenchArgs):
if is_in_ci() and bench_args.append_to_github_summary:
write_github_step_summary(summary)
else:
print(summary)
# Save results as pydantic models in the JSON format
if bench_args.pydantic_result_filename:

View File

@@ -84,14 +84,6 @@ class HarmonyContext(ConversationContext):
if isinstance(output, dict) and "output_ids" in output:
output_token_ids = output["output_ids"]
# TODO: REMOVE here:
# Very hacky, find the first occurrence of token 200006 and cut from there
try:
start_index = output_token_ids.index(200006)
output_token_ids = output_token_ids[start_index:]
except ValueError:
pass
for token_id in output_token_ids:
self.parser.process(token_id)
output_msgs = self.parser.messages
@@ -189,6 +181,7 @@ class StreamingHarmonyContext(HarmonyContext):
self.parser = get_streamable_parser_for_assistant()
self.encoding = get_encoding()
self.last_tok = None
self.num_processed_tokens = 0
@property
def messages(self) -> list:
@@ -199,16 +192,25 @@ class StreamingHarmonyContext(HarmonyContext):
# RequestOutput from SGLang with outputs
output_token_ids = output["output_ids"]
# TODO: REMOVE here:
# Very hacky, find the first occurrence of token 200006 and cut from there
# Find the first occurrence of token 200006 and cut from there
try:
start_index = output_token_ids.index(200006)
output_token_ids = output_token_ids[start_index:]
except ValueError:
pass
# Check if we need to handle cumulative tokens
meta_info = output.get("meta_info", {})
completion_tokens = meta_info.get("completion_tokens")
if (
completion_tokens is not None
and len(output_token_ids) == completion_tokens
):
# Case 1: When --stream-output is not set.
# The output_ids contains all tokens generated so far.
# We only need to process the new tokens.
new_token_ids = output_token_ids[self.num_processed_tokens :]
self.num_processed_tokens = len(output_token_ids)
else:
# Case 2: When --stream-output is set.
# The output_ids contains only the new tokens.
new_token_ids = output_token_ids
self.num_processed_tokens += len(output_token_ids)
for token_id in output_token_ids:
for token_id in new_token_ids:
self.parser.process(token_id)
else:

View File

@@ -345,11 +345,7 @@ def parse_remaining_state(parser: StreamableParser):
return [reasoning_item]
elif parser.current_channel == "final":
output_text = ResponseOutputText(
content=[
ResponseReasoningTextContent(
text=parser.current_content, type="reasoning_text"
)
],
text=parser.current_content,
annotations=[], # TODO
type="output_text",
logprobs=None, # TODO

View File

@@ -75,6 +75,13 @@ class OpenAIServingChat(OpenAIServingBase):
f"Using default chat sampling params from model generation config: {self.default_sampling_params}",
)
# Check if the model is a GPT-OSS model
self.is_gpt_oss = (
hasattr(self.tokenizer_manager.model_config, "hf_config")
and hasattr(self.tokenizer_manager.model_config.hf_config, "model_type")
and self.tokenizer_manager.model_config.hf_config.model_type == "gpt_oss"
)
def _request_id_prefix(self) -> str:
return "chatcmpl-"
@@ -205,14 +212,8 @@ class OpenAIServingChat(OpenAIServingBase):
self, request: ChatCompletionRequest, is_multimodal: bool
) -> MessageProcessingResult:
"""Process chat messages and apply chat template"""
is_gpt_oss = (
hasattr(self.tokenizer_manager.model_config, "hf_config")
and hasattr(self.tokenizer_manager.model_config.hf_config, "model_type")
and self.tokenizer_manager.model_config.hf_config.model_type == "gpt_oss"
)
# GptOss model needs to keep special tokens for harmony parsing
if is_gpt_oss:
if self.is_gpt_oss:
request.skip_special_tokens = False
tool_call_constraint = None

View File

@@ -1623,7 +1623,7 @@ class TokenizerManager(TokenizerCommunicatorMixin):
if isinstance(recv_obj, BatchStrOutput):
state.text += recv_obj.output_strs[i]
if state.obj.stream:
if self.server_args.stream_output and state.obj.stream:
state.output_ids.extend(recv_obj.output_ids[i])
output_token_ids = state.output_ids[state.last_output_offset :]
state.last_output_offset = len(state.output_ids)