0. 开始之前:我们要做什么、需要准备什么¶
本章不碰任何命令。读完你应该能回答四个问题:我们到底要做出什么东西;整个过程分几步、每一步在哪台机器上做;需要提前准备什么;各个部件之间怎样配合。
0.1 一句话说清楚:把通用模型“岗前培训”成专用服务¶
我们从网上下载一个开源的通用大模型 Qwen3-4B(约 40 亿参数,阿里通义千问团队发布)。它什么都能聊,但说话方式不受我们控制:可能回答太长、用词超出小学生水平、喜欢反问。
接着用 600 段“孩子提问 → 理想回答”的示范对话微调它,让它学会一种固定的说话方式:先回答、短句、遇到错误猜想先纠正、给一个安全的小观察。最后把训练好的模型部署成一个 HTTP 服务,任何会调 OpenAI API 的后端代码改一下地址就能用。
用招聘做类比:
| 现实中的招聘 | 本教程里对应的东西 |
|---|---|
| 招来一个知识面很广的新员工 | 下载开源基座模型 Qwen3-4B |
| 给他看一叠“标准回复示范”做岗前培训 | 用示范对话做 SFT 微调 |
| 培训只记在一本小笔记里,不改变他原来的知识 | LoRA:原模型不动,只训练约 130 MB 的增量 |
| 培训后让他上岗接电话 | 用 vLLM 把模型部署成 API |
| 抽查他接电话的质量、看他一天能接多少通 | 调用测试、盲评、压测 |
最重要的一条边界: 微调教的是“怎么说”,不是“知道什么”。具体的科学事实由调用方每次放进提示词(本项目叫“事实卡”),模型负责用合适的方式讲出来。基座明明已经懂常识,为什么还要事实卡、训练时为什么也要放,第 2.2 节专门回答。
0.2 全流程:每一步在哪里做、产出什么¶
① 读懂数据 dataset.json → 1150 条训练样本 (第 2 章,只读)
↓
② 准备 GPU 训练环境 .venv-train + 8 GB 基座模型 (第 3 章,GPU 终端)
↓
③ 训练 LoRA Notebook 跑 72 步 → 130 MB 的 adapter (第 4 章,JupyterLab)
↓
④ 合并导出 基座 + adapter → 8 GB 的完整模型 (第 4 章,JupyterLab)
↓
⑤ vLLM 部署 完整模型 → OpenAI 兼容的 HTTP 服务 (第 5 章,GPU 终端)
↓
⑥ 调用与压测 本地电脑经 SSH 隧道调用,测延迟和吞吐 (第 5 章,本地终端)
↓
⑦ 评估值不值 和“原模型 + 好提示词”盲评对照 (第 6 章,GPU 终端)
| 步骤 | 在哪里做 | 用什么 | 产出 | 大小 | 本书 |
|---|---|---|---|---|---|
| ① 读懂数据 | 任何电脑,只看文件 | 浏览器或编辑器 | 理解 600 段对话怎样变成 1150 条训练样本 | — | 第 2 章 |
| ② 准备 GPU | GPU 主机的终端 | pip、下载脚本 | .venv-train 训练环境、models/qwen3-4b/ 基座 |
环境约 10 GB、基座 8 GB | 第 3 章 |
| ③ 训练 | GPU 主机的 JupyterLab | Notebook 逐格执行 | adapter/(LoRA 增量)、loss-curve.png |
约 130 MB | 第 4 章 |
| ④ 合并导出 | 同一个 Notebook | PEFT | merged-model/,一个可独立运行的完整模型 |
约 8 GB | 第 4、5 章 |
| ⑤ 部署 | GPU 主机的终端 | vLLM | 一个监听 8000 端口的 OpenAI 兼容服务 | 占显存约 20 GB | 第 5 章 |
| ⑥ 调用与压测 | 你自己的电脑 → SSH 隧道 → GPU | Python 标准库 / OpenAI SDK、vllm bench serve |
模型回答、延迟和吞吐数字 | — | 第 5 章 |
| ⑦ 评估 | GPU 主机 | 命令行脚本 + 人工评分 | “LoRA 比只写提示词好多少”的证据 | — | 第 6 章 |
①~⑥ 是主线,GPU 开机约 2~3 小时。⑦ 回答“值不值得微调”,需要更多 GPU 时间和人工评分,可以在主线跑通后再做。
0.3 两台机器、三个窗口:它们怎样配合¶
整个过程只涉及两台机器。GPU 主机按小时租用,用完就停;你自己的电脑负责阅读、打包和调用。
你的电脑(Mac / Linux / Windows 均可)
├── 浏览器:读这本书
├── 浏览器:打开平台提供的 JupyterLab ──HTTPS──→ GPU 主机的 JupyterLab
├── 终端 A:打包项目,用平台上传功能传到 GPU 主机
├── 终端 B:SSH 隧道,本地 18000 端口 ──SSH──→ GPU 主机 8000 端口
└── 终端 C:运行 Python 调用示例,请求发往本地 18000
云上 GPU 主机(Linux + RTX 4090)
├── JupyterLab:运行 Notebook,训练、保存、合并
├── 终端 1:装环境、下载模型、启动 vLLM 服务(监听 127.0.0.1:8000)
└── 终端 2:nvidia-smi 看显存、运行压测
| 部件 | 是什么 | 为什么需要它 |
|---|---|---|
| GPU 云主机 | 按小时租用的 Linux 服务器,带一张 NVIDIA 显卡 | 训练和推理都是海量矩阵运算,CPU 太慢;训练用的 4 bit 量化库只支持 NVIDIA |
| 平台镜像 | 开机时选的系统模板,预装了 Ubuntu、Python 3.11、显卡驱动 | 省去装系统和驱动;驱动只能由平台提供 |
| JupyterLab | 浏览器里的交互式 Python 编辑器,平台一般自带 | 训练代码一格一格执行,每格都能看到输出,出错时只重跑那一格 |
虚拟环境 .venv-* |
项目私有的 Python 依赖目录 | 训练和部署需要的库版本互相冲突,分开装才不会互相覆盖 |
| 内核(kernel) | Jupyter 背后真正执行代码的 Python 进程 | 必须选 .venv-train 注册的内核,Notebook 才能用到项目的依赖;关闭内核才会释放显存 |
| SSH 隧道 | 把本地端口转发到远端端口的加密通道 | 模型服务只监听 GPU 主机的 127.0.0.1,不暴露公网;本地通过隧道像访问本机一样调用它 |
0.4 需要提前准备什么¶
| 准备项 | 具体要求 | 说明 |
|---|---|---|
| 技能 | 会用 Linux 终端、能读 Python、知道 HTTP 和 JSON | 不需要懂数学、PyTorch 或机器学习;需要的概念第 1 章从零讲 |
| GPU 云主机账号 | 任一支持按量计费的 GPU 云平台,账户里有余额 | 需要能开 RTX 4090(24 GB 显存)实例,平台提供 JupyterLab 和 SSH 登录。作者用的是智川云,注册填邀请码 zt4f01m0 可领新人代金券,见第 3.1 节 |
| 主机配置 | 1 × RTX 4090、内存 ≥ 32 GB(合并时建议 ≥ 64 GB)、数据盘 ≥ 100 GB | 镜像选 Ubuntu 22 + Python 3.11 + CUDA 12.x;具体选择见第 3.1 节 |
| 预算 | 主线约 2~3 小时开机,评估实验另需 10~20 小时 | 以智川云 RTX 4090D 按量 ¥1.25/小时计,主线约 ¥3~4,评估实验约 ¥13~25;估算方法见第 7.1 节 |
| 你自己的电脑 | 能上网、有终端和 SSH 客户端;想在本地运行检查或调用示例时装 Python 3.11 | 不需要本地显卡,也不需要自己装 CUDA |
| 网络 | GPU 主机能访问 PyPI(或平台镜像源)和魔搭 ModelScope | 国内主机通常访问不了 huggingface.co,本教程默认用魔搭下载 |
| 本项目文件 | 本仓库,或电子书“源码下载”页面的练习包 | 上传到 GPU 的是用 tools/build_gpu_zip.py 打出的精简包,第 3.3 节说明 |
| 时间 | 第 1~2 章阅读 1~2 小时;GPU 操作一次连续 2~3 小时 | GPU 按开机时长计费,建议读完前两章再开机 |
不需要准备的: OpenAI 账号或 API Key(vLLM 服务和 OpenAI 接口格式一样,但完全跑在你租的机器上)、Hugging Face 账号(模型公开,从魔搭下载)、自己的训练数据(项目已经带了一份)。
0.5 阅读路线¶
本书按顺序就是操作顺序,每章开头说明本章要做什么、需要什么、做完得到什么。
| 章节 | 内容 | 在哪里读/做 | 必读? |
|---|---|---|---|
| 0~1 | 目标、准备、必要概念 | 只读 | 必读:第 1 章是后面所有数字和参数的字典 |
| 2 | 训练数据长什么样、怎样变成训练样本 | 只读;可选在本地跑检查 | 必读:知道模型到底在学什么 |
| 3 | 租机器、装环境、下载模型 | GPU 终端 | 必做 |
| 4 | Notebook 训练、看 loss、对比回答、合并 | GPU JupyterLab | 必做 |
| 5 | vLLM 部署、本地调用、压测 | GPU 终端 + 本地 | 必做 |
| 6 | 和“原模型 + 好提示词”做对照、盲评 | GPU 终端 | 主线跑通后再做 |
| 7 | 成本、排错表、最终验收 | — | 遇到问题时查;最后对照验收 |
| 8、附录 | 自动化测试、代码地图、训练代码全文 | — | 想改代码时读 |
已经懂概念的读者可以从第 3 章开始,遇到不认识的参数再回第 1 章或 Notebook 对应格下方的表。
0.6 练习任务:陪小学生探索科学¶
为什么不用客服、写代码之类的常见任务?因为“给小学生讲科学”这种回答风格鲜明,微调前后的变化一眼就能看出来;而且科学事实可以核对,方便判断模型有没有乱编。
为什么选择科学探索¶
孩子问“为什么”,后续可能是猜错了、没听懂、想亲手验证,或者只想马上知道答案。这些反馈能让我们观察模型是否真的调整解释,而不只比较措辞是否可爱。
目标是:事实正确、孩子听得懂、下一步值得探索。趣味可以来自一个反常识现象、一个有边界的比喻或一个安全的小观察,不必每条都讲故事或用夸张语气。孩子说结束就结束,不以延长对话时长作为成功标准。
覆盖范围¶
| 类别 | 数据值 | 训练主题例子 |
|---|---|---|
| 天文与太空 | space |
昼夜、四季、月相、流星 |
| 地球与天气 | earth |
云雨、雪花、岩石、河流 |
| 生命与自然 | life |
种子、根、蝴蝶、食物网 |
| 身边的物理 | physics |
影子、声音、浮力、溶解 |
| 工程与工具 | engineering |
拱桥、杠杆、飞机、太阳能电池 |
每类 100 段训练,另有 10 段验证和 10 段测试。这是有限教学样本,不是完整小学课程知识库。grade_band 分为 1–2、3–4、5–6 年级;学段是解释起点,实际反馈优先,不能断言同年级的孩子理解能力一致。
提示词与微调怎样分工¶
一次请求里有四样东西,各管一件事:
| 部件 | 管什么 | 什么时候生效 |
|---|---|---|
| System Prompt(角色提示词) | 角色和基本规则:“你是陪小学生探索科学的伙伴……” | 每次请求都发 |
| 事实卡 | 这道题可以依据的科学资料 | 每次请求按题目选出来发 |
| SFT 示范对话 | 示范如何处理误解、没听懂、观察不一致和偏好变化 | 只在训练时用,学到的方式存进 adapter |
| LoRA | 限定只更新一小部分参数,原模型不动 | 训练时决定改哪些参数 |
本项目的 10 类示范路径是:纠正误解、换一种解释、接住具体追问、可选观察、检验猜想、由简入深、说明比喻边界、核对观察差异、不出题追问、自然结束。同一主题内部分答案复用,不能把 500 段理解成 500 个独立科学问题。
不承诺“提示词永远替代不了微调”。第 6 章会比较原模型加完整提示词及三个示例的 B 组,与使用完全相同输入的 LoRA C 组。在未训练的科学主题上,观察 C 是否更稳定地回应孩子反馈。如果没有改善,就如实保留 B。
0.7 当前有什么¶
更新:2026-10-10。
| 内容 | 当前状态 |
|---|---|
| 单一数据源 | data/dataset.json:60 张事实卡、600 段合成对话(500 train / 50 val / 50 test) |
| 训练样本 | 500 段 train 展开成 1150 个回答目标;Notebook 默认跑满 1 个 Epoch(约 72 步) |
| Notebook | 分词、掩码、QLoRA、loss 曲线、保存、重载、比较、BF16 合并,最后附 vLLM 部署和调用 |
| 部署 | vLLM 部署合并模型或直接挂载 adapter;标准库 / OpenAI SDK 调用;vllm bench serve 压测 |
| 本地验证 | 数据检查和微型 CPU 训练机制测试,见验证记录 |
| 尚未在真实 GPU 上验证 | 4B 训练耗时与显存、vLLM 服务、压测数字;以你在 GPU 主机上的实测为准 |
0.8 结论的边界(全书只说一次)¶
- 所有对话都是合成草稿(
review.status="draft"),没有经过人工逐条审核,回答偏短、结构重复。用它学流程和工程完全够用;用它得出“LoRA 一定更好”的结论不够。 - 能生成回答,只说明文件和服务可用;loss 下降,只说明模型更像参考回答。回答质量要看第 4.5 节的人工对比和第 6 章的盲评。
- 微调改变的是“怎么说”,不会让模型自动获得新知识或实时信息;事实仍由调用方放进提示词。
验收: 能画出“数据 → 训练 → 合并 → 部署 → 调用”的流程,说出每一步在哪台机器上做、产出什么文件;能列出开机前要准备好的东西;能指出一段对话中“知识是什么”以及“根据反馈改变了什么”。