大语言模型微调入门:从 ChatGPT 训练原理到本地 QLoRA 实作
本文是 AI 系列的第三篇。如果你还不了解 AI 的基本概念与 Transformer 发展脉络,建议先阅读《从智慧到人工智能:AI 基本概念与发展史入门》与《机器学习与 MNIST 手写数字识别入门》。
这篇文章会从 ChatGPT 等大语言模型「怎么被训练出来」讲起,解释为什么预训练 alone 不够、为什么需要 SFT 与 RLHF 做对齐,最后带你用 fine-tuning-playground 在本地 GPU 上跑一遍 QLoRA 监督微调,让 Qwen3.5-4B 学会回答台湾师范大学(NTNU)相关的问题。
你不需要已经训过大模型,但最好有基本 Python 环境,并愿意打开终端跟着敲命令。
前言——从「会说话」到「当好助手」
你可能已经用过 ChatGPT、Claude、Gemini 或通义千问。它们能写邮件、改代码、解释概念,语气往往礼貌、结构清晰,像一个训练有素的助手。2022 年底 ChatGPT 发布之后,「大语言模型」从科研对象迅速变成 消费级产品——背后不仅是参数变大,更是 训练范式 的成熟:先预训练,再 SFT,再 RLHF。OpenAI 后续 GPT-4、o 系列在架构与数据上继续迭代,但 对齐流水线 的逻辑一脉相承。
但如果你只把「大语言模型(Large Language Model,LLM)」理解成「读了互联网上所有文字的超级 autocomplete」,就会漏掉一半故事:产品级的对话 AI,几乎都不是「预训练完就上线」的。
预训练教会模型「语言是什么」——语法、事实片段、写作风格、代码模式。它不会天然知道:用户问一个问题时,应该直接回答,而不是续写一篇 Wikipedia;应该简洁,而不是写三千字散文;应该承认不知道,而不是自信地编造。这些「当好助手」的能力,来自后续的对齐(Alignment)阶段:监督微调(Supervised Fine-Tuning,SFT) 与 基于人类反馈的强化学习(Reinforcement Learning from Human Feedback,RLHF)。
本文路线图如下:
- 训练原理:预训练 → SFT → 奖励模型 → RLHF,四步走完 ChatGPT 类模型的工业化流水线。
- 对齐动机:为什么「会说话」不等于「会办事」,仅靠预训练有哪些典型失败。
- 微调方法速览:Full FT、LoRA、QLoRA、RAG、Prompt 各适合什么场景。
- 本地实作:用 fine-tuning-playground 对 Qwen3.5-4B 做 QLoRA SFT,数据集为 bundled 的
ntnu_dataset.jsonl(约 1,252 条师大问答)。 - 讨论:预训练/SFT/RLHF 各解决什么、数据质量 vs 数量、何时微调 vs 改提示词、流畅是否等于正确。
读完本文你能做什么
- 解释 ChatGPT 类模型为何需要 SFT 与 RLHF,而不只是「数据越大越好」
- 识别 预训练模型当助手用时常见的失败模式
- 在单卡 GPU 上 跑通 fine-tuning-playground 的 QLoRA 训练与 base/finetuned 对比
- 判断 你的下一个项目该改 prompt、上 RAG,还是值得训一个 LoRA adapter
与前两篇系列的关系
AI 入门 建立了 函数视角 与 Transformer 位置;MNIST 实战 带你走过 损失函数、反向传播、epoch 与 train/test split。本文把同一套「用数据塑形行为」的思路搬到 十亿参数语言模型 上:预训练权重是起点,SFT 数据集是你给模型上的「专业课」。
大语言模型是如何被训练的
现代 ChatGPT 类助手,背后通常是一条多阶段训练流水线。OpenAI 在 InstructGPT 论文(Ouyang et al., 2022)中把这条路线讲得很清楚:先用海量文本做预训练,再用人类示范做 SFT,再用人类比较训练奖励模型,最后用强化学习把策略推向「人类更喜欢的回答」。Anthropic、Google、Meta 等厂商的 Claude、Gemini、LLaMA 系列产品在公开材料中同样强调 post-training 阶段的重要性——细节各异,但 「基座 + 对齐」 二分法已成为行业语言。下面按 InstructGPT 四步顺序展开,便于你对照任何一家厂商的技术博客阅读。
时间线:从 GPT 到「会聊天的 GPT」
2018 GPT-1 预训练 + 任务 fine-tune 范式确立
2019 GPT-2 更大模型、零样本能力引发关注
2020 GPT-3 少样本 prompting,仍主要是 base LM
2022 InstructGPT SFT + RLHF,小模型胜大 base
2022 ChatGPT 消费级 instruct 产品化
2023+ GPT-4 / 开源 LLaMA 2/3 / Qwen 对齐成标配,DPO 等简化 RLHF早期 GPT-3 已展现 in-context learning:在 prompt 里给几个例子,模型就能模仿任务格式。但 可靠性、安全性、助手人格 仍不足,直到 InstructGPT 系统化 人类反馈对齐 后,才出现今天熟悉的 ChatGPT 体验。理解这条时间线,你会明白:并非单靠某次架构突破,而是预训练与对齐数据工程层层叠加的结果。
先学语言:从海量文本中学会下一个词预测
预训练(Pretraining) 的目标可以一句话概括:给定已经出现的 token 序列,预测下一个 token 是什么。
形式化地,自回归语言模型在 token 序列 上优化:
每个位置都在问:「根据上文,下一个词最可能是什么?」模型通过数十亿次这样的预测,从数据里压缩出语法、常识、推理模式与各种文体。
数据从哪来
预训练语料通常包括:
- 网页文本(Common Crawl 等,经过去重与过滤)
- 书籍与论文(Books3、arXiv 等)
- 代码仓库(GitHub 公开代码,提升编程能力)
- 对话与论坛(比例因模型而异)
原始语料体积以 TB 级存储 计,训练前往往要经过 过滤 pipeline:去重(MinHash / exact dedup)、语言识别、质量分类器(剔除 spam、成人内容、乱码页)、PII 脱敏等。你下载的 开源 base 模型 已经完成了这一整套;个人 SFT 只需关心 千级 JSONL 是否干净。
GPT-3 使用了约 3000 亿 token 级别的数据;更大模型的数据量与算力继续 scaling。Qwen3.5 等 2025–2026 年的基座,预训练 token 数与多语言比例通常 高于 GPT-3 时代,但 对齐阶段的数据与标注 仍是产品差异化的核心。你不需要记住具体数字,只需建立直觉:预训练是在「模仿互联网上的写法」,而不是在「模仿客服手册里的答法」。
模型结构:Decoder-only Transformer
GPT、LLaMA、Qwen 等生成式 LLM 多采用 Decoder-only Transformer(仅解码器)。与前一篇 AI 入门中的 self-attention 一致:每个 token 通过**因果掩码(causal mask)**只能看见自己和之前的 token,从而支持从左到右逐 token 生成。
分词:文本如何变成 token
原始文本不会直接喂进神经网络,而是先经 分词器(Tokenizer) 切成 token。常见算法有 BPE(Byte Pair Encoding) 与 SentencePiece。中文往往一个字或多个字对应一个 token;英文常见子词切分。词表大小通常在 32K–128K 之间。
分词影响训练效率与「一个汉字算几个 token」的成本。做本地微调时,max_seq_length 限制的就是 token 数,不是字符数。
例子:「国立台湾师范大学」在 Qwen 分词下可能是 4–8 个 token 不等。一条 512 汉字的中文回答,可能占用 700–900 token。设置 max_seq_length=2048 时,绝大多数师大 QA 不会截断;若你加入超长招生简章式回答,才需要提高上限或截断数据。
预训练在学什么、没学什么
预训练 倾向于:
- 常见事实与共现统计(「台北」后面常跟「市」)
- 多种文体(新闻、论坛、代码注释)
- 多语言混合(取决于语料比例)
预训练 不保证:
- 听用户指令(除非语料里对话格式足够多)
- 拒绝 harmful 请求
- 对特定机构(如某校某系)有准确、最新的结构化知识
- 统一「助手」口吻
Temperature 与 sampling 影响的是 推理阶段 随机性,不能替代对齐。高 temperature 的 base 模型只会 更创意地胡说;instruct 模型则在 对齐行为 基础上调节多样性。微调改变的是 条件分布 本身,而不只是采样噪声。
因此,ChatGPT 的体验 = 预训练能力 + 对齐后的行为。你本地微调,是在 对齐链路的最后一环 再加一层 领域 specialization。
预训练与算力:数量级直觉
Kaplan、Hoffmann 等人的 Scaling Laws 表明:在足够大的数据与算力下,参数量、数据量、计算量与模型 loss 之间存在可预测的幂律关系——更大通常更强,但边际收益递减。Chinchilla 等工作进一步指出:给定固定算力,模型大小与训练 token 数应配平,许多早期模型其实 训得不够 token 或 参数量过大。这些结论指导工业界在预训练阶段 烧算力的方式;对个人而言,只需记住:我们站在巨人肩膀上,用 LoRA 改行为,而不是重新烧预训练。
训练 GPT-4 级别模型需要数千张 GPU、数月时间与数千万美元量级成本,这是工业界与学术实验室的分水岭。

