第三章 EvalScope学习

3.1 使用 EvalScope 评估大模型推理性能
模型部署成功后,还需要通过性能测试评估模型的响应延迟、Token 生成速度、并发能力及吞吐量,判断其能否满足实际业务需求。
EvalScope 是一个开源大模型评测框架,支持对 Ollama、vLLM 等提供 OpenAI 兼容接口的模型服务进行性能压测,也支持本地 Transformers 和 vLLM 推理评估。
① 安装 EvalScope
bash
pip install 'evalscope[perf]' -U
# 验证安装
evalscope --version
② 使用 EvalScope 进行压力测试
以第二章部署的 Qwen3-0.6B 模型为例,假设 vLLM 服务端口为 8005,对外模型名称为 qwen3-local:
bash
evalscope perf \
--parallel 1 5 10 \
--number 10 25 50 \
--model qwen3-local \
--url http://127.0.0.1:8005/v1/chat/completions \
--api openai \
--dataset random \
--min-prompt-length 512 \
--max-prompt-length 512 \
--min-tokens 256 \
--max-tokens 256 \
--tokenizer-path ./models/qwen3-0.6b \
--extra-args '{"ignore_eos": true}'
这里分别测试 1、5、10 并发,对应总请求数为 10、25、50;固定输入 512 Token,目标输出 256 Token,以减少不同请求长度带来的干扰。
注意:ignore_eos 需要推理服务支持,固定输出长度的压测结果主要用于比较性能,并不代表真实用户请求分布。
③ 常用性能评估指标
| 指标 | 含义 | 优化目标 |
|---|---|---|
| TTFT | 首 Token 响应时间 | 越低越好 |
| TPOT | 首 Token 之后平均每个 Token 的耗时 | 越低越好 |
| Latency | 请求端到端总耗时 | 越低越好 |
| RPS | 每秒完成请求数 | 越高越好 |
| Output Throughput | 每秒生成的 Token 总数 | 越高越好 |
| Success Rate | 请求成功率 | 越高越好 |
④ 如何设计性能对比实验?
建议采用控制变量的方法:
- 固定模型:使用相同模型和量化精度。
- 固定硬件:在同一 GPU 环境下测试。
- 改变并发量:分别测试 1、5、10 等不同并发。
- 记录指标:比较 TTFT、TPOT、吞吐量、显存占用和请求成功率。
通过实验,可以进一步比较 Ollama 与 vLLM 的性能差异,并分析并发量增加后,吞吐量是否提升、响应延迟是否明显恶化。
实际实验建议增加预热与重复测试,重点关注平均值和 P95/P99 延迟,避免仅凭单次测试判断部署性能。
3.2 EvalScope 模型推理性能实测与结果分析

在掌握 EvalScope 的基本使用方法后,可以进一步通过实际压测数据,分析模型在不同并发条件下的吞吐量、响应延迟及性能瓶颈。
① 实验环境与测试配置
本次截图使用 EvalScope 对通过 vLLM 部署的 Qwen3-4B 模型进行压力测试。
- 测试模型:Qwen3-4B
- 推理服务:vLLM(OpenAI 兼容 API)
- 并发数量:1、5、10、20
- 输入长度:1024 Tokens
- 输出长度:1024 Tokens
- 测试数据:Random 随机数据集
核心配置:
evalscope perf \
--parallel 1 5 10 20 \
--number 1 5 10 20 \
--model Qwen3-4B \
--url http://127.0.0.1:8000/v1/chat/completions \
--api openai \
--dataset random \
--min-tokens 1024 \
--max-tokens 1024 \
--min-prompt-length 1024 \
--max-prompt-length 1024 \
--tokenizer-path ./Qwen3-4B \
--extra-args '{"ignore_eos": true}'
② 实际测试结果
根据 EvalScope 输出的 Performance Test Summary Report,得到以下数据:
| 并发数 | RPS | 输出吞吐量 (tok/s) | 平均 TTFT (s) | 平均延迟 (s) |
|---|---|---|---|---|
| 1 | 0.08 | 84.68 | 0.136 | 12.09 |
| 5 | 0.35 | 358.59 | 0.600 | 14.26 |
| 10 | 0.59 | 602.63 | 0.748 | 16.97 |
| 20 | 0.59 | 602.35 | 1.353 | 24.24 |
以上为截图中的实际测试数据,四组请求成功率均为 100%。RPS 表示每秒完成的请求数,TTFT 表示首 Token 延迟。
③ 推理性能分析
- 吞吐量变化:并发从 1 增加到 10 时,输出吞吐量从 84.68 提升至 602.63 tok/s,约提升 7.1 倍。
- 性能趋于饱和:并发从 10 增加到 20 后,吞吐量基本保持在 602 tok/s 左右,没有继续明显提升。
- 响应延迟增加:并发为 20 时,平均 TTFT 增加至 1.353 秒,平均请求延迟达到 24.24 秒。
- 尾部延迟恶化:20 并发时 P99 请求延迟达到 33.997 秒,说明高负载下部分请求等待时间明显增加。
④ 如何判断最合适的并发数?
从本次实验来看:
- 低并发(1~5):单请求响应相对较快,但 GPU 整体吞吐能力尚未充分发挥。
- 中等并发(10):吞吐量达到本次测试的最高水平,响应延迟仍相对可控。
- 较高并发(20):吞吐量不再增加,但响应延迟明显上升。
因此,在本次测试的四组配置中,并发数 10 是较好的吞吐量与延迟折中点,但并不能直接认定它是生产环境的最优并发配置。
需要注意,本次各组测试请求数量较少,后续应增加重复测试,并结合 GPU 利用率、显存峰值和 P95/P99 延迟进一步验证结果。
第四章 Dify 智能体与应用开发
4.1 Dify 简介
Dify 是一个开源的大语言模型(LLM)应用开发平台,提供可视化界面,帮助开发者快速构建 AI 应用、RAG 知识库、Agent 和自动化工作流。
它的核心价值是:将底层模型能力转化为可实际使用的 AI 应用,降低开发和集成难度。
① Dify 的主要功能
- 模型接入:支持接入云端模型 API,以及通过 Ollama、vLLM 等部署的本地模型。
- 知识库(RAG):通过文档解析、向量检索和大模型生成,实现企业知识问答。
- Agent 智能体:结合大模型与工具调用,完成复杂任务。
- Workflow 工作流:通过可视化节点编排,实现多步骤 AI 处理流程。
② Dify 的两种使用方式
| 部署方式 | 特点 | 适用场景 |
|---|---|---|
| 开源自托管版 | 部署在本地或企业服务器上 | 私有化应用、内部知识库 |
| Dify 云服务 | 无需自行维护底层平台 | 快速开发、原型验证 |
③ Dify 与大模型的关系
Dify 本身并不是大语言模型,而是一个AI 应用开发与编排平台。
用户输入
↓
Dify 应用
↓
工作流 / RAG / Agent
↓
调用 LLM(Ollama / vLLM / 云端 API)
↓
返回结果
例如,在企业内部可以使用本地部署的 Qwen 模型作为推理引擎,通过 Dify 构建产品说明书查询、技术资料检索等应用。
④ 官方资源
- 官网:https://dify.ai/
- 中文文档:https://docs.dify.ai/zh-hans/introduction
- 开源项目:https://github.com/langgenius/dify
4.2 使用 Docker 部署 Dify

