模型微调学习(二)

第三章 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 构建产品说明书查询、技术资料检索等应用。

④ 官方资源

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 中配置可信的镜像加速地址。

配置步骤:

  1. 打开 Docker Desktop。
  2. 进入 Settings → Docker Engine。
  3. 在 JSON 配置中添加 registry-mirrors。
  4. 点击 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 知识库

进入:

复制代码
知识库 → 创建知识库 → 导入文档

完成以下配置:

  1. 上传 PDF、Markdown、TXT 等业务文档。
  2. 选择文档分段方式(Chunk)。
  3. 选择 Embedding 模型并建立向量索引。
  4. 配置检索策略,并按需启用 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 曲线只能提供诊断线索,不能仅凭单张图确定原因。还需要结合业务测试集的实际效果来判断微调是否成功。

相关推荐
合尘猫24 分钟前
给 AI 客服加权限边界:12 项自查清单与一次越权测试
人工智能·安全·llm
stereohomology25 分钟前
外挂的不同表现形式
人工智能·markdown·所见即所得
wflynn31 分钟前
GitHub 日榜趋势速报 | 2026-10-19
开源·github
长不大的杨瑞杰32 分钟前
Windows 安装 OpenCode v2:原生、WSL、Desktop 怎么选?完整配置与避坑指南
人工智能·windows·ai agent·opencode
灵动的艺术34 分钟前
如一 Agent 架构解读(二):上下文工程——为模型构造它唯一的现实
人工智能·架构·agent
创世虚拟世界35 分钟前
AI 生成的模型怎么放进 3D 虚拟世界
人工智能·3d
yixun_gdas35 分钟前
政企网站错敏巡查:错敏都藏在哪些位置?
开发语言·前端·javascript·内容运营
小羊没烦恼!38 分钟前
.NET 11 Runtime Async 详解
java·运维·开发语言·javascript·python
Дерек的学习记录40 分钟前
Unreal Engine 5:开关门实现和流程控制
开发语言·学习·ue5
硅基流动44 分钟前
超级峰的 AI 开发实践:从做出功能到持续交付|开发者说
人工智能·科技·ai