全栈开发知识库

15 · 模型微调与私有化部署

前面 14 篇你一直在"调用别人的模型"。这一篇回答两个进阶问题:什么时候需要自己微调模型、怎么调;怎么把模型部署在自己的机器上、让你的 Agent 连上它。这两块是"Agent 应用工程师"和"Agent 专家"的分水岭,也是面试高级岗位的必考题。

预计 2~3 天(不含训练等待时间)。没有 GPU 也能学:第 6 节的 Ollama 路线用 CPU/Mac 就能跑,微调可以用免费的云 GPU(Colab/Kaggle)。

1. 先想清楚:你真的需要微调吗?

遇到"模型效果不好",专家的排查顺序是一个成本递增的阶梯,绝不上来就微调:

提示词工程(几分钟) → RAG外挂知识(几天) → 微调(几周+算力钱) → 预训练(别想了)
问题类型 正确手段 为什么
模型不知道你的私有知识/新知识 RAG(第 10 篇第 4 节) 知识会变,微调"缝死"在权重里,更新要重训
输出格式/语气/风格不对 先提示词,不行再微调 微调最擅长学"形式",几百条样本就够
特定领域任务做不好(如医疗问诊、代码评审) 微调(SFT) 领域套路要内化到权重
想省钱:用 7B 小模型替代 GPT-4 级 API 蒸馏微调 用大模型造数据教小模型,专项任务上可接近大模型
模型能力天花板不够(推理、数学) 换更强的基座 微调救不了基座智商

一句面试金句:"RAG 解决'知道不知道'的问题,微调解决'会不会做'的问题。"

2. 微调方法地图(名词一次说清)

  • 全参微调(Full Fine-tuning):更新全部参数。7B 模型全参训练要 100GB+ 显存,个人玩不起,也容易把通用能力练丢(灾难性遗忘)
  • LoRA(Low-Rank Adaptation):冻结原模型,只在每层旁边加两个小矩阵——一个大矩阵可以近似拆成两个"瘦长"小矩阵相乘,这就是低秩分解,参数量因此骤减——只训练这不到 1% 的新参数。效果接近全参、显存省一个数量级,是当前微调的绝对主流
  • QLoRA:把冻结的原模型量化成 4bit 再做 LoRA,显存再省一半——7B 模型 16GB 显存(一张免费 Colab T4)就能微调
  • SFT(Supervised Fine-Tuning,监督微调):用"问题-标准答案"对训练,教模型"照着学"。你要做的 99% 是这个
  • RLHF / DPO(偏好对齐):用"回答 A 比回答 B 好"的偏好数据训练,教模型"哪种更好"。大厂对齐团队做的事,了解概念即可

层级关系:SFT/DPO 说的是用什么数据、学什么目标;全参/LoRA/QLoRA 说的是更新哪些参数。两组词可以自由组合,最常见组合 = SFT + QLoRA。

3. 数据准备:微调成败的 80%

3.1 两种通用格式

Alpaca 格式(单轮指令):

{
  "instruction": "把用户的旅行需求解析成JSON",
  "input": "我想十一带爸妈去西安玩四天,预算八千",
  "output": "{\"city\": \"西安\", \"days\": 4, \"budget\": 8000, \"companions\": \"父母\", \"date\": \"十一假期\"}"
}

ShareGPT 格式(多轮对话,Agent 场景更常用):

{
  "conversations": [
    {"from": "human", "value": "北京天气怎么样?"},
    {"from": "gpt", "value": "[TOOL_CALL:get_weather:city=Beijing]"},
    {"from": "human", "value": "[工具返回] Beijing: 晴 25°C"},
    {"from": "gpt", "value": "北京今天晴,25度,很适合出门!"}
  ]
}

看到第二个例子的价值了吗?把你 Agent 的工具调用轨迹做成训练数据,微调后小模型也能稳定输出你的工具调用协议——这是 Agent 微调最常见的实战场景。