Dify 支持通过 Docker Compose 快速部署,将 Web、API、数据库及其他依赖服务运行在独立容器中,适合构建企业内部 AI 应用和 RAG 知识库。
① 基础环境准备
最低系统要求:
- CPU:2 核及以上
- 内存:4 GiB 及以上
- 软件:Docker、Docker Compose 2.24.0 或更新版本
以上为官方最低要求,实际运行知识库等业务时建议配置更多内存。
② 下载并启动 Dify
# 下载 Dify 源码
git clone https://github.com/langgenius/dify.git
# 进入 Docker 目录
cd dify/docker
# 创建环境配置
cp .env.example .env
首次启动之前,可以根据需要修改 .env 文件。配置完成后运行:
docker compose up -d
# 查看容器运行状态
docker compose ps
初始化页面通常为:
http://localhost/install
③ 修改时区和文件上传限制
打开 dify/docker/.env 文件,设置以下环境变量:
# 将日志时区从 UTC 修改为上海时间
LOG_TZ=Asia/Shanghai
# 普通文件上传上限:200 MB
UPLOAD_FILE_SIZE_LIMIT=200
# Nginx 请求体上限:预留额外传输空间
NGINX_CLIENT_MAX_BODY_SIZE=220M
三个配置的含义:
| 环境变量 | 设置值 | 作用 |
|---|---|---|
LOG_TZ |
Asia/Shanghai |
修改应用日志使用的时区 |
UPLOAD_FILE_SIZE_LIMIT |
200 |
将普通文件上传上限调整为 200 MB |
NGINX_CLIENT_MAX_BODY_SIZE |
220M |
避免 Nginx 提前拒绝较大的上传请求 |
需要注意:LOG_TZ 控制日志时间,并不保证所有容器和前端显示时间都会同步改变。
此外,普通文件、图片、视频和音频的上传限制是分别配置的。例如:
UPLOAD_IMAGE_FILE_SIZE_LIMIT=20
UPLOAD_VIDEO_FILE_SIZE_LIMIT=100
UPLOAD_AUDIO_FILE_SIZE_LIMIT=50
这里是示例值,并非要求把所有媒体类型统一修改为 200 MB。
④ 重新启动并验证配置
修改 .env 后,重新创建相关容器,使配置生效:
docker compose up -d --force-recreate
# 查看容器状态
docker compose ps
可以尝试上传一份小于 200 MB 的测试文档,验证配置是否生效。

⑤ 配置 Docker 镜像加速
Dify 由多个 Docker 容器组成,首次部署时需要下载 Web、API、数据库等组件的镜像。如果网络访问 Docker Hub 较慢,可能出现镜像下载超时或长时间停留在 Pulling 状态。
可以在 Docker Desktop 中配置可信的镜像加速地址。
配置步骤:
- 打开 Docker Desktop。
- 进入
Settings → Docker Engine。 - 在 JSON 配置中添加
registry-mirrors。 - 点击
Apply & restart,保存并重启 Docker Engine。
示例配置:
{
"experimental": false,
"registry-mirrors": [
"https://your-trusted-mirror.example.com"
]
}
其中 your-trusted-mirror.example.com 只是占位地址,需要替换为实际可用且可信的镜像服务。不要直接使用未经验证的第三方镜像源。Docker Desktop 支持通过 Docker Engine 配置界面修改守护进程参数。
⑥ 使用 Docker Compose 启动 Dify
进入 Dify 的 Docker 配置目录:
cd E:\apps\dify192\docker
执行启动命令:
docker compose -p dify192 up -d
其中:
-p dify192:指定 Docker Compose 项目名称。up:创建并启动项目容器。-d:后台运行,不占用当前终端。
截图中出现的:
unknown shorthand flag: 'p' in -p
是因为 -p 被放到了 up 后面。项目名称选项属于 docker compose 的全局参数,应该放在 up 前面
⑦ 查看容器运行状态
首次执行启动命令时,Docker 会自动拉取所需镜像。截图中的 Pulling、Waiting 代表镜像正在拉取或等待处理,不能据此判断部署已经完成。
完成镜像下载后,可以执行:
# 查看容器状态
docker compose -p dify192 ps
# 查看服务日志
docker compose -p dify192 logs --tail=100
# 查看实时日志
docker compose -p dify192 logs -f
所有必需服务正常启动后,再通过浏览器访问 Dify 的初始化页面:
http://localhost/install
实际访问地址取决于 .env 中配置的端口。
需要注意,dify192 只是本次示例的项目名称。如果之前已使用其他名称启动 Dify,后续应保持同一项目名称,避免创建重复容器或产生端口冲突。
4.3 Dify 初始化配置、插件安装与应用发布

