Agnes-AI's picture
Upload folder using huggingface_hub
e6b37e4 verified
Raw
History Blame Contribute Delete
3.53 kB
"""Single home for the chat-encoding dispatch.
Which encoder turns chat messages into prompt tokens is a property of the
model, so the serving path and offline tools (benchmarks, evals) must resolve
it here instead of re-deriving it from model architectures themselves.
"""
from __future__ import annotations
from typing import Any, Dict, List, Optional
def resolve_chat_encoding_spec(
*,
hf_config: Any,
tokenizer: Any,
tool_call_parser: Optional[str] = None,
) -> Optional[str]:
"""Return the chat encoding spec for a model: "dsv4", "dsv32", "inkling", or None.
None means the default path (HF chat template).
"""
if tool_call_parser == "deepseekv4":
return "dsv4"
if tool_call_parser == "deepseekv32":
return "dsv32"
architectures = hf_config.architectures
arch = architectures[0] if architectures else ""
if "Agnes" in arch:
return "dsv4"
# Inkling has no Jinja chat_template and uses a tiktoken base + a special-token
# overlay + negative MM placeholders, so it can't go through apply_chat_template;
# render input_ids directly via the Inkling renderer (serving_chat._encode_messages).
if "InklingForConditionalGeneration" in arch:
return "inkling"
has_chat_template = tokenizer is not None and tokenizer.chat_template is not None
if "DeepseekV3" in arch and not has_chat_template:
return "dsv32"
return None
def encode_simple_chat(
*,
tokenizer: Any,
spec: Optional[str],
messages: List[Dict[str, Any]],
thinking_mode: str = "chat",
) -> List[int]:
"""Encode a plain-text chat conversation into prompt token ids.
Minimal encode for offline tools: no tools, no multimodal content, no
continue_final_message; the serving path keeps its full request-level
pipeline in ``serving_chat``. Like
``serving_chat``, an empty system message is prepended when the
conversation does not start with one (for the dsv4/dsv32 encoders this
currently renders to zero tokens, but keeping the insertion explicit ties
this helper to the serving semantics rather than to that coincidence).
"""
if spec == "inkling":
from sglang.srt.parser.inkling_renderer import render_inkling_messages
from sglang.srt.parser.inkling_tokenizer import InklingTokenizer
return render_inkling_messages(
messages,
InklingTokenizer(tokenizer=tokenizer),
add_generation_prompt=False,
)
if spec in ("dsv4", "dsv32"):
if messages and messages[0]["role"] != "system":
messages = [{"role": "system", "content": ""}] + list(messages)
if spec == "dsv4":
from sglang.srt.entrypoints.openai import encoding_dsv4
real_input = encoding_dsv4.encode_messages(
messages, thinking_mode=thinking_mode
)
else:
from sglang.srt.entrypoints.openai import encoding_dsv32
real_input = encoding_dsv32.encode_messages(
messages, thinking_mode=thinking_mode
)
return tokenizer.encode(real_input)
if getattr(tokenizer, "chat_template", None) is None:
raise ValueError(
"This model has no HF chat template and no custom chat encoder; "
f"cannot encode chat messages with {getattr(tokenizer, 'name_or_path', tokenizer)!r}."
)
return tokenizer.apply_chat_template(
messages, add_generation_prompt=True, tokenize=True
)