LLaMA Factory微调后的大模型在vLLM框架中对齐对话模版

LLaMA Factory微调后的大模型Chat对话效果,与该模型使用vLLM推理架构中的对话效果,可能会出现不一致的情况。

下图是LLaMA Factory中的Chat的对话

下图是vLLM中的对话效果。

模型回答不稳定:有一半是对的,有一半是无关的。
1、未收敛;

模型回答与LLaMA Factory训练chat界面的不一致。
1、对话模版chat_template不一致。

本文来讲解下对话模版不一致的情况的解决方法。

一、原因分析

1、LLaMA Factory在微调训练需要选择模型名称,自动带出对话模版,比如qwen。这个对话模版是LLaMA Factory项目根据qwen官方提供的对话模版改编,与大模型自身的对话模版并不相等。

2、LLaMA Factory的对话模版的源码在LLaMA-Factory/src/llamafactory/data/template.py这个类里。获取对话模版的方法(私有方法)_get_jinja_template ,可以用公共方法fix_jinja_template来调用该私有方法。

大模型的默认对话模版在 tokenizer_config.json里chat_template字段。

3、可以看到LLaMA Factory微调训练时的对话模版与大模型的默认对话模版并不相同。

二、解决方案

既然是因为两边不一致,那么只要保证两边一致即可。也就是模版对话对齐。

我们可以将LLaMA Factory中的模版修改掉,需要修改源码;也可以在vLLM、ollama或LMDeploy等推理框架在运行大模型时候手动指定对话模版。两种方法都可以,这里我们先使用后者来操作。

1、获取LLaMA Factory中的对话模版

在微调训练中,界面中选择大模型后,自定带出对话模版,记住名称,比如qwen 。

写一个python代码,获取对话模版,get_chat_template.py 。

# get_chat_template.py
import sys
import os# 将项目根目录添加到 Python 路径
root_dir = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))))
sys.path.append(root_dir)from llamafactory.data.template import TEMPLATES
from transformers import AutoTokenizer# 1. 初始化分词器(任意支持的分词器均可)
tokenizer = AutoTokenizer.from_pretrained("/root/autodl-tmp/llm/Qwen/Qwen2.5-0.5B-Instruct")# 2. 获取模板对象
template_name = "qwen"  # 替换为你需要查看的模板名称
template = TEMPLATES[template_name]# 3. 修复分词器的 Jinja 模板
template.fix_jinja_template(tokenizer)# 4. 直接输出模板的 Jinja 格式
print("=" * 40)
print(f"Template [{template_name}] 的 Jinja 格式:")
print("=" * 40)
print(tokenizer.chat_template)

需要修改2个地方,(1)初始化分词器,地址要写本地存在的大模型; (2)获取模版对象,template_name一定要写你微调界面上选择的对话模版名称,比如qwen  。

将该文件放在目录LLaMA-Factory/src/llamafactory/data下。

运行该文件。

python get_chat_template.py 

结果如下: 