完成 Dify 的 Docker 部署后,还需要进行管理员初始化、模型接入、知识库配置以及应用发布,才能真正构建可运行的 AI 应用。
① 初始化管理员账号
首次访问 Dify 时,打开:
http://localhost/install
设置管理员邮箱、用户名和密码,完成工作区初始化。管理员可以管理模型供应商、成员权限和应用配置。
② 安装模型插件
Dify 通过插件扩展模型接入能力。
安装路径:
插件 → 安装插件 → Marketplace
常见插件包括:
| 插件 | 主要用途 |
|---|---|
| Ollama | 接入本地 Ollama 模型 |
| OpenAI-API-compatible | 接入兼容 OpenAI API 的推理服务 |
| vLLM | 接入 vLLM 推理服务 |
| Xorbits Inference | 接入 Xinference 模型 |
| 通义千问 | 接入 Qwen 云端模型服务 |
根据实际部署方案安装相应插件即可,无需全部安装。
③ 配置模型供应商
进入:
个人头像 → 设置 → 模型供应商
添加模型供应商并配置 API Key、模型名称或服务地址。
在构建 RAG 知识库时,通常需要配置:
- LLM:负责理解问题并生成答案。
- Embedding:负责文本向量化和知识检索。
- Rerank:可选,用于重新排序检索结果。
还可以进入"系统模型设置",指定工作区默认使用的模型。不同版本的具体入口可能存在差异。
④ 工作区成员与权限管理
在设置页面选择"成员",可以邀请其他用户加入工作区。
常见角色包括所有者、管理员、编辑者和成员。不同角色具有不同的应用编辑、模型配置及管理权限,适合多人协同开发。
⑤ 创建 RAG 知识库
进入:
知识库 → 创建知识库 → 导入文档
完成以下配置:
- 上传 PDF、Markdown、TXT 等业务文档。
- 选择文档分段方式(Chunk)。
- 选择 Embedding 模型并建立向量索引。
- 配置检索策略,并按需启用 Rerank。
例如,可以将产品说明书、技术规范和安装手册导入知识库,实现基于企业资料的智能问答。
⑥ 应用预览与发布
在 Dify 工作室创建 Chatflow、Workflow 等应用,配置模型及知识检索节点。
创建应用
↓
配置模型和知识库
↓
编排工作流节点
↓
预览与调试
↓
发布应用
↓
通过 Web 或 API 访问
应用通过调试后,可通过"发布"将版本提供给用户使用。后续修改工作流时,通常需要重新发布更新才能使改动在已发布应用中生效
4.4 Dify 接入 Ollama 并构建 RAG 知识问答应用

在完成 Dify 初始化和插件安装后,可以将本地部署的 Ollama 模型接入 Dify,并结合知识库实现 RAG(检索增强生成)问答,最后将应用发布为网页或嵌入已有系统。
① 添加 Ollama 大语言模型
进入 Dify:
设置 → 模型供应商 → Ollama → 添加模型
以 qwen3:8b 为例:
| 配置项 | 示例值 |
|---|---|
| 模型名称 | qwen3:8b |
| 模型类型 | LLM |
| 基础 URL | http://10.10.13.122:11435 |
| 模型模式 | 对话(Chat) |
| 上下文长度 | 4096 |
其中,模型名称需要与 Ollama 实际安装的模型名称保持一致。
注意:截图中使用的是 11435 端口,而 Ollama 默认端口为 11434。如果 Dify 通过 Docker 部署,需要填写容器能够访问的 Ollama 地址,不能简单使用容器自身的 localhost。
② 添加 Embedding 向量模型
知识库需要通过 Embedding 模型将文本转换为向量,以支持语义检索。
例如:
| 配置项 | 示例值 |
|---|---|
| 模型名称 | bge-m3 |
| 模型类型 | Text Embedding |
| 基础 URL | http://10.10.13.122:11435 |
| 上下文长度 | 8192 |
模型需要事先在 Ollama 中下载:
ollama pull qwen3:8b
ollama pull bge-m3
qwen3:8b 用于生成回答,bge-m3 用于向量检索。Embedding 模型的上下文长度应与实际模型能力和部署配置相匹配。
③ 配置知识库并测试问答
在 Dify 中创建聊天助手,选择 qwen3:8b 作为 LLM,并关联已经使用 bge-m3 建立索引的知识库。
以截图中的热带鱼饲养知识库为例:
用户提问:水温多少合适?
↓
Embedding:将问题转换为向量
↓
知识库:检索相关饲养资料
↓
LLM:结合检索片段生成回答
↓
返回回答及知识来源引用
通过右侧的"调试与预览",可以检查模型是否正确利用知识库内容回答问题。
④ 发布应用并嵌入网站
应用测试完成后,点击右上角的"发布",Dify 支持通过多种方式提供服务:
- Web 应用:直接分享已发布的聊天页面。
- 网站嵌入:通过 iframe 或聊天悬浮组件接入现有网站。
- API 调用:供其他业务系统集成。
截图中还展示了 Chrome 扩展嵌入方式。对于正式企业应用,更建议优先采用 Dify 提供的 iframe、嵌入脚本或 API 集成方案,避免不必要的第三方扩展依赖。
⑤ 企业应用场景拓展
相同的技术流程可以应用于企业技术知识问答,例如导入开关插座的产品说明书、技术参数、安装规范及常见故障资料。
用户提问"某型号开关适用什么安装环境?"时,系统可以检索对应技术文档,再由本地模型生成回答,并提供来源依据。
这样能够将 本地大模型部署 + Embedding 向量检索 + Dify 应用开发串联成可落地的企业知识服务方案。
第五章 大语言模型基础原理
5.1 人工智能、大模型及其训练与推理

