[Bugfix][Frontend] Raise exception when file-like chat template fails to be opened (#4292)

This commit is contained in:
Cyrus Leung 2024-04-24 02:19:03 +08:00 committed by GitHub
parent 2b7949c1c2
commit 1e8f4252aa
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 29 additions and 13 deletions

View File

@ -76,20 +76,29 @@ def test_load_chat_template():
{% if add_generation_prompt and messages[-1]['role'] != 'assistant' %}{{ '<|im_start|>assistant\\n' }}{% endif %}""" # noqa: E501 {% if add_generation_prompt and messages[-1]['role'] != 'assistant' %}{{ '<|im_start|>assistant\\n' }}{% endif %}""" # noqa: E501
def test_no_load_chat_template(): def test_no_load_chat_template_filelike():
# Testing chatml template # Testing chatml template
template = "../../examples/does_not_exist" template = "../../examples/does_not_exist"
tokenizer = MockTokenizer() tokenizer = MockTokenizer()
mock_serving_chat = MockServingChat(tokenizer)
with pytest.raises(ValueError, match="looks like a file path"):
OpenAIServingChat._load_chat_template(mock_serving_chat,
chat_template=template)
def test_no_load_chat_template_literallike():
# Testing chatml template
template = "{{ messages }}"
tokenizer = MockTokenizer()
mock_serving_chat = MockServingChat(tokenizer) mock_serving_chat = MockServingChat(tokenizer)
OpenAIServingChat._load_chat_template(mock_serving_chat, OpenAIServingChat._load_chat_template(mock_serving_chat,
chat_template=template) chat_template=template)
template_content = tokenizer.chat_template template_content = tokenizer.chat_template
# Test assertions assert template_content == template
assert template_content is not None
# Hard coded value for template_chatml.jinja
assert template_content == """../../examples/does_not_exist"""
@pytest.mark.asyncio @pytest.mark.asyncio

View File

@ -319,23 +319,30 @@ class OpenAIServingChat(OpenAIServing):
return response return response
def _load_chat_template(self, chat_template): def _load_chat_template(self, chat_template):
tokenizer = self.tokenizer
if chat_template is not None: if chat_template is not None:
try: try:
with open(chat_template, "r") as f: with open(chat_template, "r") as f:
self.tokenizer.chat_template = f.read() tokenizer.chat_template = f.read()
except OSError: except OSError as e:
JINJA_CHARS = "{}\n"
if not any(c in chat_template for c in JINJA_CHARS):
msg = (f"The supplied chat template ({chat_template}) "
f"looks like a file path, but it failed to be "
f"opened. Reason: {e}")
raise ValueError(msg) from e
# If opening a file fails, set chat template to be args to # If opening a file fails, set chat template to be args to
# ensure we decode so our escape are interpreted correctly # ensure we decode so our escape are interpreted correctly
self.tokenizer.chat_template = codecs.decode( tokenizer.chat_template = codecs.decode(
chat_template, "unicode_escape") chat_template, "unicode_escape")
logger.info( logger.info(
f"Using supplied chat template:\n{self.tokenizer.chat_template}" f"Using supplied chat template:\n{tokenizer.chat_template}")
) elif tokenizer.chat_template is not None:
elif self.tokenizer.chat_template is not None:
logger.info( logger.info(
f"Using default chat template:\n{self.tokenizer.chat_template}" f"Using default chat template:\n{tokenizer.chat_template}")
)
else: else:
logger.warning( logger.warning(
"No chat template provided. Chat API will not work.") "No chat template provided. Chat API will not work.")