将内容复制,从====的下一行{% 开始复制。保存到一个文件中,格式为.jinja   ,比如  qwen.jinja 。

2、vLLM运行大模型指定jinja文件

为了使语言模型支持聊天协议,vLLM 要求模型在其 tokenizer 配置中包含一个聊天模板。聊天模板是一个 Jinja2 模板,它指定了角色、消息和其他特定于聊天对 tokens 如何在输入中编码。

可以在 --chat-template 参数中手动指定聊天模板的文件路径或字符串形式。

https://vllm.hyper.ai/docs/serving/openai-compatible-server#%E8%81%8A%E5%A4%A9%E6%A8%A1%E6%9D%BF

vllm serve <model> --chat-template ./path-to-chat-template.jinja

比如:

vllm serve /root/autodl-tmp/llm/Qwen/Qwen2.5-0.5B-Instruct-merge --chat-template /root/autodl-tmp/project/day07/qwen.jinja 

这样就可以保证对话模版一致了。

3、ollama创建ModelFile的内容

创建一个python文件,获取内容:get_ollama_modelfile.py

# mytest.py
import sys
import os# 将项目根目录添加到 Python 路径
root_dir = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))))
sys.path.append(root_dir)from llamafactory.data.template import TEMPLATES, get_template_and_fix_tokenizer
from transformers import AutoTokenizer
from llamafactory.hparams import DataArguments# 1. 初始化分词器(任意支持的分词器均可)
tokenizer = AutoTokenizer.from_pretrained("/root/autodl-tmp/llm/Qwen/Qwen2.5-0.5B-Instruct")# 2. 获取模板对象
template_name = "qwen"  # 替换为你需要查看的模板名称
template = TEMPLATES[template_name]# 3. 修复分词器的 Jinja 模板
template.fix_jinja_template(tokenizer)# 4. ollama制作ModelFile的内容template = get_template_and_fix_tokenizer(tokenizer, DataArguments(template=template_name))
# template.get_ollama_modelfile(tokenizer)
print("=" * 40)
print(f"Template [{template_name}] 的 Modelfile 格式:")
print("=" * 40)
print(template.get_ollama_modelfile(tokenizer))

3、LMDeploy框架指定对话模版

https://lmdeploy.readthedocs.io/zh-cn/latest/advance/chat_template.html

LMDeploy支持json格式的对话模版,需要将jinja2格式的转成json格式。我们可以使用AI搜索来做。比如我们使用DeepSeek来转换。

打开https://chat.deepseek.com/  ,上传jinja2文件,并且输入文字:


文件中是一个jinja2格式的qwen的对话模版,我需要转成lmdeploy框架支持的的json格式的对话模版,json模版格式如下:{"model_name": "your awesome chat template name","system": "<|im_start|>system\n","meta_instruction": "You are a robot developed by LMDeploy.","eosys": "<|im_end|>\n","user": "<|im_start|>user\n","eoh": "<|im_end|>\n","assistant": "<|im_start|>assistant\n","eoa": "<|im_end|>","separator": "\n","capability": "chat","stop_words": ["<|im_end|>"]
}

返回结果:

{"model_name": "qwen","system": "<|im_start|>system\n","meta_instruction": "You are Qwen, created by Alibaba Cloud. You are a helpful assistant.","eosys": "<|im_end|>\n","user": "<|im_start|>user\n","eoh": "<|im_end|>\n","assistant": "<|im_start|>assistant\n","eoa": "<|im_end|>","separator": "\n","capability": "chat","stop_words": ["<|im_end|>", "</tool_call>", "<|im_start|>", "<|im_end|>\n"],"tool_spec": {"tool_call_start": "<tool_call>","tool_call_end": "</tool_call>","tool_response_start": "<tool_response>","tool_response_end": "</tool_response>"}
}

字段说明

  • system/eosys:对应系统消息的开始和结束标记。
  • user/eoh:用户消息的起止标记。
  • assistant/eoa:助理消息的起止标记。
  • meta_instruction:使用原模板中的默认系统提示。
  • separator:消息间的换行符(\n)。
  • stop_words:添加 <|im_end|> 和其他可能的终止标记(如工具调用相关标签)。

工具调用扩展

  • 虽然 LMDeploy 基础模板不直接支持工具调用,但通过 tool_spec 字段扩展了工具调用的起止标记,以兼容原模板中的 <tool_call> 和 <tool_response> 逻辑。

注意事项

  • 若 LMDeploy 严格限制字段,需移除 tool_spec 字段。

  • 若需要动态系统消息(根据输入切换),需在 LMDeploy 框架中额外处理,此 JSON 模板仅保留静态默认值。

三、Open WebUI对话模版说明

Open WebUI有自己的一套对话模版,所以微调后的大模型在使用推理框架(vLLM,ollama,LMDeploy)+Open WebUI,结果可能会产生偏差。所以一般不建议微调后的大模型使用Open WebUI来做界面。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/76210.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

004 健身房个性化训练计划——金丹期(体态改善)