在学习大语言模型之前,需要先理解人工智能、机器学习、深度学习与生成式 AI 之间的关系,以及大模型从训练到实际应用的基本过程。
① 人工智能的核心概念
- 人工智能(AI):使计算机具备感知、理解、推理和决策等智能能力。
- 机器学习(ML):人工智能的重要实现方式,通过数据学习规律,包括监督学习、无监督学习和强化学习。
- 深度学习(DL):机器学习的分支,主要利用多层神经网络学习数据特征。
- 生成式 AI(Generative AI):能够生成文本、图像、音频等内容,目前主流生成式 AI 主要基于深度学习。
三者的主要包含关系为:
人工智能(AI) ⊃ 机器学习(ML) ⊃ 深度学习(DL)
② 什么是大模型(Foundation Model)?
2021 年,斯坦福大学研究团队系统提出了 Foundation Models(基础模型) 的概念。
其核心思想是:
通过大规模数据预训练获得通用能力,再适配不同的下游任务。
- 训练数据:可以包括文本、图像、音频等多种模态。
- 预训练过程:从大规模数据中学习通用特征和知识。
- 下游应用:通过提示词、微调等方式完成问答、翻译、信息提取等任务。
需要注意,基础模型并没有严格的参数量门槛,并不是只有超过百亿参数才能称为大模型。
③ 大模型的训练与推理
| 对比维度 | 模型训练(Training) | 模型推理(Inference) |
|---|---|---|
| 核心目的 | 学习知识和能力 | 利用已有能力完成任务 |
| 参数变化 | 更新模型权重 | 通常不更新权重 |
| 计算过程 | 前向传播、损失计算、反向传播 | 前向计算并生成结果 |
| 常见场景 | 预训练、微调、对齐训练 | 智能问答、文本生成、RAG |
④ 大语言模型的典型训练流程
大语言模型通常会经历以下阶段:
预训练(Pre-training) → 监督微调(SFT) → 偏好对齐(如 RLHF)
- 预训练:利用海量数据进行自监督学习,获得语言理解、生成及通用知识能力。
- 监督微调(SFT):使用高质量指令与回答数据,提高模型遵循指令和完成特定任务的能力。
- RLHF:利用人类偏好反馈和强化学习优化模型行为,使其回答更符合预期。
其中,RLHF 并不是所有大模型必须经历的训练阶段,也可以采用 DPO 等其他偏好优化方法。
5.2 模型微调相关原理

模型微调(Fine-tuning)是指在预训练模型的基础上,利用特定任务或领域的数据进一步训练,使模型更好地适应目标场景。
要理解微调,首先需要掌握损失函数、梯度下降和训练超参数等基础概念。
① 机器学习:通过数据学习模型参数
传统编程通常由开发者直接编写规则,而机器学习是通过训练数据自动寻找合适的参数。
例如,一个简单的线性模型:
f(x)=ax
其中:
- (x):输入数据
- (a):模型参数(权重)
- (f(x)):模型预测结果
训练的目标就是找到合适的参数 (a),使预测结果尽可能接近真实值。
② 损失函数(Loss)与代价函数(Cost)
两者都用于衡量模型预测的误差,但在基础教学中通常这样区分:
- Loss Function:衡量单个样本的预测误差。
- Cost Function:汇总整个训练集或一个批次的损失,用于优化模型。
例如,采用平方误差:
单个样本损失:
L_i=(y_i-ax_i)\^2
整个训练集的均方误差(MSE):
J(a)=\\frac{1}{m}\\sum_{i=1}^{m}(y_i-ax_i)^2
其中,(m) 是样本数量,(y_i) 为真实值,(ax_i) 为预测值。
训练过程就是不断调整参数,使 (J(a)) 尽可能减小。
③ 梯度下降(Gradient Descent)
梯度下降是一种通过梯度信息迭代优化模型参数的方法。
参数更新公式:
\\boxed{a_{\\text{new}}=a_{\\text{old}}-\\eta\\frac{\\partial J(a)}{\\partial a}}
- 梯度:决定参数调整的方向。
- 学习率 (\eta):控制每次参数更新的幅度。
学习率过小,训练收敛缓慢;学习率过大,可能发生震荡,甚至无法收敛。
④ 常见训练超参数
| 参数 | 含义 | 主要影响 |
|---|---|---|
batch_size |
每次参数更新使用的样本数量 | 显存占用、梯度估计 |
learning_rate |
学习率 | 参数更新幅度 |
epoch |
完整遍历一次训练集 | 训练轮数 |
eval_steps |
每隔多少训练步执行评估 | 验证频率 |
例如,训练集有 1000 条样本,batch_size=10,则每个 Epoch 约有 100 个优化步骤(不使用梯度累积时)。
⑤ 为什么需要微调?
Prompt、RAG 和 Fine-tuning 都能够改善模型在特定任务中的表现,但原理不同:
- Prompt:通过提示词引导模型完成任务,不修改权重。
- RAG:通过检索外部知识,为模型补充回答依据,不修改权重。
- Fine-tuning:利用训练数据更新部分或全部参数,改善特定任务能力或输出行为。
例如:
- 需要查询最新产品参数 → 优先考虑 RAG。
- 需要统一专业术语、回答格式或特定任务行为 → 可以考虑 SFT 微调。
- 需要在有限显存条件下训练 → 可以进一步研究 LoRA / QLoRA。
这是对应 5.2 模型微调相关原理 的总结配图,已经修正损失函数公式,并将 Loss、Cost、梯度下降、微调作用及训练超参数整合在同一张图中。
5.3 微调方法分类与 LoRA、QLoRA 原理

模型微调(Fine-tuning)是在预训练模型的基础上,利用特定任务数据继续训练,使模型更好地适应目标领域。
根据需要更新的参数数量,通常可以分为全参数微调(Full Fine-tuning)和参数高效微调(PEFT)。
① 全参数微调与高效微调
| 对比维度 | 全参数微调 | 参数高效微调(PEFT) |
|---|---|---|
| 更新参数 | 全部模型参数 | 少量参数 |
| 显存需求 | 通常较高 | 通常较低 |
| 训练成本 | 较高 | 相对较低 |
| 代表方法 | Full Fine-tuning | LoRA、Adapter、Prompt Tuning |
| 适用场景 | 计算资源充足、深度任务适配 | 有限 GPU 资源、领域任务适配 |
需要注意,微调虽然可以增强领域任务能力,但不合理的数据和训练策略也可能造成灾难性遗忘(Catastrophic Forgetting),使模型原有能力下降。
② LoRA:低秩适配微调
LoRA(Low-Rank Adaptation)是最常用的 PEFT 方法之一。
其核心思想是:冻结预训练模型原有权重,只训练两个较小的低秩矩阵,用它们近似表示权重的更新量。
假设原始权重矩阵为:
W_0\\in\\mathbb{R}\^{d_{\\text{out}}\\times d_{\\text{in}}}
LoRA 不直接更新 (W_0),而是引入:
\\boxed{W=W_0+\\Delta W=W_0+BA}
其中:
- (A\in\mathbb{R}^{r\times d_{\text{in}}})
- (B\in\mathbb{R}^{d_{\text{out}}\times r})
- (r):低秩矩阵的秩(Rank),通常远小于原始矩阵维度。
实际实现中还常加入 (\alpha/r) 等缩放因子。
例如,对于一个 (4096\times4096) 的权重矩阵,设置 r=16:
- 原始参数量:约 1678 万。
- LoRA 新增可训练参数:约 13.1 万。
因此,LoRA 可以在大幅减少可训练参数的同时,实现针对特定任务的模型适配。
③ LoRA 与 QLoRA 的区别
QLoRA(Quantized Low-Rank Adaptation)可以理解为在 LoRA 基础上,进一步对冻结的预训练模型权重进行低比特量化,从而减少微调时的显存需求。
| 特性 | LoRA | QLoRA |
|---|---|---|
| 基础模型权重 | 常用 FP16 / BF16 | 通常采用 4-bit NF4 |
| 训练对象 | LoRA 低秩参数 | LoRA 低秩参数 |
| 基础模型是否更新 | 不更新 | 不更新 |
| 显存需求 | 较低 | 通常进一步降低 |
| 主要优势 | 训练高效、适配灵活 | 更适合显存受限的微调 |
注意:QLoRA 的核心优势是降低训练显存,而不是保证推理速度更快。 量化计算可能引入额外开销,推理速度还取决于量化格式、硬件和推理引擎。
④ 其他常见高效微调方法
- Freeze Tuning(部分参数冻结):冻结大部分模型参数,仅训练指定层,例如最后几层网络。
- Adapter Tuning:在 Transformer 中插入小型可训练模块,冻结原始模型参数。
- Prompt Tuning:训练连续的软提示向量,引导模型适应下游任务,而不是更新全部模型权重。
这些方法都旨在减少需要训练的参数,但实现方式、额外计算量和任务适配能力存在差异。
⑤ LoRA 关键超参数
| 参数 | 作用 |
|---|---|
r |
控制低秩矩阵维度和可训练参数数量 |
lora_alpha |
控制 LoRA 更新的缩放幅度 |
lora_dropout |
对 LoRA 分支进行 Dropout 正则化 |
target_modules |
指定注入 LoRA 的模型层 |
一般来说:
r越小,可训练参数越少,但可能限制适配能力。r越大,参数量和显存消耗增加,不一定带来更好的效果。- 小数据集可先尝试
r=8或r=16,再根据验证集结果调整,而不是仅根据数据集大小确定 Rank。
对于本地 GPU 资源有限的场景,通常可以优先尝试 LoRA;如果基础模型权重占用过高,再考虑 QLoRA。
这是重新制作的 5.3 微调方法分类与 LoRA、QLoRA 原理配图,包含低秩矩阵结构、量化区别、其他 PEFT 方法和关键超参数,不再重复 5.2 的内容。
5.4 微调数据集构建与格式设计

