大模型-vllm 启动参数 --chat-template -72
关于 vLLM "--chat-template" 参数的非常常见且重要的问题。简单来说,这个参数决定了 vLLM 如何将多轮对话(系统、用户、助手消息)格式化成一个单一的字符串,以便模型能够正确理解。
首选:不设置,让 vLLM 自动加载。
对于大多数发布在 Hugging Face Hub 上的现代聊天模型(如 Llama 3, Mistral, Qwen2, Gemma 等),模型作者已经将聊天模板保存在了 tokenizer_config.json 文件中。vLLM 默认会尝试自动读取这个配置。
启动时先不加 --chat-template 参数,直接指定模型
python -m vllm.entrypoints.openai.api_server --model "meta-llama/Llama-3-8B-Instruct"
如果 vLLM 能够找到模板,它会打印类似 INFO: Using chat template ... 的日志。
次选:当自动加载失败或你想覆盖时,手动指定。
如果模型比较老、不规范,或者你想使用自定义的模板,就需要手动设置。
你需要找到对应模型的 Jinja2 模板。
操作:将模板字符串或保存模板的文件路径传给 --chat-template 参数。
为什么需要聊天模板 (Chat Template)?
聊天模型(Instruct/Chat models)在训练时,其输入并不是简单的 "你好吗?",而是遵循特定格式的字符串,这个格式包含了角色信息(系统、用户、助手)和特殊的控制符(special tokens)。
Llama 3 的格式可能长这样:
<|begin_of_text|><|start_header_id|>system<|end_header_id|>\n\nYou are a helpful assistant.<|eot_id|><|start_header_id|>user<|end_header_id|>\n\nWhat is the capital of France?<|eot_id|><|start_header_id|>assistant<|end_header_id|>\n\nParis is the capital of France.<|eot_id|>
如果输入的格式与模型训练时的格式不匹配,模型的性能会急剧下降,甚至完全无法理解指令。
--chat-template 参数的作用就是告诉 vLLM 如何使用 Jinja2 模板语言 将一个对话列表(例如 OpenAI API 格式的 messages 列表)转换成上述模型期望的单一字符串。
如何找到正确的聊天模板
Hugging Face 模型仓库 (推荐)
打开你的模型在 Hugging Face 上的主页(例如:meta-llama/Llama-3-8B-Instruct)。
进入 "Files and versions" 标签页。
找到并打开 tokenizer_config.json 文件。
在 JSON 文件中寻找一个名为 "chat_template" 的键。它的值就是你需要的 Jinja2 模板。
流行模型的模板,你可以直接使用。
你可以将模板内容保存到一个文件(例如 chat_template.jinja),然后通过 --chat-template chat_template.jinja 来加载。或者,如果模板不复杂,可以直接作为字符串传入(注意 shell 的引号转义)。
Llama 2 Chat
{% if messages[0]['role'] == 'system' %}
{% set loop_messages = messages[1:] %}
{% set system_message = messages[0]['content'] %}
{% else %}
{% set loop_messages = messages %}
{% set system_message = false %}
{% endif %}
{% for message in loop_messages %}
{% if (message['role'] == 'user') != (loop.index0 % 2 == 0) %}
{{ raise_exception('Conversation roles must alternate user/assistant/user/assistant/...') }}
{% endif %}
{% if loop.index0 == 0 and system_message != false %}
{% set content = '<<SYS>>\n' + system_message + '\n<</SYS>>\n\n' + message['content'] %}
{% else %}
{% set content = message['content'] %}
{% endif %}
{% if message['role'] == 'user' %}
{{ bos_token + '[INST] ' + content.strip() + ' [/INST]' }}
{% elif message['role'] == 'assistant' %}
{{ ' ' + content.strip() + ' ' + eos_token }}
{% endif %}
{% endfor %}
Mistral Instruct / Mixtral Instruct
{{ bos_token }}{% for message in messages %}{% if (message['role'] == 'user') %}{% set content = message['content'] %}{% else %}{% set content = message['content'] %}{% endif %}{% if message['role'] == 'user' %}{{ '[INST] ' + content.strip() + ' [/INST]' }}{% elif message['role'] == 'assistant' %}{{ ' ' + content.strip() + eos_token }}{% endif %}{% endfor %}
ChatML (Qwen, Gemma 等模型使用或兼容)
这是非常通用和流行的一种格式。
{% for message in messages %}
{{'<|im_start|>' + message['role'] + '\n' + message['content'] + '<|im_end|>' + '\n'}}
{% endfor %}
{% if add_generation_prompt %}
{{ '<|im_start|>assistant\n' }}
{% endif %}
将复制的模板内容粘贴到一个新文件,比如 my_template.jinja
python -m vllm.entrypoints.openai.api_server \
--model "your-local-or-hf-model" \
--chat-template my_template.jinja
Qwen2.5-7B-Instruct 使用的是ChatML格式的聊天模板。您可以从模型的 tokenizer_config.json 文件中找到它。
以下是 Qwen2.5-7B-Instruct 的官方 Jinja2 聊天模板:
{% for message in messages %}
{{'<|im_start|>' + message['role'] + '\n' + message['content'] + '<|im_end|>' + '\n'}}
{% endfor %}
{% if add_generation_prompt %}
{{ '<|im_start|>assistant\n' }}
{% endif %}

浙公网安备 33010602011771号