个人笔记使用。 01 肱骨前移 1.放松肩前束 2.放松肩后束 2.5kg哑铃侧展 泡沫轴上下滚 招财猫 肱二头 02 溜肩 宽距的坐姿划船 上顶

【已开源】UniApp+vue3跨端应用从0到1开发指南、uniapp+vue3模板应用

在跨端开发日益成为主流的今天&#xff0c;如何高效构建规范、可维护的企业级应用&#xff1f;本文以UniAppVue3* *TypeScript**为核心技术栈&#xff0c;手把手带你从零搭建高标准的跨平台项目。 通过本文&#xff0c;你将系统掌握&#xff1a; ✅ 环境配置&#xff1a;Node…

线程池设计

线程池实际上也是一个生产者消费者模型&#xff0c;线程池可以让多个线程去任务队列中取任务&#xff0c;执行任务&#xff0c;适用于需要大量的线程来完成任务且完成任务的时间较短。 #include "log.hpp" #include <mutex> #include <condition_variable&…

黑盒测试的正交实验法

背景: 利用因果图法、判定表法可以帮助我们对于输入数据的组合情况进行用例设计&#xff0c;但当输入数据的组合数量巨大时&#xff0c;由于不太可能覆盖到每个输入组合的测试情况&#xff0c;因果图法或判定表法可能就不太适用了&#xff0c;可以采用正交实验法、来合理地减少…

Linux内核编程

linux 系 统 在 2 4 4 0 上 的 启 动 过 程 分 三个 阶 段 u-boot的启动 1.先分清寄存器的分类 RAM的分类 ROM的分类 Mini2440开发板的存 储器配置 Mini2440开发板板载: 1. 64MB sdram; 2. 256MB nand-flash; 3. 2MB nor-flash; 4. s3c2440内部还有4KB iram; Mini2440的启…

黑盒测试的判定表法(能对多条件依赖关系进行设计测试点)

定义: 判定表是分析和表达多逻辑条件下执行不同操作的工具。就是指把所有的输入条件、所有可能采取的动作按表格列出来&#xff0c;每一种条件和动作的组合构成一条规则&#xff0c;也即一条用例。 1.判定表法的引用 等价类边界值分析法主要关注单个输入类条件的测试并未考虑…

从零构建大语言模型全栈开发指南:第四部分:工程实践与部署-4.1.2ONNX格式转换与TensorRT部署

👉 点击关注不迷路 👉 点击关注不迷路 👉 点击关注不迷路 文章大纲 从零构建大语言模型全栈开发指南-第四部分:工程实践与部署4.1.2 ONNX格式转换与TensorRT部署1. 模型部署的核心挑战与价值2. ONNX格式转换技术详解2.1 ONNX技术栈组成2.2 转换流程与关键技术2.3 转换常…

免费下载 | 2025年网络安全报告

报告总结了2024年的网络安全态势&#xff0c;并对2025年的安全趋势进行了预测和分析。报告涵盖了勒索软件、信息窃取软件、云安全、物联网设备安全等多个领域的安全事件和趋势&#xff0c;并提供了安全建议和最佳实践。 一、报告背景与目的 主题&#xff1a;2024企业信息安全峰…

基于Real-Sim-Real循环框架的机器人策略迁移方法

编辑&#xff1a;陈萍萍的公主一点人工一点智能 基于Real-Sim-Real循环框架的机器人策略迁移方法本文通过严谨的理论推导和系统的实验验证&#xff0c;构建了一个具有普适性的sim-to-real迁移框架。https://mp.weixin.qq.com/s/cRRI2VYHYQUUhHhP3bw4lA 01 摘要 本文提出的Rea…

语义分析(编译原理)

1.什么是语义分析: 前两个阶段&#xff0c;词法分析是从字符到单词的一级识别&#xff0c;保证了每个单词的形式是正确的&#xff0c; 语法分析是由单词到语法树的一级识别&#xff0c;如果不符合语法规则就不能建树&#xff0c;因此保证了各个语法成分的构成是正确的 词法分…