在大模型微调过程中,数据集的质量、结构及任务覆盖范围,往往直接影响最终的微调效果。
对于 Qwen3 等支持多轮对话、Function Calling 和思考模式的模型,仅有简单的问答数据可能不足以满足复杂任务需求,需要根据实际应用场景设计训练数据。
① 为什么需要构建微调数据集?
公开数据集可以用于通用指令微调,但当模型需要学习特定任务行为时,通常需要构建或筛选专用数据。
- 领域适配:学习行业术语、回答规范和特定任务流程。
- 工具调用:提高 Function Calling 的工具选择与参数生成准确率。
- 能力保持:合理混合通用数据与领域数据,降低灾难性遗忘风险。
数据集并非越大越好,数据准确性、一致性和多样性比单纯增加数量更重要。
② SFT 数据集的基本格式
监督微调(SFT)常见的一种数据格式是 Alpaca 格式,由 instruction、input 和 output 三个字段组成。
{
"instruction": "解释什么是模型量化",
"input": "",
"output": "模型量化是将模型权重转换为较低精度表示,以减少模型存储和运行资源需求。"
}
其中:
instruction:任务指令。input:额外输入,可以为空。output:期望模型学习的标准回答。
对于多轮对话,更推荐使用带角色信息的 messages 结构:
{
"messages": [
{"role": "system", "content": "你是一名技术助手。"},
{"role": "user", "content": "什么是LoRA?"},
{"role": "assistant", "content": "LoRA是一种低秩适配微调方法。"}
]
}
这种结构更适合训练模型理解 System、User 和 Assistant 之间的角色关系。
③ Chat Template 与特殊 Token
大语言模型实际接收的输入通常并非简单拼接的文本,而是经过 Chat Template(对话模板) 转换后的 Token 序列。
以 Qwen3 的常见对话模板为例:
<|im_start|>system
你是一名技术助手。
<|im_end|>
<|im_start|>user
你好!
<|im_end|>
<|im_start|>assistant
你好,有什么可以帮助你?
<|im_end|>
常见标记的作用:
| 特殊标记 | 作用 |
|---|---|
| `< | im_start |
| `< | im_end |
system |
系统角色 |
user |
用户角色 |
assistant |
助手角色 |
<think> |
部分 Qwen3 模型的思考内容标记 |
</think> |
思考内容结束标记 |
表中对特殊标记加了转义,仅用于展示;实际 Qwen3 模板中使用不带转义的原始字符串。不同模型的特殊 Token 和终止符可能不同。
这些标记告诉模型:谁在说话、消息从哪里开始和结束,以及哪些内容属于特定结构。
实际微调时,通常让 Tokenizer 的 apply_chat_template() 根据模型配置自动处理,不建议随意手工拼接特殊 Token
④ Function Calling 数据集格式
如果希望模型学会调用工具,例如查询天气、访问数据库或调用业务接口,则需要在数据集中体现完整的工具调用流程。
用户:查询北京天气
↓
Assistant:选择 get_weather 工具
↓
工具参数:{"location": "北京"}
↓
Tool:返回天气查询结果
↓
Assistant:根据工具结果回答用户
在结构化微调数据中,应包含工具定义、工具调用参数、工具返回结果及最终回答,而不是仅记录"用户问题---最终答案"。
⑤ 带思考过程的据集
部分推理模型支持区分中间推理内容和最终回答,例如 Qwen3 的某些思考模式。
{
"system": "你是一名技术助手。",
"conversations": [
{
"role": "user",
"content": "2 + 3 等于多少?"
},
{
"role": "assistant",
"reasoning_content": "先计算两个整数的和。",
"content": "2 + 3 = 5。"
}
]
}
这里的结构仅用于说明数据组织方式,并非所有训练框架都直接支持该格式,需要根据模型模板进行转换。
reasoning_content:部分数据格式中单独存储的中间推理内容。content:提供给用户的最终回答。- 对于不需要训练思考模式的任务,也可以只保留标准回答。
需要注意,思考数据不能简单等同于高质量训练数据。应核验其正确性、来源和任务适配性,避免将错误的推导过程引入训练。
⑥ 微调数据集的构建流程
明确微调目标
↓
收集公开或业务数据
↓
数据清洗、去重与脱敏
↓
构造问答 / 多轮对话 / 工具调用样本
↓
适配模型 Chat Template
↓
划分训练集与验证集
↓
开展 SFT 微调与效果评估
对于实际项目,建议建立独立测试集,确保训练集与测试集不存在内容泄漏,并同时评估目标任务能力和模型原有通用能力。
注意:Qwen3 实际使用的消息边界标记是 <|im_start|> 和 <|im_end|>,不包含反斜杠。实际训练应以对应模型的 tokenizer_config.json 和 Chat Template 为准。
5.5 Function Calling 与思考数据集构建

对于普通问答任务,使用 instruction / input / output 结构通常就可以完成监督微调。但对于支持工具调用和推理过程的模型,需要构建更丰富的训练数据。
① Function Calling 数据结构
Function Calling 的核心目标是让模型学会什么时候调用工具、调用哪个工具以及如何生成正确参数。
典型流程:
用户提出任务
↓
Assistant 选择工具并生成参数
↓
Function Call(工具调用)
↓
Observation(工具执行结果)
↓
Assistant 生成最终回答
例如 LLaMA-Factory 的 ShareGPT 工具调用数据可使用:
{
"conversations": [
{"from": "human", "value": "帮张三生成发票"},
{
"from": "function_call",
"value": "{\"name\":\"generate_invoice\",\"arguments\":{\"customer_name\":\"张三\"}}"
},
{
"from": "observation",
"value": "{\"invoice_id\":\"INV001\"}"
},
{"from": "gpt", "value": "发票已生成,编号为INV001。"}
]
}
实际训练时还需提供对应的工具定义,并遵循训练框架的字段映射规则。
② 带思考过程的数据
部分推理模型的数据集会区分:
reasoning_content:中间推理内容。content:最终回答内容。
这类数据可用于特定推理能力的训练,但需要保证推理内容正确,并适配模型的 Chat Template。并不是所有模型或训练框架都直接支持 reasoning_content 字段。
③ 构建时需要注意
工具调用数据应覆盖成功调用、参数错误、工具异常以及多轮交互等场景,不能只训练"正确调用一次工具"的理想情况。
5.6 RLHF 偏好数据集与模型对齐

