Refactor tokenizer error handling to use warnings instead of exceptio… (#744)

* Refactor tokenizer error handling to use warnings instead of exceptions for missing tool call tokens

* disable tool calling if not in vocab

* add tool call warning

---------

Co-authored-by: Awni Hannun <[email protected]>
This commit is contained in:
Gia Huy Vuong
2026-01-09 07:19:33 -08:00
committed by GitHub
co-authored by Awni Hannun
parent 3eb6ecf2b6
commit a20eefd7c2
2 changed files with 16 additions and 8 deletions
+7
View File
@@ -524,6 +524,13 @@ class ResponseGenerator:
if tokenizer.has_chat_template:
process_message_content(messages)
if tools and not tokenizer.has_tool_calling:
logging.warning(
"Received tools but model does not support tool calling. "
"If you think this is an error, file an issue here: "
"https://github.com/ml-explore/mlx-lm/issues"
)
return tokenizer.apply_chat_template(
messages,
tools=tools,
+9 -8
View File
@@ -1,13 +1,12 @@
import importlib
import json
import warnings
from functools import partial
from json import JSONDecodeError
from typing import Any, Dict, List, Optional
from transformers import AutoTokenizer, PreTrainedTokenizerFast
from .tool_parsers.json_tools import parse_tool_call as default_tool_parser
class StreamingDetokenizer:
"""The streaming detokenizer interface so that we can detokenize one token at a time.
@@ -276,7 +275,7 @@ class TokenizerWrapper:
self.has_chat_template = (
tokenizer.chat_template is not None or chat_template is not None
)
self._tool_parser = tool_parser or default_tool_parser
self._tool_parser = tool_parser
self._tool_call_start = tool_call_start
self._tool_call_end = tool_call_end
@@ -290,11 +289,13 @@ class TokenizerWrapper:
self._think_end_id = vocab[think_end]
break
# Fallback to defaults if no tool call tokens are provided
if tool_call_start and tool_call_start not in vocab:
raise ValueError("Tool call start token not in vocab")
if tool_call_end and tool_call_end not in vocab:
raise ValueError("Tool call end token not in vocab")
# Disable tool calling if tool call tokens aren't in vocab
if (tool_call_start and tool_call_start not in vocab) or (
tool_call_end and tool_call_end not in vocab
):
self._tool_call_start = None
self._tool_call_end = None
self._tool_parser = None
def apply_chat_template(self, *args, tokenize=True, **kwargs):
if self._chat_template is not None: