ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Phi-4-mini-instruct MLX 8Bit 多轮对话教程:chat_template.jinja 一招搞定对话与工具调用

Phi-4-mini-instruct MLX 8Bit 多轮对话教程:chat_template.jinja 一招搞定对话与工具调用

【免费下载链接】Phi-4-mini-instruct-mlx-8Bit

项目地址:https://ai.gitcode.com/hf_mirrors/mlx-community/Phi-4-mini-instruct-mlx-8Bit
点击查看免费下载

Phi-4-mini-instruct-mlx-8Bit 是将微软 Phi-4-mini-instruct 小模型转换为 MLX 格式并做 8Bit 量化的版本,专为 Apple Silicon 芯片设计,让 Mac 也能流畅跑本地大模型多轮对话。本教程带你彻底看懂它的核心文件 chat_template.jinja——这个模板既能组织多轮对话历史,又能在 system 消息中嵌入工具调用定义,一套模板通吃两种场景 🍎

为什么选 MLX 8Bit 版本

这个仓库里的模型基于 model.safetensors.index.json 中记录的约38.4 亿参数(约 3.8B),并通过 config.json 中的quantization字段配置为 8Bit(bits: 8、group_size: 64、mode: affine)量化:

特性说明
运行框架MLX(README.md 中说明使用 mlx-lm 0.31.2 转换)
量化精度8Bit 分组量化,体积约为 bf16 的一半
上下文长度tokenizer_config.json 中model_max_length为 131072
长文本能力config.json 配置了longrope的rope_scaling

8Bit 量化意味着模型文件更小、显存/内存占用更低,在 Mac 上运行多轮对话时速度更快,而效果损失很小,是本地部署的性价比之选 ✅

核心文件 chat_template.jinja 解析

chat_template.jinja 是整个仓库的"灵魂"文件——它决定了你的对话消息最终会被拼装成什么样的文本喂给模型。整个模板只有一行,逻辑却包含两个关键分支:

{% for message in messages %} {% if message['role'] == 'system' and 'tools' in message and message['tools'] is not none %} {{ '<|' + message['role'] + '|>' + message['content'] + '<|tool|>' + message['tools'] + '<|/tool|>' + '<|end|>' }} {% else %} {{ '<|' + message['role'] + '|>' + message['content'] + '<|end|>' }} {% endif %} {% endfor %} {% if add_generation_prompt %}{{ '<|assistant|>' }}{% else %}{{ eos_token }}{% endif %}

用表格拆解它的行为规则:

场景模板输出
普通消息(user / assistant / system)<\|role\|>内容<\|end\|>
system 消息且带tools字段<\|system\|>内容<\|tool\|>工具定义<\|/tool\|><\|end\|>
add_generation_prompt=True末尾追加<\|assistant\|>,提示模型"该你回答了"
add_generation_prompt=False末尾追加eos_token作为收尾

可以看到,每一轮消息都用<|end|>收尾,角色由<|user|>、<|assistant|>等标记界定——这就是多轮对话能在同一模板里层层叠加的底层机制。

多轮对话实战:构建对话循环

使用 README.md 中的 mlx-lm 方式,多轮对话的关键是:维护一个messages列表,每轮把模型回复追加进去,再重新渲染模板。

from mlx_lm import load, generate model, tokenizer = load("SkyStar-tech/Phi-4-mini-instruct-mlx-8Bit") # 维护多轮历史 messages = [{"role": "user", "content": "帮我解释一下什么是量化?"}] for _ in range(3): # 模拟三轮对话 prompt = tokenizer.apply_chat_template( messages, tokenize=False, add_generation_prompt=True ) response = generate(model, tokenizer, prompt=prompt) # 追加模型回复与下一轮用户输入 messages.append({"role": "assistant", "content": response}) messages.append({"role": "user", "content": input("你: ")})

渲染后的 prompt 大致长这样(每一轮都被完整保留):

<|user|>帮我解释一下什么是量化?<|end|><|assistant|>量化是指……<|end|> <|user|>那 8Bit 和 4Bit 有什么区别?<|end|><|assistant|>

三个必须懂的参数

  • add_generation_prompt=True:在末尾生成<|assistant|>,模型看到这个标记就知道轮到自己生成回答,多轮对话必须开启。
  • add_generation_prompt=False:末尾输出eos_token,适合训练数据构造这类"完整语料"场景,仓库中的微调脚本 sample_finetune.py 正是这么用的。
  • tokenize=False:返回渲染后的文本而不是 token ID,方便你肉眼检查模板拼接是否正确,排查对话"串台"问题非常有用。

工具调用:system 消息里的隐藏开关

模板中if message['role'] == 'system' and 'tools' in message这个分支,就是工具调用的入口。只要在 system 消息里带上tools字段,工具定义就会被自动包进<|tool|>...<|/tool|>标记中:

messages = [ { "role": "system", "content": "You are a helpful assistant.", "tools": '{"type":"function","function":{"name":"get_weather","description":"查询天气","parameters":{"type":"object","properties":{"city":{"type":"string"}},"required":["city"]}}}' }, {"role": "user", "content": "北京今天天气怎么样?"} ] prompt = tokenizer.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)

渲染结果中,system 部分会变为:

<|system|>You are a helpful assistant.<|tool|>{"type":"function",...}<|/tool|><|end|> <|user|>北京今天天气怎么样?<|end|><|assistant|>

⚠️ 两点提醒:

  1. 该模板把工具定义放在system 消息的tools字段中,属于项目自定义的拼装方式,与 OpenAI 风格的独立tools参数并不通用。若使用 mlx-lm 等框架内置的工具调用功能,需确认框架能正确传递这个字段。
  2. 模型只负责"按模板格式输出",真正解析工具调用结果并循环调用外部函数,需要你在应用层自行实现。

相关配置与文件清单

文件作用
chat_template.jinja对话与工具调用的 Jinja 模板,本教程主角
tokenizer.json / tokenizer_config.json分词器词表与特殊 token 定义
config.json模型结构、8Bit 量化与长上下文配置
generation_config.json生成时的起止 token(eos_token_id等)
modeling_phi3.py / configuration_phi3.pyPhi-3 架构的模型实现与配置类
sample_finetune.py基于 SFTTrainer + LoRA 的微调示例,内含apply_chat_template用法

如果后续想用自己的数据微调,可以参考 sample_finetune.py:它演示了如何用tokenizer.apply_chat_template(messages, tokenize=False, add_generation_prompt=False)把多轮对话语料拼成训练文本,配合 LoRA(r=16)在 V100 级别显卡上即可训练。

总结

  • 多轮对话:维护messages列表 + 每轮add_generation_prompt=True重新渲染,模板会自动带上全部历史。
  • 工具调用:在 system 消息中添加tools字段,模板会将其包进<|tool|>标记,无需额外改代码。
  • 本地部署:8Bit 量化的 MLX 格式让 3.8B 模型在 Apple Silicon 上运行更快、占用更低,配合 131072 的上下文长度可处理长文档。

掌握 chat_template.jinja 这一个文件,你就掌握了 Phi-4-mini-instruct-mlx-8Bit 多轮对话与工具调用的全部钥匙 🔑

【免费下载链接】Phi-4-mini-instruct-mlx-8Bit

项目地址:https://ai.gitcode.com/hf_mirrors/mlx-community/Phi-4-mini-instruct-mlx-8Bit
点击查看免费下载

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进