RLHF(Reinforcement Learning from Human Feedback)通过人类反馈优化模型行为,使模型回答更符合任务要求、用户偏好和安全规范。
① 偏好数据集的核心结构
与 SFT 数据集只提供一个参考答案不同,偏好数据集通常针对同一个问题提供两种回答:
- Chosen:更符合预期的回答。
- Rejected:相对较差的回答。
例如:
{
"instruction": "解释什么是模型量化",
"input": "",
"chosen": "模型量化通过低比特表示降低模型存储及计算资源需求,但可能产生精度损失。",
"rejected": "模型量化可以完全不损失精度,并且一定提升推理速度。"
}
② RLHF 与 DPO 的区别
| 方法 | 基本思路 |
|---|---|
| RLHF(典型 PPO 路线) | 利用偏好数据训练奖励模型,再通过强化学习优化策略 |
| DPO | 直接通过偏好数据优化模型,无需单独训练显式奖励模型 |
两者都可以利用 chosen / rejected 类型的偏好数据,但训练算法不同。
③ 偏好对齐的主要作用
- 提高模型遵循用户指令的能力。
- 减少不符合规范或明显错误的回答。
- 优化回答的准确性、完整性和表达方式。
需要注意,偏好对齐不能保证模型完全正确或绝对安全,训练后仍需要进行独立评估。
5.7 面向代码任务的 SFT 数据集设计

对于代码大模型,不同任务需要不同的数据组织方式。例如,代码审查与代码补全虽然都处理源代码,但学习目标不同。
① 代码审查(Code Review)
代码审查的目标是让模型发现潜在问题,并提出具体修改建议。
{
"instruction": "检查代码并指出潜在问题",
"input": "def divide(a, b):\n return a / b",
"output": "未处理b为0的情况,可能触发ZeroDivisionError。建议增加输入检查。"
}
根据应用需求,可以将训练目标设计为:
- 二分类任务:判断是否需要代码审查。
- 问题识别任务:指出错误及风险。
- 修改建议任务:提供修复方案。
② 代码补全(Code Completion)
代码补全则是根据已有代码、注释或函数定义,预测后续实现。
{
"instruction": "根据函数定义补全代码",
"input": "def safe_divide(a, b):",
"output": " if b == 0:\n raise ValueError('除数不能为0')\n return a / b"
}
③ 两类任务的主要区别
| 对比维度 | 代码审查 | 代码补全 |
|---|---|---|
| 输入 | 完整或部分代码 | 代码前缀、函数定义 |
| 输出 | 问题分析、修改建议 | 续写代码 |
| 评价方式 | 问题识别准确率、误报率 | 语法正确率、测试通过率 |
实际构建数据集时,建议增加代码语言、难度及错误类型的多样性,并通过单元测试或人工审核验证生成结果。
5.8 使用 Easy Dataset 构建高质量微调数据集

手工编写大量 SFT 数据成本较高,可以通过 Easy Dataset 等工具辅助完成领域数据集的构建与整理。
Easy Dataset 是一个开源的数据集创建工具,支持文档解析、自动提问、答案生成、数据审核和多格式导出。
① Easy Dataset 数据处理流程
创建项目
↓
配置模型 API
↓
导入领域文档
↓
文档解析与分段
↓
自动生成问题与答案
↓
人工审核、清洗与去重
↓
导出 Alpaca / ShareGPT 数据集
项目地址:Easy Dataset GitHub
② 微调数据集的质量控制
| 关键因素 | 主要要求 |
|---|---|
| 数据质量 | 内容正确、格式一致,去除错误样本 |
| 多样性 | 覆盖不同任务、表达方式和难度 |
| 类别平衡 | 避免模型过度偏向某类任务 |
| 数据去重 | 避免重复样本及训练测试集泄漏 |
| 持续迭代 | 根据验证结果补充薄弱场景 |
③ 数据集规模应该如何选择?
数据量没有统一的最低标准。相比单纯追求几千或几万条数据,更应关注任务复杂度和数据质量。
- 对简单的格式适配任务,可先用少量高质量数据进行验证。
- 对复杂的工具调用和多任务场景,需要覆盖更多样的交互情况。
- 对领域知识查询任务,如果知识更新频繁,可优先使用 RAG,而不是全部依赖微调记忆。
④ 数据集构建的实际建议
可以先准备一批小规模、高质量、经过人工校验的样本,开展 LoRA 微调实验,再根据验证集中的错误类型针对性补充数据。
对于企业业务文档,必须注意数据脱敏、资料授权和生成答案的事实核查,避免将内部敏感信息或错误内容引入训练集。
5.9 常用微调框架与实践流程

