大模型-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 %}
posted @ 2025-06-24 09:44  jack-chen666  阅读(1246)  评论(0)    收藏  举报