3.2 数据从哪来

  1. 生产日志清洗(最好的来源):从你的 Agent 日志里挑出"回答得好"的对话,人工修正后入库
  2. 大模型蒸馏:用 DeepSeek/GPT-4 级模型批量生成高质量问答,教给 7B 小模型(注意各家 API 的服务条款)
  3. 人工编写种子 + 扩写:手写 50 条典型样本,让大模型仿写扩充到 500 条,再人工抽查

3.3 数量与质量

  • 学格式/语气:300~1000 条就有明显效果
  • 学领域任务:3000~50000 条
  • 铁律:质量 > 数量。100 条精心校对的样本,胜过 10000 条脏数据;脏数据不仅没用,还会教坏模型

4. 实操:LLaMA-Factory 微调 Qwen(主推路线)

LLaMA-Factory 是目前中文社区最流行的微调框架,WebUI 点点鼠标就能训。

4.1 硬件要求速查

微调方式 7B 模型显存需求 参考硬件
QLoRA (4bit) ~12GB RTX 3060 12G / Colab 免费 T4
LoRA (16bit) ~20GB RTX 3090/4090 24G
全参 100GB+ 多卡 A100,忘了它

没有 GPU:用 Google Colab(免费 T4)或 Kaggle(每周 30 小时免费 GPU),流程完全一样。

4.2 安装与启动

git clone https://github.com/hiyouga/LLaMA-Factory.git
cd LLaMA-Factory
pip install -e ".[torch,metrics]"

llamafactory-cli webui        # 打开 http://localhost:7860