蓝桥杯备考---》贪心算法之矩阵消除游戏

我们第一次想到的贪心策略一定是找出和最大的行或者列来删除&#xff0c;每次都更新行和列 比如如图这种情况&#xff0c;这种情况就不如直接删除两行的多&#xff0c;所以本贪心策略有误 so我们可以枚举选的行的情况&#xff0c;然后再贪心的选择列和最大的列来做 #include …

LeetCode hot 100—二叉搜索树中第K小的元素

题目 给定一个二叉搜索树的根节点 root &#xff0c;和一个整数 k &#xff0c;请你设计一个算法查找其中第 k 小的元素&#xff08;从 1 开始计数&#xff09;。 示例 示例 1&#xff1a; 输入&#xff1a;root [3,1,4,null,2], k 1 输出&#xff1a;1示例 2&#xff1a; …

【Java SE】Arrays类

参考笔记&#xff1a; Java中Arrays类(操作数组的工具)_java arrays-CSDN博客 Java——Arrays 类详解_java arrays类-CSDN博客 目录 1.Arrays类简介 2.Arrays.toString 2.1 使用示例 2.2 源码 3. Arrays.copyOf 3.1 使用示例 3.2 源码 4.Arrays.sort 4.1 默认排序使…

git命令简陋版本

git push git pull 临时仓库暂存区 ##############创建提交################ git init #创建git地址 git config --global user.name "***YQ1007" git config --global user.email "***gmail.com" git remote…

6. 王道_网络协议

1 网络协议和网络模型 2 TCP/IP协议族概览 2.1 四层模型的各层实体 2.2 协议数据单元的转换 2.3 常见协议以及分层 2.4 ifconfig 2.5 本地环回设备 3 以太网 3.1 以太网和交换机 3.2 以太网帧 MAC地址大小 48位 6字节 IP地址 32位 4字节 port 16位 2字节 3.3 ARP协议 4 IP协…

minecraft.service 文件配置

minecraft.service 文件配置 # /etc/systemd/system/minecraft.service [Unit] DescriptionMinecraft Fabric Server Afternetwork.target Wantsnetwork-online.target[Service] Usermcfabricuser Groupmcfabricuser WorkingDirectory/minecraft/1.21.1-fabric-server ExecStar…

python leetcode简单练习(2)

20 有效括号 方法思路 要判断一个仅由括号组成的字符串是否有效&#xff0c;可以使用栈这一数据结构。核心思路是遍历字符串中的每个字符&#xff0c;遇到左括号时压入栈中&#xff0c;遇到右括号时检查栈顶的左括号是否匹配。若匹配则弹出栈顶元素&#xff0c;否则返回false。…

AI 数字人短视频数字人口播源码:短视频内容生产的新引擎​

在当下信息爆炸的时代&#xff0c;短视频已成为主流的信息传播与娱乐方式之一。在如此庞大的市场需求下&#xff0c;如何高效、创新地生产短视频内容成为了行业关注的焦点。AI 数字人短视频数字人口播源码应运而生&#xff0c;为短视频内容生产带来了全新的变革。​ 一、行业背…

AI对传统IT行业的变革

传统 IT 行业长期以来面临着诸多挑战。系统类型繁杂、复杂度高&#xff0c;不少环节依赖人工操作&#xff0c;智能化水平偏低&#xff0c;极大地制约了业务运营效率。此外&#xff0c;传统 IT 企业背负沉重的历史包袱&#xff0c;重构系统不仅成本高昂&#xff0c;由于现有系统…

mapbox基础,使用geojson加载cluster聚合图层

👨‍⚕️ 主页: gis分享者 👨‍⚕️ 感谢各位大佬 点赞👍 收藏⭐ 留言📝 加关注✅! 👨‍⚕️ 收录于专栏:mapbox 从入门到精通 文章目录 一、🍀前言1.1 ☘️mapboxgl.Map 地图对象1.2 ☘️mapboxgl.Map style属性1.3 ☘️circle点图层样式二、🍀使用geojson加…