大模型微调涉及模型加载、数据处理、训练参数配置、训练监控和模型导出等环节。借助开源框架,可以减少重复开发工作,快速开展 LoRA、QLoRA 等训练实验。
① 常见微调框架
| 框架 | 核心特点 | 适用场景 |
|---|---|---|
| LLaMA-Factory | 集成多种微调算法,提供 Web UI | 快速微调、教学实验 |
| ms-swift | 支持多模态模型、多种训练与对齐方法 | 大模型科研、多模态训练 |
- LLaMA-Factory:基于 Hugging Face 等生态组件,支持 SFT、LoRA、QLoRA、DPO 等训练方式。
- ms-swift:ModelScope 社区推出的训练工具,覆盖微调、对齐、模型评估及推理部署等环节。
② 微调实践的基本流程
环境准备
↓
选择预训练模型
↓
准备并清洗训练数据
↓
选择 LoRA / QLoRA 等训练方式
↓
执行模型训练
↓
评估训练效果
↓
导出并部署模型
③ 如何选择?
- 初学者希望快速完成实验:可以优先使用 LLaMA-Factory。
- 涉及多模态模型、复杂训练任务:可以重点研究 ms-swift。
- 两者均支持命令行训练,具体模型兼容性应以对应版本为准。
5.10 LLaMA-Factory 微调实战

LLaMA-Factory 是一款开源大模型微调框架,提供命令行和图形化操作界面,能够快速完成模型加载、数据配置、LoRA 训练及模型导出。
① 安装 LLaMA-Factory
以 Linux + NVIDIA GPU 为例:
git clone --depth 1 https://github.com/hiyouga/LLaMA-Factory.git
cd LLaMA-Factory
# 安装依赖
pip install -e ".[torch,metrics]"
# 启动 Web UI
llamafactory-cli webui
安装前需要配置兼容的 Python、PyTorch 和 CUDA 环境。
② 下载预训练模型
以 Qwen3-4B 为例:
pip install modelscope
modelscope download \
--model Qwen/Qwen3-4B \
--local_dir ./models/Qwen3-4B
下载后可通过 model_name_or_path 参数指定本地模型路径。
③ 准备训练数据
LLaMA-Factory 常用两种数据格式:
- Alpaca:适合单轮指令微调。
- ShareGPT:适合多轮对话、角色消息和工具调用数据。
使用自定义数据集时,将文件放入 data/ 目录,并在 dataset_info.json 中进行注册。
例如:
{
"my_sft": {
"file_name": "my_sft.json",
"formatting": "alpaca"
}
}
④ 训练与评估
在 Web UI 中选择模型、数据集和 LoRA 训练方式,然后配置:
learning_rate:学习率。num_train_epochs:训练轮数。batch_size:每设备批量大小。lora_rank:LoRA 秩。output_dir:训练结果保存目录。
训练完成后,应先对验证集及独立测试集进行评估,再决定是否合并 LoRA 权重并部署。
5.11 使用 ms-swift 进行 LoRA 微调

ms-swift 是 ModelScope 社区的开源大模型训练框架,支持 SFT、LoRA、QLoRA、DPO、GRPO 等训练方法,同时提供命令行与 Web UI 操作方式。
① 安装与启动
# 安装 ms-swift
pip install -U ms-swift
# 启动图形化界面
swift web-ui
注意:当前官方文档使用的是 swift web-ui 命令。
② 使用命令行微调 Qwen3
以下示例基于官方 LoRA 配置简化:
CUDA_VISIBLE_DEVICES=0 swift sft \
--model Qwen/Qwen3-4B-Instruct-2507 \
--tuner_type lora \
--dataset 'AI-ModelScope/alpaca-gpt4-data-zh#500' \
--torch_dtype bfloat16 \
--num_train_epochs 1 \
--per_device_train_batch_size 1 \
--gradient_accumulation_steps 16 \
--learning_rate 1e-4 \
--lora_rank 8 \
--lora_alpha 32 \
--target_modules all-linear \
--output_dir output
③ 关键参数
--model:指定预训练模型。--dataset:选择训练数据集。--tuner_type lora:采用 LoRA 微调。--lora_rank:控制低秩矩阵维度。--gradient_accumulation_steps:通过梯度累积增加有效 Batch Size。
使用 ms-swift 时,可以通过命令行开展可复现实验,也可以通过 Web UI 完成可视化参数配置。
5.12 训练 Loss 分析与常见问题排查

模型训练过程中,可以通过 Training Loss(训练损失) 和 Validation Loss(验证损失) 的变化趋势,判断模型是否正常收敛。
① 过拟合(Overfitting)
典型表现:
- Training Loss 持续下降。
- Validation Loss 先下降,随后反弹上升。
说明模型对训练数据的拟合越来越好,但对未见样本的泛化能力开始下降。
解决方向:减少训练轮数、使用 Early Stopping、增加高质量数据或适当增强正则化。
② 欠拟合(Underfitting)
典型表现:
- 训练和验证损失都较高。
- 模型对训练数据也没有充分拟合。
可能原因包括训练不足、模型能力受限或参数设置不合理。
解决方向:适当增加训练步数、检查学习率及数据质量,并评估模型是否具备完成任务的能力。
③ 训练不稳定或失败
可能表现为:
- Loss 剧烈震荡或持续增大。
- 出现
NaN、Inf。 - 参数更新后模型效果明显恶化。
常见原因包括学习率过大、异常训练样本、数值精度问题和梯度爆炸等,需要结合日志排查。
④ 三种情况对比
| 情况 | Train Loss | Eval Loss | 优先排查 |
|---|---|---|---|
| 过拟合 | 持续下降 | 先降后升 | Epoch、数据多样性 |
| 欠拟合 | 偏高或缓慢下降 | 通常也偏高 | 训练步数、模型能力 |
| 训练失败或不稳定 | 震荡、发散、NaN | 往往异常 | 学习率、数据、数值稳定性 |
注意:Loss 曲线只能提供诊断线索,不能仅凭单张图确定原因。还需要结合业务测试集的实际效果来判断微调是否成功。