对个人开发者而言,预训练不现实;在已有基座模型上做 SFT / LoRA 才是可行路径——也正是本文后半部分要做的事。
再学示范:人类训练师写出「好答案」,模型模仿
预训练模型已经「会语言」,但用户要的是 instruction-following(遵循指令):你问它问题,它答你,而不是接着你的句子写下去。ChatGPT 界面里的 多轮对话,在训练数据里被显式构造成 user/assistant 角色;模型因此学会 在合适的位置停下,而不是无限续写——这也是 SFT 与 raw completion 的关键差异之一。
监督微调(SFT) 的做法是:收集大量 (用户问题, 理想回答) 对,让人类训练师(或高质量标注流程)写出「好答案」,然后继续用交叉熵损失训练模型,让它模仿这些示范。
损失怎么算
在 ChatML 等多轮格式里,一条样本常包含 user 与 assistant 消息。SFT 通常 只在 assistant 回复的 token 上计算 loss,user 部分 mask 掉——因为我们要学的是「怎么答」,不是「怎么问」。
InstructGPT 与 ChatGPT 的启示
OpenAI 的 InstructGPT 论文展示了一个反直觉的结果:1.3B 参数的 InstructGPT 在人类评估中优于 175B 的 GPT-3 base。参数少两个数量级,但因为做了 SFT + RLHF,更对齐人类意图。这说明:对齐有时比 raw scale 更重要(至少在「当助手」这个任务上)。
对 企业落地 的启示是:不必盲目追逐最大 base 模型;在 7B–13B instruct 模型 + 领域 LoRA 上,很多垂直场景(校内问答、内部规章、客服话术)已能达到可用质量,且 推理成本 远低于调用 frontier API。本文 4B QLoRA 更是 消费级 GPU 可复现 的下限参考——先在小模型上验证数据与 eval,再考虑放大模型或上云训练。
数据格式:ChatML 与 Alpaca
工业界与开源社区常见格式:
| 格式 | 结构 | 典型用途 |
|---|---|---|
| ChatML | messages: [{role, content}, ...] | Qwen、OpenAI 兼容 API |
| Alpaca | instruction + input + output | 指令微调数据集(如 Dolly) |
| 纯 text | 已渲染好的单字符串 | 自定义模板 |
fine-tuning-playground 默认 ChatML,与 Qwen 原生模板一致。
SFT 数据从哪来
工业界 SFT 数据来源包括:
- 人工撰写:质量最高,成本最高(InstructGPT 雇佣标注员)
- 现有产品日志:真实用户 query + 人工修正的 model 输出(需注意隐私)
- 合成数据:用 GPT-4 等强模型生成 QA,人工抽检(Alpaca、Self-Instruct 路线)
- 开源数据集:Dolly、ShareGPT、领域 wiki 问答等
本文 ntnu_dataset.jsonl 属于 结构化事实 + 模板化 paraphrase 的合成路线:保证实体一致性与问法多样性,适合教学。生产环境还应加入 人工审核 与 时效性维护(院系改名、排名年份更新等)。
Chat Template 与训练文本长什么样
Qwen 的 chat template 会把 messages 渲染成带特殊 token 的字符串,例如概念上类似:
<|im_start|>user
請簡單介紹國立臺灣師範大學。
<|im_start|>assistant
國立臺灣師範大學,簡稱臺師大……SFTTrainer 读入的是渲染后的 整段 text,模型做 causal LM:预测每个 token,但 loss mask 确保 不惩罚 user 段上的预测误差(由 TRL / template 内部处理)。你在 inference.py 里用同一 tokenizer 的 apply_chat_template(..., add_generation_prompt=True),才能保证 训练与推理格式一致——这是微调最容易踩的坑之一。
再学偏好:让人类比较多个答案,训练奖励模型
SFT 教模型「示范长什么样」,但示范无法覆盖所有情况。同一个问题,可以有很多「语法正确、内容相关」的回答,哪一个更好?更简洁?更诚实?更安全?
奖励模型(Reward Model,RM) 学习的是:给 (prompt, response) 打一个标量分数 ,分数越高表示人类越偏好该回答。
训练数据来自 人类比较:标注员看到同一 prompt 下的多个模型输出,进行排序或 pairwise 选择(A 比 B 好)。常用 Bradley-Terry 模型建模偏好概率:
其中 是胜出(winning)回答, 是落败(losing)回答, 是 sigmoid。
RM 通常 与策略模型共享 Transformer backbone,把语言建模头换成 标量输出头。初始化常来自 SFT checkpoint,以便理解「什么样的文本像助手回复」。
标注界面长什么样
在 InstructGPT 流程中,标注员看到 同一用户问题 与 多个模型生成的回答(可能来自不同 checkpoint 或不同 sampling 温度)。任务不是写新答案,而是 比较哪个更好——有时允许并列。这些比较构成 稀疏但高信息密度 的监督:每条标注同时约束两个回答的相对排序。
奖励模型训练完成后,不会直接给用户用;它只在 RL 阶段当 打分器。若 RM 有偏见(例如偏好更长回答),RL 后的策略也会继承该偏见——这是 RLHF 需要持续 eval 与 RM 迭代 的原因。
再做强化学习:让模型更倾向产生人类喜欢的回答
有了 RM,就可以把它当作 强化学习中的 reward 信号,进一步微调 策略模型(policy)——也就是最终给用户生成文本的那个 LLM。
RLHF 常用 PPO(Proximal Policy Optimization):
- 从当前策略 对 prompt 采样回答
- 用 RM 计算 reward
- 用 PPO 更新 ,使高 reward 回答的概率上升
- 加入 KL 惩罚,限制策略不要偏离 SFT 模型太远——避免「reward hacking」(钻 RM 空子)或语言能力崩溃
KL 项的直觉:RM 只是人类偏好的 近似,不完美。若 RL 阶段让策略跑太远,可能学会 讨好 RM 但语义崩坏(例如重复高分短语)。KL 惩罚 把策略拴在 SFT 附近,在对齐与能力之间折中。
PPO 本身还有 clip 机制限制单步更新幅度,避免 reward 噪声导致训练发散。完整 RLHF 工程涉及 reward model ensemble、在线数据刷新、安全过滤器 等,远超个人项目范畴;理解「RM 打分 → 策略梯度 → KL 约束」这条主线即可。
Alignment Tax 与 RLHF 的替代
对齐不免费。Alignment Tax(对齐税) 指:强对齐有时会在某些 raw benchmark(如纯知识问答、代码题)上略微牺牲分数,换取更好的指令遵循与安全性。是否接受这种 trade-off,取决于产品目标。
工业界也在探索 DPO(Direct Preference Optimization)、ORPO、RLAIF(AI 反馈替代人类) 等,跳过显式 RM + PPO,降低 pipeline 复杂度。ChatGPT 的具体实现未公开,但公开论文与开源生态(LLaMA-2、Mistral 等)都指向 SFT + 偏好优化 已是标配。
ChatGPT 训练流水线全景(小结)
| 阶段 | 数据 | 目标 | 产出 | 典型成本 |
|---|---|---|---|---|
| 预训练 | 万亿 token 级网页/书/代码 | 下一个词预测 | Base LM | 极高(集群 × 月) |
| SFT | 万–百万级人工示范 | 模仿好答案 | Instruct 模型 | 高(标注 + GPU) |
| RM | 人类排序/比较 | 预测偏好 | Reward Model | 高(标注) |
| RLHF | RM 提供 reward | 优化策略 | 对齐助手 | 中高(RL 不稳定) |
对你我这样的个人开发者:完整 RLHF 门槛很高;但 SFT / LoRA / QLoRA 在单卡 GPU 上完全可行,且能解决大量「领域知识 + 固定答法」需求——下文实作章节即属此类。
工业界变体简述
| 变体 | 要点 |
|---|---|
| RLAIF | 用强模型代替人类做偏好标注,降低成本 |
| Constitutional AI | 用原则性文本指导 self-critique 与修订(Anthropic) |
| DPO / ORPO | 直接用偏好对优化策略,省略显式 RM + PPO |
| Continued Pretraining | 在领域语料上继续预训练,再 SFT——适合专业术语极多的领域(法律、医学) |
ChatGPT 的确切配方未公开,但 「base → instruct → preference optimization」 已是 2023 年后开源与闭源产品的共识路径。你本地做的 NTNU SFT,相当于这条链路上的 instruct 阶段的一个子集。
为什么只靠预训练不够
把预训练模型直接当聊天机器人用,往往会遇到一类系统性问题:它很会「接着写」,但不一定会「照着办」。
「会说话,但不一定会办事」
预训练的目标函数是 语言建模,不是 任务完成。模型学到的是:「这段文字后面通常接什么」。当你输入「请用三句话介绍台湾师范大学」,预训练倾向可能包括:
- 续写成招生简章体例的长文
- 混入训练语料里常见的模板句
- 用 Wikipedia 口吻客观陈述,而非对话式回答
SFT 明确教它:看到 user 消息,应生成 assistant 角色的、针对问题的回复。RLHF 进一步教它:在多种合法回复里,人类更偏哪一种风格与长度。
典型失败模式
在不做对齐的情况下,常见表现包括:
| 问题 | 表现 |
|---|---|
| 答非所问 | 解释概念而不是执行指令(「写代码」→ 讲编程史) |
| 冗长 | 无法收敛到用户要的篇幅 |
| 语气不稳定 | 同一会话里 formal / 口语 / 角色扮演 混用 |
| 幻觉 | 流畅但错误的事实(「师大有五个校区」) |
| 缺少助手人格 | 不像「帮你办事」,像「随机抽一段网页」 |
越狱(jailbreak) 类 prompt 试图让模型 忽略安全策略(例如「假装你是 DAN」)。对齐模型在 RL 数据里见过大量 拒答示范,但仍可能被 novel attack 突破——这是 持续红队 + 更新对齐数据 的原因。个人微调若 不加安全样本,可能让模型 更愿意照单全收 用户指令,部署到公网前务必评估。
这些不全是「模型笨」,而是 训练目标与用户期望不一致。
一个具体的「补全 vs 问答」例子
假设用户输入:
用户:台湾师范大学有几个校区?请简要说明。未经对齐的 base 模型 可能续写为:
……该校办学规模庞大,在国内外享有盛誉。以下介绍其历史背景:国立台湾师范大学的前身可追溯到 1922 年……它把输入当成 文章开头,继续写「百科体」长文,甚至 不先回答「几个校区」。
经 SFT 的 instruct 模型 更可能直接:
台湾师范大学共有三个校区:和平校区(校本部)、公馆校区、林口校区。其中……这就是 任务格式对齐 的价值:同样的知识可能存在于预训练权重里,但 输出行为 需要对齐数据来激活。
幻觉与「流畅的错误」
预训练模型在 不确定 时仍会采样出 plausible 文本——语法正确、语气连贯,但 事实错误。这在开放域尤其危险:用户会把 confident tone 误判为 reliable。SFT 可以通过示范 「不知道就说不知道」 来部分缓解;RLHF 可以 penalize 胡编。但 没有任何阶段保证事实 100% 正确,这就是为什么 RAG、工具调用与人工审核在产品里仍重要。
对齐(Alignment)是什么
对齐指让模型行为符合 人类意图与价值观。OpenAI 常用 HHH 框架概括助手目标:
- Helpful(有帮助):真正解决用户问题
- Honest(诚实):不编造,不确定时说明
- Harmless(无害):拒绝有害请求,减少滥用
SFT 主要解决 格式与任务类型(怎么像助手一样说话);RLHF / 偏好优化主要解决 在多种合法回答里选更好(更简洁、更安全、更讨喜)。两者缺一不可地构成了 ChatGPT 类产品与 raw base model 的体验差距。
开源 instruct 模型已经做了哪几步
当你下载 Qwen3.5-4B-Instruct 时,厂商通常 已做过大规模 SFT,部分还有 RLHF/DPO。你在其上做 NTNU LoRA,属于 第三次 specialization:
Qwen 预训练 → Qwen Instruct 对齐 → 你的 NTNU LoRA若从 非 instruct 的 base 训练,你等于 自己承担更多格式对齐工作;数据里就要包含 更多「怎么答」的示范,而不只是 raw 事实。教学仓库允许两种起点;建议初学者 优先 instruct 基座 + 领域 JSONL。
补充:越狱与对齐的猫鼠游戏
对齐也在 对抗性使用 下持续演进:用户通过 jailbreak prompt 试图绕过安全策略。这说明对齐不是一次训练就永久完成,而是 数据、策略、评估迭代 的长期工程。个人做领域 SFT 时虽不涉及完整安全栈,但应意识到:微调会改变模型行为边界,数据集里有什么语气与内容,模型就会倾向什么。
微调方法速览——Full FT、LoRA 与 QLoRA
在进入本地实作之前,先把「有哪些微调手段」摆清楚。个人开发者几乎总是在 已有基座模型 上动手,而不是从零预训练。
基座模型从哪来
本文实作使用 Qwen/Qwen3.5-4B——阿里巴巴 Qwen 团队发布的开源权重,已在万亿级 token 上预训练,并通常附带 基础 instruct 版本(如 Qwen3.5-4B-Instruct)。fine-tuning-playground 默认从 base 或 instruct checkpoint 加载后再加 LoRA;在已有 instruct 模型上继续 SFT 往往 收敛更快,因为模型已经「像助手」了,你的数据只需 注入领域事实。若从纯 base 开始,则需要更多 epoch 或数据来同时学格式与知识。
LoRA 的 target_modules 怎么选
Qwen 类 decoder 中,注意力层 q_proj/k_proj/v_proj/o_proj 负责 上下文混合;MLP 层 gate_proj/up_proj/down_proj 负责 特征变换。fine-tuning-playground 默认 七层全开,在 4B 上取得较好适配;若 OOM,可只训 attention 四层,牺牲部分表达能力换内存。rank r=16、alpha=32(alpha 约为 2r)是社区常见起点:r 越大,可训练容量越大,也越容易过拟合小数据集。
Full Fine-tuning 全参数微调
Full Fine-tuning 更新模型的 全部权重。优点是能最大程度适应新任务;缺点是:
- 显存:4B 模型全参数 + 优化器状态,常需 24GB+ VRAM
- 灾难性遗忘(Catastrophic Forgetting):在小数据集上全参微调,可能损害通用能力
- 存储:每个任务一份完整模型副本,体积以 GB 计
适合有充足算力、数据量大(万级以上高质量样本)、且需要深度改造模型的团队。
LoRA:低秩适配器
LoRA(Low-Rank Adaptation)(Hu et al., 2021)冻结基座权重 ,只训练低秩分解 ,其中 ,,。
推理时:,或把 adapter 合并进权重。可训练参数通常只占 0.1%–1%,却能在许多任务上接近全参效果。
QLoRA:在消费级 GPU 上训 4B 模型
QLoRA(Dettmers et al., 2023)把基座权重量化为 4-bit NF4,在 GPU 上反量化计算;LoRA adapter 仍用 bf16/fp16 训练。这使得 6–8 GB VRAM 即可微调 4B 级模型——RTX 3060 / 4060 / 4070 都能跑。
fine-tuning-playground 默认 QLoRA + 7 个线性层 LoRA target(Q/K/V/O 与 MLP 的 gate/up/down),在 4B 规模上兼顾效果与内存。
SFT、RLHF、RAG、Prompt 怎么选
| 方法 | 改什么 | 成本 | 适合 |
|---|---|---|---|
| Prompt Engineering | 不改权重,改输入 | 最低 | 快速验证、通用任务、少样本 |
| RAG | 检索外部知识再生成 | 中(索引 + 推理) | 知识常更新、需引用来源 |
| SFT / LoRA | 改(部分)权重 | 中(GPU + 数据) | 固定领域、固定格式、离线部署 |
| RLHF / DPO | 偏好优化 | 高 | 产品级助手、安全与风格 |
过拟合 是 SFT 最常见坑:训练 loss 下降、eval loss 上升,模型「背答案」但不会泛化到新问法。缓解手段包括:更少 epoch、更大 test_split、数据增强问法、LoRA rank 不要过大。
学习率与 epoch:小数据集(如 1.2K)常用 lr 、epoch 2–3;数据量到 30K+ 时往往 减少 epoch 防过拟合(fine-tuning-playground README 有表格)。
灾难性遗忘与混合数据
在小数据集上 全参微调 容易 灾难性遗忘:模型学会师大 FAQ,却变笨了算术或英文。LoRA 因 大部分权重冻结,遗忘风险 显著低于 full FT,但并非为零——若 lr 过大、epoch 过多,仍可能损害通用能力。缓解:降低 lr、减少 epoch、在数据里 掺 5–10% 通用 instruct 样本(alpaca 子集)做 混合训练。fine-tuning-playground 未默认混合,但生产环境常见。
量化感知:推理时怎么加载 adapter
训练保存的是 LoRA adapter;推理时 inference.py 用 PeftModel.from_pretrained(base, adapter_path) 合并逻辑加载。--load_in_4bit True 与训练一致可省 VRAM。若要把 adapter 合并进全量权重 导出单文件,可用 PEFT 的 merge_and_unload()——便于部署到 不支持 PEFT 的运行时,但失去「一个小 adapter 多任务切换」的灵活性。
本地 SFT 实作——fine-tuning-playground
理论讲完,下面 动手。我们使用作者维护的教学仓库 fine-tuning-playground:单文件 src/train.py、CLI 驱动、内置 ntnu_dataset.jsonl(约 1,252 条国立台湾师范大学 ChatML 问答),目标是在本地让 Qwen3.5-4B 更可靠地回答师大相关问题。
整个实作 不修改 基座权重文件本身;训练产物是 LoRA adapter 目录,可随时删除重训,风险可控。这也是个人玩微调相比 full FT 的 另一大优点:实验迭代快,磁盘占用小。
仓库另有
data/taiwan/universities.jsonl、districts.jsonl、geography.jsonl等扩展集;更换--dataset_path即可复用同一 pipeline。本文聚焦 bundled 师大集,降低首次上手复杂度。
项目概览
技术栈:
| 包 | 作用 |
|---|---|
transformers | 加载 Qwen3 / Qwen3.5、分词器 |
peft | LoRA / QLoRA 配置 |
trl | SFTTrainer 监督微调 |
bitsandbytes | 4-bit 量化 |
datasets | 加载 JSONL |
硬件参考(QLoRA 4B):
| 配置 | 最低 VRAM | 典型 GPU |
|---|---|---|
| batch 1–2 | ~6–8 GB | RTX 3060 / 4060 / 4070 |
| batch 2, seq 2048 | ~12 GB | RTX 3060 12GB / 4070 |
无 CUDA 时会 自动降级 CPU + float32,仅适合 smoke test,4B 全精度极慢。
数据集:ntnu_dataset.jsonl
每条记录是一个 JSON 对象,含 messages 数组(ChatML)。示例(繁体原文与仓库一致):
{
"messages": [
{"role": "user", "content": "請簡單介紹國立臺灣師範大學。"},
{"role": "assistant", "content": "國立臺灣師範大學,簡稱臺師大、師大或 NTNU,是臺灣第一所師範大學……"}
]
}英文问法同样存在,例如 "What is National Taiwan Normal University?",有助于模型 双语回答 同一实体。
数据主题覆盖:历史沿革、三校区(和平、公馆、林口)、九大学院、国语教学中心(MTC)、国际排名、交通地址、知名校友等。问法多样,避免模型只记住单一模板。部分回答含 排名年份、QS/THE 分数 等时变信息——部署到生产前应 核对时效;教学实验则重在观察 格式与实体是否对齐数据,而非排名数字是否最新。
构造流程(仓库 data/ 下脚本):结构化事实 → 多模板 paraphrase 问法 → 合并为 JSONL → generate_ntnu_dataset.py 可聚合子目录。教学时可直接用 bundled 文件,不必自己标注 1,252 条。
数据集统计与划分
约 1,252 条记录中,问法涵盖 中文简繁、英文、简称(师大、NTNU)、细节追问(地址、排名、学院) 等。train.py 默认 test_split=0.05、seed=42,即约 63 条 eval、1,189 条 train。Trainer 在 eval loss 最优时 load_best_model_at_end,避免最后一轮过拟合。
你可以用下面命令快速统计本地 JSONL 行数:
wc -l data/ntnu_dataset.jsonl
python -c "import json; print(sum(1 for _ in open('data/ntnu_dataset.jsonl',encoding='utf-8')))"为何选「台湾师范大学」作教学主题
师大实体 边界清晰(一所学校、三校区、公开信息多),适合验证微调是否 注入结构化知识。同一 pipeline 可换成你关心的 内部文档 QA、产品手册、API 说明——关键是 问答对质量与覆盖面,而非主题本身。
环境安装与 GPU 验证
Python 3.11 或 3.12 推荐(CUDA wheel 兼容性好)。
git clone https://github.com/cw1997/fine-tuning-playground.git
cd fine-tuning-playground
conda create -n finetune python=3.11 -y
conda activate finetune
pip install -r requirements.txtWindows 可用 PowerShell:powershell -File scripts/install_deps.ps1;Git Bash 与 Linux 相同。
验证 GPU:
python -c "import torch; print(torch.cuda.is_available(), torch.version.cuda)"应输出 True 与 CUDA 版本号。若为 False,检查驱动与 PyTorch CUDA 构建是否匹配。
Windows 与 Linux 差异
- Git Bash / WSL / Linux:直接运行
bash scripts/train_preset.sh - PowerShell:使用
train_preset.ps1;环境变量用$env:DATASET_PATH=... - 路径:
dataset_path本地路径需以./或/开头,否则会被当作 Hugging Face Hub 数据集名
首次安装 bitsandbytes 在 Windows 上偶有问题;仓库 README 建议 Python 3.11 + CUDA cu128 wheel。若 4-bit 加载失败,可暂时 --load_in_4bit False 并 --device cpu 做逻辑验证(勿用于完整 4B 训练)。
训练:从 smoke test 到完整 run
第一步:Smoke test(1 epoch,确认 pipeline 通)
bash scripts/train_preset.sh smoke-4bWindows PowerShell:
powershell -File scripts/train_preset.ps1 -Preset smoke-4b第二步:完整训练(12 GB GPU + 4B + 默认师大集,3 epoch)
bash scripts/train_preset.sh gpu-12gb-4b等价手动命令:
python src/train.py \
--model_id Qwen/Qwen3.5-4B \
--dataset_path ./data/ntnu_dataset.jsonl \
--device gpu \
--load_in_4bit True \
--torch_dtype bfloat16 \
--max_seq_length 2048 \
--num_epochs 3 \
--per_device_batch_size 2 \
--gradient_accum_steps 8 \
--learning_rate 2e-4 \
--lora_r 16 --lora_alpha 32 \
--lora_dropout 0.05 \
--warmup_ratio 0.03 \
--test_split 0.05 \
--logging_steps 10 \
--save_steps 200 \
--output_dir ./models/ntnu/gpu-12gb-4b关键参数解读
| 参数 | 含义 | 调参提示 |
|---|---|---|
model_id | Hugging Face 模型名 | 推理时必须与训练一致 |
load_in_4bit | QLoRA 量化 | OOM 时先降 max_seq_length |
lora_r / lora_alpha | LoRA 秩与缩放 | 小数据 r=16 常用;大数据可试 32 |
learning_rate | 峰值学习率 | 1.2K 样本默认 2e-4 |
test_split | 验证集比例 | 0.05 → 按 eval_loss 存 best checkpoint |
gradient_accum_steps | 梯度累积 | 有效 batch = batch_size × accum |
有效 batch size 预设约为 16(如 batch 2 × accum 8),适合小数据集稳定训练。
train.py 流水线(8 步)
阅读 src/train.py 时可按此顺序对照:
- fix_ssl_certificates — 修复部分环境 HF 下载证书问题
- parse_args — 解析 CLI
- resolve_device — 自动 GPU/CPU,CPU 时关 4-bit
- load_tokenizer — Qwen 分词器
- load_base_model — 可选 4-bit 加载基座
- get_peft_model — 注入 LoRA adapter
- load_training_datasets — JSONL → chat template →
text字段;可选 train/test split - SFTTrainer.train / save — 训练并保存 adapter 到
output_dir
核心 LoRA 与 Trainer 配置如下(摘自仓库,略有删节):
model = get_peft_model(
model,
LoraConfig(
r=args.lora_r,
lora_alpha=args.lora_alpha,
lora_dropout=args.lora_dropout,
target_modules=target_modules,
bias="none",
task_type="CAUSAL_LM",
),
)
trainer = SFTTrainer(
model=model,
processing_class=tokenizer,
args=SFTConfig(
output_dir=args.output_dir,
num_train_epochs=args.num_epochs,
learning_rate=args.learning_rate,
gradient_checkpointing=True,
load_best_model_at_end=eval_dataset is not None,
metric_for_best_model="eval_loss",
dataset_text_field="text",
max_length=args.max_seq_length,
),
train_dataset=train_dataset,
eval_dataset=eval_dataset,
)
trainer.train()
trainer.save_model(args.output_dir)load_training_datasets 中对 ChatML 的处理:每条 messages 经 tokenizer.apply_chat_template(..., tokenize=False) 转成单一字符串,供 SFTTrainer 做 causal LM loss。
gradient_checkpointing 与 dataloader
train.py 默认 gradient_checkpointing=True:用 重算激活 换 更低显存,训练会略慢但 4B QLoRA 在 8GB 卡上更稳。Windows 上 dataloader_num_workers=0 避免多进程 spawn 问题;Linux 可用 2 workers 略提速。
若你修改 dataset_format=alpaca,需保证 JSON 含 instruction/output 字段;text 格式则适合 已渲染好的 多轮字符串。师大实验 stick to chat 即可。
训练完成后,output_dir 内主要是 LoRA adapter 权重(体积通常远小于完整模型),以及 tokenizer 配置。
训练时间预期
在 RTX 4070 12GB 量级 GPU 上,1,252 样本 × 3 epoch、seq 2048、有效 batch 16,完整 run 往往 在 数十分钟到一两小时 之间,取决于 GPU 型号、磁盘与是否首次下载模型。smoke-4b(1 epoch)通常在 十分钟左右 可完成,适合验证环境。
日志中关注:
Train examples: 1189, eval: 63
{'loss': 1.85, 'learning_rate': ..., 'epoch': 0.12}
...
{'eval_loss': 1.42, ...}train_loss 与 eval_loss 同步下降 通常是健康信号;若 train 继续降而 eval 回升,考虑 提前停止 或 减少 epoch。
推理与微调前后对比
微调前(基座模型):
python src/inference.py --mode base --model_id Qwen/Qwen3.5-4B \
--prompt "台灣師範大學的地址是什麼" --no_interactive微调后(加载 adapter):
python src/inference.py --mode finetuned --model_id Qwen/Qwen3.5-4B \
--adapter_path ./models/ntnu/gpu-12gb-4b \
--prompt "台灣師範大學的地址是什麼" --no_interactive并排对比:
python src/inference.py --mode compare --model_id Qwen/Qwen3.5-4B \
--adapter_path ./models/ntnu/gpu-12gb-4b \
--prompt "請簡單介紹國立臺灣師範大學" --no_interactive预期现象:基座模型可能对「师大」实体 泛化不足或幻觉地址;微调后更倾向输出数据集中常见的 和平东路一段 162 号、三校区、MTC 等结构化事实。这不是「模型变聪明了」,而是 行为被领域数据塑形。
省略 --no_interactive 时进入 交互循环,可持续提问测试;--use_thinking 可启用 Qwen3 思考链模板(本数据集默认关闭)。
推送 adapter 到 Hugging Face Hub(可选)
若你训练出满意的 LoRA,可用:
python src/train.py \
--dataset_path ./data/ntnu_dataset.jsonl \
--output_dir ./models/ntnu/my-run \
--push_to_hub True \
--hub_model_id your-username/qwen-ntnu-lora需要先 huggingface-cli login。上传的是 adapter + tokenizer 配置,使用者仍需基座 Qwen/Qwen3.5-4B 加载合并。这与 全量模型开源 不同,但 分享成本低、下载快,适合课程作业或团队内共享实验。
扩展数据集:从师大到更多台湾问答
仓库 data/generate_ntnu_dataset.py 可聚合 data/ntnu/ 与 data/taiwan/ 下多份 JSONL(大学、行政区、地理等)。更换训练路径示例:
python src/train.py \
--model_id Qwen/Qwen3.5-4B \
--dataset_path ./data/taiwan/universities.jsonl \
--output_dir ./models/tw-universities \
--device gpu或指向整个目录递归加载所有 .jsonl。本文聚焦 ntnu_dataset.jsonl 以保持实验 可复现、易评估;你掌握 pipeline 后,换数据即是 同一套代码、不同领域 specialization。
常见问题与调参建议
CUDA OOM
- 降低
--max_seq_length(2048 → 1536 → 1024) --per_device_batch_size 1,增大gradient_accum_steps保持有效 batch--target_modules q_proj,k_proj,v_proj,o_proj(仅 attention 层 LoRA)
过拟合
- 减少
--num_epochs - 增大
--test_split(如 0.10) - 监控 TensorBoard 或日志中的
eval_loss
数据集规模指引(README 摘要)
| 样本量 | Epoch | LR | 备注 |
|---|---|---|---|
| < 500 | 3–5 | 1e-4 | 过拟合风险高 |
| ~1.2K(师大集) | 3 | 2e-4 | 预设默认值 |
| 5K–30K | 2–3 | 1.5e-4–2e-4 | 可试 lora_r=32 |
| 30K+ | 1–2 | 1.5e-4 | 避免过多 epoch |
Windows 若显存碎片导致 OOM,可设:
export PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True实作检查清单
在宣称「微调成功」之前,建议逐项确认:
-
torch.cuda.is_available()为 True(GPU 训练) - smoke test 无报错跑完 1 epoch
-
output_dir内存在 adapter 权重(非空目录) -
inference.py --mode compare在 至少 5 个 held-out 问法 上优于 base - 模型 没有 在所有问题上都复读同一段模板(过拟合信号)
- 英文与中文问法都能触发合理回答(若数据双语)
若 eval_loss 最低点的 checkpoint 不在最后一轮,确认 load_best_model_at_end=True 已生效;推理时使用 该 checkpoint 对应目录 或 trainer 自动加载的 best 权重,避免 用最后一轮过拟合权重 做 demo。完整训练日志可重定向到文件便于事后排查:bash scripts/train_preset.sh gpu-12gb-4b 2>&1 | tee train.log。
讨论——微调的智慧
走完原理与实作,回到更 general 的问题:什么时候值得微调?数据越多越好吗?「更像人」是否「更正确」?
预训练、SFT、RLHF 各自解决什么问题
可以用 学生成长 类比(仅为直觉,非严格对应):
| 阶段 | 类比 | 模型层面 |
|---|---|---|
| 预训练 | 读大量书籍与网页 | 学会语言、事实片段、代码、文体 |
| SFT | 做习题并对照标准答案 | 学会「用户问 → 助手答」格式与任务类型 |
| RM | 老师比较两份作文孰优 | 学会什么是「更好」的回答 |
| RLHF | 根据评分调整写作习惯 | 在多种合法回答中偏向高 reward |
预训练解决 「知不知道怎么说」;SFT 解决 「听不听得懂指令、会不会按示范答」;RLHF 解决 「在都对的情况下哪个更讨人喜欢、更安全」。
个人领域微调(如本文 NTNU)通常 只做 SFT 已足够——因为你主要注入 事实与固定叙述风格,而非重塑全局偏好。产品级 ChatGPT 则四段齐全。
能力栈:四层叠加而非替换
可以把四层看成 叠加 而非 互相取代:
RLHF 偏好层 ← 哪种答法更好、更安全
SFT 任务层 ← 怎么像助手一样答
预训练知识层 ← 语言与广泛事实
(可选)RAG 外挂 ← 动态、可引用的事实本地 NTNU 实验动的是 SFT 任务层 + 部分知识层(师大事实)。若师大招生简章 每年更新,仅靠 SFT 权重无法自动更新——应 重训数据 或 RAG 接官网。
为什么「多数据」不一定比「好数据」更有效
机器学习老话:Garbage in, garbage out。微调尤其敏感:
- 1,252 条 人工 curated 的师大 QA,往往优于 1 万条 爬虫噪声(错误地址、过时院系、重复模板)
- 多样性 重要:同一事实多种问法(中文/英文、简称/全称)比重复同一问句 100 遍更有泛化价值
- 去重与矛盾检测:数据里若「三校区」与「五校区」并存,模型会学到混乱分布
InstructGPT 论文也强调:标注质量与标注者培训 是对齐的关键成本。开源社区常见失败案例:用低质 Alpaca 翻译数据 SFT,模型 格式像助手、内容胡编——量很大,但「好」不足。
实践建议:
- 先 100–200 条金标准 做 pilot,肉眼看生成
- 再扩到 1K+,覆盖主要实体与问法类型
- 留 held-out 测试集(训练时未见过的问法)做人工 eval
反例:把同一 FAQ 复制粘贴 5000 次只能让 loss 降得「很快」,模型却 不会 因此更会回答新问法——它只是记住了 重复模式的统计。好数据的核心是 覆盖 + 正确 + 多样,而不是单纯堆行数。
什么情况下应该做微调,什么情况下只改提示词就够了
优先 Prompt Engineering 当:
- 任务用 通用知识 即可(总结、翻译、头脑风暴)
- 需要 快速迭代,不想每次改数据就重训
- 使用 闭源 API,无法改权重
- 有 少样本示例 可放进 context(few-shot)
Prompt 工程的成本在于 长 system prompt 占用 context 窗口、每次推理重复发送、以及 不同模型对 prompt 敏感度不同。当 prompt 长到数千 token 仍无法稳定输出格式时,就该认真考虑 SFT 把格式 bake 进权重。
值得 SFT / LoRA 当:
- 需要 稳定格式(JSON、固定报告模板、客服话术)
- 领域知识 不在基座训练分布或常被幻觉(校内规章、内部 API 文档风格)
- 离线部署 小模型,不能每次带 10K token 的 system prompt
- 延迟与成本:把知识 bake 进权重,推理时 prompt 更短
值得 RAG 当:
- 知识 频繁更新(股价、规章版本、新闻)
- 需要 引用来源 可核查
- 数据以 文档库 形式存在,而非 QA 对
三者 可组合:RAG 检索 + 小模型 SFT 学「怎么根据检索结果回答」是常见企业架构。
决策清单(可直接自问)
- 知识是否 静态 且 量有限(< 几万 token)?→ 考虑 SFT bake-in
- 知识是否 每周变?→ 优先 RAG
- 是否 只用 API、不能训?→ Prompt + RAG
- 是否要 7B 以下小模型离线跑?→ SFT 减 prompt 长度、降延迟
- 是否要 统一客服口吻 且 拒答规则固定?→ SFT 示范 + 可选 RLHF/DPO
成本粗算:一次 4B QLoRA 完整 run 电费加折旧通常 可忽略于个人实验;人力成本主要在 数据整理与 eval。相比之下, frontier API 按 token 计费,在 高 QPS、长 prompt 场景下,小模型 + LoRA 部署可能在 数月内回本——但前提是你的任务 不需要 frontier 级推理,且 维护数据与模型版本 的成本可接受。
没有银弹;很多团队 先 prompt 原型 → RAG 接文档 → 最后 LoRA 固化高频场景。
模型回答「更像人」一定代表「更正确」吗
不一定。 RLHF 优化的是 人类偏好,不是 客观真值。
典型现象:
- Sycophancy(谄媚):模型倾向同意用户,即使用户错了
- 流畅幻觉:语气自信、结构完整,但事实错误
- 长度偏好:标注员常偏好「看起来努力」的长回答,RL 可能 reinforce 冗长
评估应 双轨:
- Preference / 有用性 — 人类或 GPT-4-as-judge 打分
- Factuality — 对结构化 QA(如师大地址)做 精确匹配或实体 F1;对开放域做检索验证
本文 NTNU 实验里,微调提升的是 与数据集一致的事实复述,不是 general reasoning。若数据集本身有错,模型会 更坚定地错——这是 SFT 的风险,再次说明 好数据 优先于 多数据。
DPO:不用 PPO 也能做偏好优化
DPO(Direct Preference Optimization) 把 RLHF 里的 RM + PPO 简化为 在偏好对 上直接优化策略,隐式对应某个最优 reward。优点:实现简单、训练更稳定;缺点:仍依赖高质量偏好数据。Meta LLaMA 2/3、许多开源对齐模型采用 SFT + DPO 组合。作为读者,你应知道 RLHF 不是唯一对齐手段,但 「从示范到偏好」的两级监督 这一思想是共通的。
安全与拒答
产品级模型还会在 SFT 与 RL 数据中加入 拒答示范(如何礼貌拒绝有害请求)与 红队测试(adversarial prompt)。个人 NTNU 微调虽不涉及,但若你的领域 bot 会面对公众,应在数据里 明确哪些话不能说,否则 base 模型的安全行为可能被 领域数据覆盖。
补充:评估基准与开源生态
- 通用 benchmark:MMLU、GSM8K、HumanEval 衡量 raw 能力
- 领域 eval:自建 50–100 条 held-out 师大问题,表格记录 base vs finetuned
- 开源 adapter 可上传到 Hugging Face Hub,与社区共享 LoRA 权重而不共享 base
术语速查
| 术语 | 英文 | 一句话 |
|---|---|---|
| 预训练 | Pretraining | 下一个词预测,学语言与常识 |
| 监督微调 | SFT | 模仿人类示范问答 |
| 人类反馈强化学习 | RLHF | 用 RM + RL 优化偏好 |
| 低秩适配 | LoRA | 只训小矩阵,冻结基座 |
| 量化 LoRA | QLoRA | 4-bit 基座 + LoRA,省 VRAM |
| 检索增强生成 | RAG | 先查文档再生成 |
| 对齐 | Alignment | 行为符合人类意图与安全 |
| 幻觉 | Hallucination | 流畅但事实错误 |
| 对齐税 | Alignment Tax | 对齐后部分 benchmark 下降 |
参考资料与扩展阅读
论文与经典文献
- Vaswani, A., et al. (2017). Attention is all you need. NeurIPS. — Transformer 架构
- Radford, A., et al. (2018, 2019). Improving Language Understanding / Generating Text. OpenAI Tech Report. — GPT 与预训练范式
- Ouyang, L., et al. (2022). Training language models to follow instructions with human feedback. NeurIPS. — InstructGPT / RLHF 三阶段
- Christiano, P., et al. (2017). Deep reinforcement learning from human preferences. NeurIPS. — RLHF 早期框架
- Hu, E. J., et al. (2021). LoRA: Low-Rank Adaptation of Large Language Models. ICLR. — LoRA
- Dettmers, T., et al. (2023). QLoRA: Efficient Finetuning of Quantized LLMs. NeurIPS. — QLoRA
- Rafailov, R., et al. (2023). Direct Preference Optimization. NeurIPS. — DPO 替代 RLHF
- Kaplan, J., et al. (2020). Scaling Laws for Neural Language Models. OpenAI. — Scaling Laws
- He, K., et al. (2016). Deep Residual Learning for Image Recognition. CVPR. — 与 LLM 无关,但 MNIST 系列读者可对照「深度模型训练技巧」的脉络
- Brown, T., et al. (2020). Language Models are Few-Shot Learners. NeurIPS. — GPT-3,few-shot 与 scaling 里程碑
官方文档与博客
- OpenAI — InstructGPT blog post
- Hugging Face — PEFT documentation
- Hugging Face — TRL SFTTrainer
- Qwen — Qwen3 / Qwen3.5 model cards on Hugging Face
代码与教程
- fine-tuning-playground — https://github.com/cw1997/fine-tuning-playground(本文实作仓库,含
README.zh-Hant.md) - Hugging Face — QLoRA notebook examples
延伸阅读(中文社区)
- 李沐等 — 《动手学深度学习》 中关于优化器、过拟合的章节,与 SFT 调参相通
- Hugging Face 中文社区 — PEFT、TRL 教程与 Qwen 微调 Notebook
- 各厂商模型卡(Qwen、LLaMA、Mistral)中的 Training Details 与 Evaluation 小节,可对照本文四阶段训练表做阅读笔记,加深对 post-training 的理解。
系列续读
- 《从智慧到人工智能:AI 基本概念与发展史入门》 — Transformer 与 AI 发展史
- 《机器学习与 MNIST 手写数字识别入门》 — 梯度下降、训练循环与 PyTorch 实战
如果你跟着本文跑通了 smoke test 和完整训练,下一步可以尝试:换
data/taiwan/universities.jsonl做台湾大学校问答、调lora_r与 epoch 观察 eval_loss、或把 adapter 推到 Hugging Face Hub 分享。微调不是魔法,而是 用高质量数据塑形模型行为 的工程;理解预训练与 RLHF 在全链路中的位置,你会更清楚自己这一步 SFT 究竟在解决什么问题。
小结:一张表记住全文
| 你想做的事 | 建议 |
|---|---|
| 理解 ChatGPT 怎么训出来 | 预训练 → SFT → RM → RLHF |
| 解释 base 模型为何不像助手 | 补全目标 ≠ 指令遵循 |
| 在 6–8GB GPU 上注入领域知识 | QLoRA + fine-tuning-playground |
| 知识常变、要 citation | RAG,或 RAG + 轻量 SFT |
| 只改语气、通用任务 | Prompt / 换 instruct 模型 |
| 评估微调效果 | compare 模式 + held-out 人工检查 |
大语言模型时代,训练决定能力上限,对齐与数据决定产品体验,而你的 SFT 数据集决定小模型在 niche 领域能有多可靠。 把这三层分开想,就不容易陷入「再训一个大模型」或「数据越多越好」的误区了。建议你把本文当作 地图,把 fine-tuning-playground 当作 练车场——先跑通完整流程,再谈优化与实际上线部署。
最后一句收束:预训练让模型读懂世界,SFT 教它如何服务你的场景,RLHF 教它何种服务方式更讨人喜欢;而你要做的,是用千条量级的精心问答,验证 LoRA 是否值得成为你工具链里的一站。 若本文对你有帮助,欢迎 star fine-tuning-playground 并在 issue 里反馈数据或脚本改进建议。