Part 00 · Orientation
导读:你要造的东西,以及这台机器的边界
先明确产物,再明确硬件上限。这两件事定了,后面的路线才不会走成“收藏了一堆教程,什么也没训出来”。
00.1五件产物:本教程的验收方式
学习目标不是“看过”,而是“留下东西”。整套教程只围绕五件可检查的产物展开,每一件都能被命令验证,不依赖你的主观感觉。
产物 01
一份能跑通的 adapter
用自己准备的 300~1000 条数据,把 3B 模型微调出可加载的 LoRA 权重,mlx_lm.chat 加载后行为与基座有明显差异。
产物 02
一份数据体检报告
对数据集输出去重保留率、长度分布、语言分布、拒绝型样本占比四个数字。数据不合格就别开训。
产物 03
一份行为评估表
200 条固定测试集,覆盖率、有用性、重复率三项打分,有基座对照、有前后对比。
产物 04
一个从零训的小模型
100M 以下、自己写的训练循环、loss 曲线存档、能生成连贯短句。目的是理解梯度,不是追求效果。
产物 05
一条可复现的发布链
一条命令完成 fuse → 量化 → 本地服务启动,附版本号、评测分数、已知缺陷清单。
副产品
一套自己的排错直觉
看到 loss 不降、OOM、输出重复、指标虚高,能在三分钟内定位到“数据 / 超参 / 代码 / 硬件”哪一类。
00.2能力阶梯:五个等级,各自的判定标准
下面这张表是整份教程的骨架。你不需要线性通关,但每个等级都有硬性判定——不达标就回去补,不要靠“大概懂了”往上跳。
| 等级 | 能独立完成 | 判定标准(可验证) | 典型耗时 |
|---|---|---|---|
| L0 使用者 | 下载模型、跑推理、改提示词 | 能用命令行加载 4-bit 模型并在 16GB 内不 OOM | 3–5 天 |
| L1 调参者 | 用现成脚本跑 LoRA,看懂 loss 曲线 | 能解释一次 loss 尖峰的原因,并改对一个超参让它消失 | 2 周 |
| L2 数据工程师 | 自己构造数据、清洗、配比、诊断数据问题 | 能证明“模型变差是数据问题”——用一份只改数据的对照实验 | 4 周 |
| L3 行为工程师 | 控制模型的拒答倾向、风格、格式,并量化 | 拒绝率下降 ≥ 20 个百分点且通用能力保持 ≥ 95% | 4–6 周 |
| L4 训练者 | 从零写训练循环,训 10M–100M 模型,理解稳定性 | 不看教程能复现自己的训练脚本,loss 曲线可预测 | 6–8 周 |
| L5 专家 | 设计数据产线、定位训练故障、评估并交付 | 能对别人的模型给出可复现的诊断结论与改进方案 | 持续 |
注意 L2 和 L3 之间的顺序。多数人跳过数据直接调参,于是永远停在 L1:因为 80% 的效果差异来自数据,而调参只能吃掉剩下 20% 里的一部分。
00.3硬件真相:16GB 统一内存到底能做什么
Mac 的统一内存意味着 CPU 和 GPU 共享同一块物理内存,模型不需要在设备间拷贝——这是它能跑起来的原因,也是它的天花板:没有独立显存可以“借用”。
关键结论,按重要性排序:
- 权重不是瓶颈,激活才是。3B 的 4-bit 权重只有 1.8GB,但 seq=1024、batch=1 时的激活峰值可以轻松超过 3GB。所以“显存不够”通常要靠缩短序列、开梯度检查点解决,而不是换更小的模型。
- 系统要预留 3~4GB。macOS 的窗口服务、浏览器、Spotlight 都会抢内存。训练时关掉浏览器是真实有效的操作,不是玄学。
- swap 是性能悬崖。一旦开始换页,训练速度会掉一个数量级,而且你不会收到明确报错,只会觉得“Mac 好慢”。所以峰值要压在 13GB 以内。
- 带宽决定速度,容量决定可行性。M4 的内存带宽约 120GB/s,比 4090 的 1000GB/s 低一个数量级。同一份 LoRA 任务,4090 上 20 分钟,这里要 1–2 小时。这是硬件事实,不是配置问题。
| 任务 | 16GB 可行性 | 建议配置 | 预期耗时 |
|---|---|---|---|
| 推理 3B / 4-bit | 轻松 | 默认参数 | 15–25 tok/s |
| 推理 8B / 4-bit | 可行 | --max-tokens 控制长度 | 8–12 tok/s |
| LoRA 1B–3B | 舒适 | bs=1, seq=1024, ckpt 可关 | 500 iters ≈ 20–40 min |
| LoRA 7B–8B | 紧张但可行 | bs=1, seq=512, 必开 ckpt, layers≤8 | 500 iters ≈ 1.5–2.5 h |
| 全量微调 1B | 不建议 | 优化器状态 ×4 权重 | 易 swap |
| 从零训 10M–100M | 可行 | bs 8–32, seq 256–512 | 数小时 |
| DPO 3B | 可行 | 需同时前向 policy + reference | 约为 SFT 的 2 倍 |
00.4学习方法:三遍法,每遍目标不同
同一个实验做三遍,比看三个不同教程有用。这是本教程建议的节奏:
| 遍次 | 目标 | 做法 | 完成标志 |
|---|---|---|---|
| 第一遍:跑通 | 建立肌肉记忆 | 原样复制命令,不修改任何参数,跑完看到 loss 下降 | 产出第一份 adapter |
| 第二遍:改坏 | 建立因果直觉 | 故意把 lr 调大 100 倍、把数据减到 10 条、把 seq 拉到 4096 | 能说出每种坏法的症状 |
| 第三遍:重建 | 把知识变成能力 | 不看教程,从空目录开始重写数据脚本和训练命令 | 能给别人讲清每一步为什么 |
“改坏”这一步最容易被跳过,但它是性价比最高的。你只需要记住四种症状的指纹:
- lr 太大:loss 前几步剧烈震荡,之后卡在一个高于起点的平台,或直接 NaN。
- 数据太少:train loss 迅速趋近 0,模型开始逐字复述训练样本,换一个问法就崩。
- 序列太长:不是报错,是系统变卡、风扇狂转、iters/s 掉到 1/5——swap 已经开始。
- 模板不匹配:loss 正常下降,但推理时模型输出角色标记(如
<|im_start|>)而不是回答。
时间预算怎么写
不要按“学完某章”排期,按“跑完某个实验”排期。一个实验的合理粒度是 1–3 小时:包含准备数据、启动训练、等待、评估。等待时间用来看理论,正好形成“做—读—改”的循环。
00.5边界:能做什么,不能做什么
这套教程涉及“降低模型拒答倾向”的技术。这个技术本身是中性的——它同时是去审查研究、角色扮演微调、客服话术定制、减少过度拒答(over-refusal)的共同基础。工程上必须分清两件事:
技术目标(本教程教的)
让模型在合法且无害的请求上不要过度拒答,同时保留对真正有害请求的拒绝能力。核心手段是数据配比、SFT、偏好优化与量化评估。
不教的部分
不提供用于绕过法律禁止内容的具体数据构造方法,不提供规避监管的分发方案。这不是能力限制,是边界。
工程实践中建议至少做三件事:
- 留数据来源台账:每条数据记来源、许可、抓取时间。后面出事,这是唯一能自证的东西。
- 保留拒绝能力基线:训练前后都跑一组“明显有害请求”的测试,确认模型没有变成“什么都答”。这既是安全要求,也是质量要求——无差别顺从的模型通常伴随幻觉率上升。
- 发布前写明用途限制:模型卡(model card)里写清训练数据、评测结果、已知缺陷、禁止用途。
00.6开跑前的 60 秒自检
下面这段命令不依赖任何模型下载,只用来看清你的机器状态。全部通过再进入第二部分。
# 1. 芯片与内存
sysctl -n machdep.cpu.brand_string
sysctl -n hw.memsize | awk '{printf "RAM: %.1f GB\n", $1/1073741824}'
# 2. macOS 版本(MLX 需要 13.5+,建议 14+)
sw_vers -productVersion
# 3. 磁盘余量(模型动辄 5-15GB)
df -h / | tail -1 | awk '{print "可用: "$4}'
# 4. Python 版本(3.10-3.12 最稳,3.13 部分包尚未跟进)
python3 -V
# 5. 当前内存压力(训练前应为绿色)
memory_pressure | head -3期望结果:内存 ≥ 16GB、macOS ≥ 14、可用磁盘 ≥ 60GB、Python 3.10–3.12。任何一项不满足,先解决它,不要带着问题往下走。
这份教程怎么读
- 第二、三部分必须动手,不能只读——环境问题只能靠动手暴露。
- 第四部分(数据)是全文最长的一章,值得慢读,它是后面所有效果的地基。
- 第六部分(行为调整)争议最大,请连同“合规边界”一起读。
- 第七部分(从零训练)看着最硬核,实际上是理解一切的最短路径。哪怕只训一个 10M 模型,你对 loss 的直觉也会永久改变。