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:
@@ -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:
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user