4.3 WebUI 训练五步

  1. Model:选 Qwen2.5-7B-Instruct(会自动从 HuggingFace/魔搭下载,国内记得 export HF_ENDPOINT=https://hf-mirror.com,见第 09 篇)
  2. Finetuning method:lora;Quantization:4(即 QLoRA)
  3. Dataset:把你的 JSON 数据放进 data/ 目录,并在 data/dataset_info.json 里注册文件名和格式(alpaca/sharegpt)
  4. 超参数(新手默认值就行,只需要懂这三个): - learning_rate 学习率:LoRA 常用 1e-4~2e-4,太大练废、太小练不动 - num_train_epochs 轮数:2~3 轮,轮数太多必过拟合 - cutoff_len 截断长度:必须大于你最长的样本
  5. 点 Start,盯着 loss 曲线:平滑下降后趋平 = 正常;一直不降 = 学习率/数据有问题;降到接近 0 = 大概率过拟合(模型在背答案)

训练产物是一个几十 MB 的 LoRA 适配器(不是完整模型)。在 WebUI 的 Export 页把适配器与基座合并导出为完整模型目录,供下一节部署用。

4.4 训练完必须做的两个检查

  1. 对照评估:准备 20~50 条训练集里没有的测试题,微调前后各跑一遍,肉眼对比 + 让 GPT-4 级模型当裁判打分(第 10 篇的 LLM-as-a-Judge)
  2. 通用能力回归:问几个与训练任务无关的常识题,确认没有灾难性遗忘(比如练完工具调用后连"你好"都回不好了,就是训过头:减少轮数或降低学习率)

5. 部署路线一:Ollama(个人/开发环境,10 分钟上手)

Ollama 把"下载模型 + 量化 + 启动服务"打包成一条命令,Mac/Windows/Linux 都支持,没有独立显卡也能跑(用 CPU,慢一些)。

# 安装(Mac: brew install ollama;或官网下载安装包)
ollama run qwen2.5:7b            # 首次自动下载约4.7GB(4bit量化版),然后直接进入对话

量化是什么:把模型权重从 16bit 压到 4bit,体积和显存降到 1/4,能力损失通常只有几个百分点。q4_k_m 是最常用的平衡档位。

部署你自己微调的模型:把 4.3 节导出的模型转成 GGUF 格式(GGUF = llama.cpp 生态的单文件模型格式,把权重和配置打包成一个文件,好比"模型界的 zip 包";转换用 llama.cpp 仓库自带的 convert_hf_to_gguf.py 脚本),写一个 Modelfile:

FROM ./my-qwen-finetuned.gguf
PARAMETER temperature 0.3
ollama create my-agent-model -f Modelfile
ollama run my-agent-model

关键:Ollama 自带 OpenAI 兼容接口(http://localhost:11434/v1)。还记得手敲四个项目里所有 LLM 调用都走 llm.py 一个文件吗?现在只改 .env 三行,你的整套 Agent 就跑在本地模型上了,一行代码都不用动:

LLM_MODEL_ID=qwen2.5:7b
LLM_API_KEY=ollama
LLM_BASE_URL=http://localhost:11434/v1

这就是"依赖抽象层"的回报——第 11 篇坚持把 LLM 调用收口进 llm.py,在这一刻兑现。

6. 部署路线二:vLLM(生产环境标配)

Ollama 适合单人开发;要同时服务几十上百个用户,用 vLLM(需要 NVIDIA GPU + Linux):

pip install vllm
vllm serve Qwen/Qwen2.5-7B-Instruct --host 0.0.0.0 --port 8001
# 微调过的模型: vllm serve /path/to/你导出的模型目录

同样暴露 OpenAI 兼容接口,.env 指过去即可。vLLM 快在哪(面试高频):

  • PagedAttention:像操作系统管理内存分页一样管理 KV Cache(第 10 篇讲过的注意力缓存),显存利用率提升数倍
  • Continuous Batching(连续批处理):不等一批请求全部完成,谁的生成结束了就立刻把空位让给新请求——高并发下吞吐量是朴素实现的 10~20 倍

显存估算公式(背下来,面试和采购都用):

推理显存 ≈ 参数量 × 精度字节数 + KV Cache
7B 模型 FP16: 7B × 2字节 = 14GB(权重) + 几GB KV Cache → 24G 卡合适
7B 模型 4bit:  7B × 0.5字节 = 3.5GB + KV Cache → 8G 卡能跑
场景 选型
个人开发/演示,无 GPU 或 Mac Ollama
生产环境、高并发、有 N 卡 vLLM
极限省资源、嵌入式/纯 CPU 服务器 llama.cpp
不想管机器,又要私有化 云厂商模型托管(火山方舟/阿里百炼私有部署版)

7. 端到端串一遍:微调 + 部署 + 你的 Agent

一条专家级的完整链路,也是一个能写进简历的项目:

  1. 收集你第 11 篇 Mini Agent 的对话日志,清洗出 500 条带 [TOOL_CALL:...] 的高质量轨迹(ShareGPT 格式)
  2. LLaMA-Factory + QLoRA 微调 Qwen2.5-7B,2 个 epoch
  3. 对照评估:微调后小模型的工具调用格式正确率从 ~80% 提到 95%+
  4. 导出合并 → Ollama/vLLM 部署 → .env 切到本地模型
  5. 效果:推理成本从按 token 付费变成一台自己的机器,数据不出内网——这两点就是企业做私有化的全部动机

8. 高频面试题

  1. RAG 和微调怎么选? 知识类问题用 RAG(可更新、可溯源),能力/格式类问题用微调;实际系统常常两个都用
  2. LoRA 为什么省显存? 冻结原权重不算梯度,只训练低秩旁路矩阵(参数量 <1%);优化器状态(占显存大头)也只需要为这 1% 维护
  3. 过拟合怎么发现、怎么办? loss 逼近 0 / 测试集表现反而变差 / 模型逐字背训练样本;办法:减轮数、加数据、降学习率
  4. 量化会损失多少能力? 4bit 常见损失 1~5 个百分点,对话/摘要类几乎无感,数学/代码类损失更明显——所以上线前要在你自己的任务上评估,不能只信通用榜单
  5. vLLM 为什么吞吐高? PagedAttention 提高显存利用率 + Continuous Batching 消除批内等待
  6. 私有化部署的动机? 数据合规(不出内网)、长期成本(高用量下自建更省)、延迟可控、不被 API 限流卡脖子

下一篇(通关最后一篇):16 · Agent专家踩坑手册与成长路线 | 返回目录:README

本页由 Markdown 自动渲染 · 共 628 篇笔记