大模型微调实战入门:generative-ai-for-beginners 第 18 课 Fine-Tuning 完整指南
本指南以微调(Fine-Tuning)为唯一主线,讲解"为什么微调、什么时候该微调、如何用数据集重新训练一个预训练大语言模型(LLM)并部署使用"。文中核心结论均来自本仓库课程第 18 课(见 18-fine-tuning/README.md 及其多语言版本),并补充以 18-fine-tuning/python/openai/oai-assignment.ipynb 中可运行的 OpenAI 微调流程代码与真实样本数据 training-data.jsonl。读完你即可掌握:微调与前两类提示技术的边界、微调的收益/成本决策框架、ChatGPT 风格模型的四步微调流水线,以及 OpenAI、Azure OpenAI、Hugging Face、AutoTrain、Unsloth 等主流微调路径的适用场景。
什么是"语言模型的微调"?
大语言模型(LLM)本质上是在互联网等海量来源的文本上预训练出来的通用模型。正因如此,直接用它对某个具体任务提问,输出质量(准确性、相关性)往往无法保证。本课程前几课已经给出两条解决思路:
- 提示工程(Prompt Engineering):通过改写/增强输入给模型"指路",对应第 04-prompt-engineering-fundamentals/README.md;
- 检索增强生成(RAG):检索外部知识库并把结果拼进提示词,对应第 15-rag-and-vector-databases/README.md。
这两类技术的共同点是只改输入、不改模型。而本课介绍的第三种技术——微调(Fine-Tuning)——思路完全不同:用额外数据把模型本身再训练一遍(retrain),得到针对特定任务/领域的自定义模型。
微调要解决的痛点:few-shot learning 的两大限制
提示工程里一种常用手段是给模型提供"少数示例"(few-shot learning):要么给显式指令(instructions),要么给几个输入输出范例(examples)。但 few-shot 有两条硬限制:
- Token 窗口限制:模型的最大 token 数限制了能塞进提示词的示例数量,示例太少又影响效果;
- Token 成本:每个提示词都附带示例,会显著抬高每次推理的 token 开销,也降低了提示设计的灵活性。
微调的本质与副产品
微调是机器学习里的常见实践:拿一个预训练模型,用新数据重新训练,以提升其在特定任务上的表现。落到语言模型上,就是挑选与该任务或应用域相关的精选示例集合,对预训练模型做进一步训练,产出一个自定义模型(custom model)——它对该任务/域的回答可以更准确、更相关。
微调还有一个"副产品":它显著减少了 few-shot 阶段必须塞进提示词的示例数量,从而降低 token 用量和相关费用。这一点在你后续比较"微调 vs 长提示词"的成本时是重要的量化维度。
什么时候、为什么该微调?(四问决策框架)
需要先澄清一个概念边界:本课讨论的是监督式微调(supervised fine-tuning)——用不属于原始训练数据集的新数据进行再训练;与之相对的是"无监督微调"——在原始数据上换一套超参数重新训练,二者目的完全不同。
课程同时强调:微调是进阶技术,需要一定专业度才能拿到期望结果。如果做得不对,它不仅不会带来预期提升,还可能让模型在你目标域上的表现变差。因此在学习"怎么微调"之前,先回答以下四组问题:
- 使用场景(Use Case):微调的用例是什么?你希望改进当前预训练模型的哪个方面?
- 替代方案(Alternatives):是否先试过其他技术并以此建立基线?
- 提示工程:先做 few-shot prompting,评估回答质量;
- 检索增强生成:用检索到的数据增强提示词,评估回答质量;
- 成本(Costs):是否盘点过微调的全部成本?
- 可调性(Tunability)——目标预训练模型是否开放微调;
- 投入(Effort)——训练数据准备、模型评估与迭代打磨的人力;
- 算力(Compute)——运行微调任务、托管微调模型的资源;
- 数据(Data)——能否拿到足够多、足够高质量的示例支撑微调见效;
- 收益(Benefits):收益是否得到验证?
- 质量(Quality)——微调模型是否真正超过基线;
- 成本(Cost)——是否因为提示词变简单而降低了 token 用量;
- 可扩展性(Extensibility)——能否把基础模型复用到新领域。
把这些问题过一遍,才能判断"微调"是不是当前用例的正解。理想情况下,只有当收益明确大于成本时,微调这条路才值得走。
微调一个预训练模型,你需要四样东西
课程把微调的前提收敛为四个要素,缺一不可:
- 待微调的预训练模型(pre-trained model);
- 用于微调的数据集(dataset);
- 运行微调任务(fine-tuning job)的训练环境;
- 部署微调后模型的托管环境(hosting environment)。
六条主流微调路径速览
课程在"Fine-Tuning In Action"一节为不同背景的开发者列出了真实可跟做的分步教程(原文档以表格列出,下表内容据 18-fine-tuning/README.md 归纳,各教程均需在对应服务商开通账号并拥有相关模型与数据集访问权限):
| 提供商/工具 | 教程主题 | 覆盖内容 |
|---|---|---|
| OpenAI | 如何微调 Chat 模型(OpenAI Cookbook) | 面向特定领域("食谱助手")微调 gpt-35-turbo:准备训练数据、启动微调任务、用微调模型做推理 |
| Azure OpenAI | GPT-3.5 Turbo 微调教程(官方文档) | 在 Azure 上微调 gpt-35-turbo-0613:创建并上传训练数据、启动任务、部署并使用新模型 |
| Hugging Face | 用 TRL 微调开源 LLM | 基于 transformers + Transformer Reinforcement Learning(TRL)微调开源模型(如 CodeLlama 7B),配合 HF 开放数据集 |
| 🤗 AutoTrain | AutoTrain / AutoTrain Advanced | Hugging Face 出品的无代码 Python 库,支持 GUI、CLI 与 YAML 配置三种训练方式,可在自有云、Hugging Face Spaces 或本地运行 |
| 🦥 Unsloth | Unsloth 微调框架 | 开源微调与强化学习(RL)框架,提供开箱即用的 Notebook 覆盖本地训练、评估与部署,还支持 TTS、BERT 与多模态模型 |
版本前提(务必阅读):仓库英文版正文与配套 Notebook 均保留一条重要提示——上述教程中出现的
gpt-35-turbo/gpt-3.5-turbo如今已同时停止推理与微调服务(OpenAI 侧已弃用,Azure OpenAI / Microsoft Foundry 亦已下线)。如果你今天要开新的微调任务,应选择当前仍受支持的模型(例如gpt-4o-mini或gpt-4.1-mini),但教程所讲的流程与概念完全适用,只需替换模型名即可。可微调模型清单请以官方最新文档为准。
端到端实操:仓库中的 OpenAI 微调流水线
课程在仓库中放了一份可运行的参考实现:18-fine-tuning/python/openai/oai-assignment.ipynb。它以"用五行打油诗(limerick)介绍化学元素"的 Elle 聊天机器人为例,完整演示了微调的四个步骤:
- 准备并上传训练数据;
- 运行训练任务得到微调模型;
- 评估微调模型并迭代质量;
- 满意后部署微调模型用于推理。
第一步:准备数据集(数据格式决定成败)
先看数据。为了让模型学会"用打油诗介绍元素",教程构造了对话样本集,真实样本见 training-data.jsonl(共 10 条示例)。文件采用 JSONL 格式:每行一条记录,每条记录是一个 JSON 对象,必须完整落在单行内(不能像普通 JSON 那样跨行缩进)。单轮对话格式形如:
{ "messages": [{"role": "system", "content": "Elle is a factual chatbot that answers questions about elements in the periodic table with a limerick"}, {"role": "user", "content": "Tell me about Gallium"}, {"role": "assistant", "content": "Gallium, oh gallium, so light - Melts in your hand, oh what a sight - At 86 degrees - Its liquid with ease - And in semiconductors, it's out of sight"}]}
{ "messages": [{"role": "system", "content": "Elle is a factual chatbot that answers questions about elements in the periodic table with a limerick"}, {"role": "user", "content": "Tell me about Hydrogen"}, {"role": "assistant", "content": "Hydrogen, the first in the line - The lightest of all, so divine - It's in water, you see - And in stars, it's the key - The universe's most common sign"}]}
每个样本由 system(设定角色)、user(用户问题)、assistant(期望回答)三段组成。课程对这份"玩具级"数据也做了诚实的边界说明:真实业务中需要远超 10 条的样本量,效果与训练时间/成本直接权衡;如果正好有现成的开源数据集(对应应用域)也可以改造复用。此外,如果你构建的是多轮对话场景,则应改用带 weight 参数的多轮格式,用 weight 标注哪些消息应参与(或不应参与)微调。
第二步:上传数据并启动微调任务
教程给出的前置条件是:安装 openai Python 包(建议版本不低于 0.28.0),并配置 OPENAI_API_KEY 环境变量;本仓库对应的环境准备流程见 00-course-setup/02-setup-local.md 与 00-course-setup/03-providers.md。
上传训练文件使用 Files API,purpose 必须声明为 "fine-tune":
from openai import OpenAI
client = OpenAI()
ft_file = client.files.create(
file=open("./training-data.jsonl", "rb"),
purpose="fine-tune"
)
print(ft_file)
print("Training File ID: " + ft_file.id)
拿到 Training File ID 后,用 client.fine_tuning.jobs.create 创建微调任务并指定基础模型(实际运行时请把 model 换成当前受支持的模型,例如 gpt-4o-mini;教程 Notebook 中示例基于 gpt-3.5-turbo 生成,仅作流程演示):
from openai import OpenAI
client = OpenAI()
ft_filejob = client.fine_tuning.jobs.create(
training_file=ft_file.id,
model="gpt-3.5-turbo"
)
print(ft_filejob)
print("Fine-tuning Job ID: " + ft_filejob.id)
任务创建后的第一件事是校验训练文件格式。你可以通过 client.fine_tuning.jobs 这组 API 管理任务生命周期(list 列出最近 n 个任务、retrieve 查询单个任务详情、cancel 取消任务、list_events 拉取任务事件、create 发起新任务)。以下代码来自 oai-assignment.ipynb,可查询任务状态与已训练 token 数:
# Once the training data is validated
# Track the job status to see if it is running and when it is complete
from openai import OpenAI
client = OpenAI()
response = client.fine_tuning.jobs.retrieve(ft_filejob.id)
print("Job ID:", response.id)
print("Status:", response.status)
print("Trained Tokens:", response.trained_tokens)
想要更细粒度的进度跟踪,可以轮询事件列表,直到看到任务成功完成的提示:
# You can also track progress in a more granular way by checking for events
# Refresh this code till you get the `The job has successfully completed` message
response = client.fine_tuning.jobs.list_events(ft_filejob.id)
events = response.data
events.reverse()
for event in events:
print(event.message)
除了用 SDK 轮询,也可以在平台 Fine-tuning 面板查看任务状态与历史。课程笔记特别记录过一个真实教训:第一次运行因为 JSON 记录格式错误而失败,修正格式后第二次运行即成功并把模型上线可用:
第三步:评估与迭代微调模型
任务成功后,先从任务响应里取出微调模型的 ID,然后像调用任何模型一样发起推理测试:
# Retrieve the identity of the fine-tuned model once ready
response = client.fine_tuning.jobs.retrieve(ft_filejob.id)
fine_tuned_model_id = response.fine_tuned_model
print("Fine-tuned Model ID:", fine_tuned_model_id)
from openai import OpenAI
client = OpenAI()
completion = client.responses.create(
model=fine_tuned_model_id,
input=[
{"role": "system", "content": "You are Elle, a factual chatbot that answers questions about elements in the periodic table with a limerick"},
{"role": "user", "content": "Tell me about Strontium"},
],
store=False,
)
print(completion.output_text)
用未在训练样本中出现过的"Strontium(锶)"提问,可以验证模型是否把"打油诗"输出格式泛化到了新元素上——这正是衡量微调是否学到模式的关键手段。
你也可以把微调模型加载到 Playground,用"对比视图"让基础模型与微调模型在完全相同的 system 上下文与问题上并排输出,直观比较差异:
课程在笔记中特别提醒两点评估要点:
- 微调模型的威力不在"更聪明",而在"更守格式":从对比中可以观察到,微调模型会严格按你样本里定义的格式作答,而基础模型往往只顺着 system prompt 泛泛输出;
- 玩具示例 ≠ 真实收益:教程刻意选用极小数据集以快速走通流程。真实场景(例如用产品目录微调客服模型)中,基础模型要达到同等质量往往需要额外堆提示工程,反而增加 token 用量与推理耗时;这时微调在质量与成本上的优势才会真正显现。
课程作业与验收清单
第 18 课的作业要求是:从上一节六条微调路径中选择一条教程并完整跟做。仓库说明同时强调:这些教程若以 Jupyter Notebook 形式在仓库中复刻,仅作参考用途;要获取最新版本,请以原始出处为准(本仓库当前就保留着一份 OpenAI 的参考实现 oai-assignment.ipynb)。
对照本课学习目标,你可以用下面四个问题自检是否过关:
- 什么是语言模型的微调?
- 什么时候、为什么微调是有效的?
- 我如何微调一个预训练模型?
- 微调的局限有哪些(成本、算力、数据、技能要求)?
继续深入:仓库内相关的延伸学习路径
- 微调主题的官方英文原版见 18-fine-tuning/README.md(其内容为本仓库各语言翻译版之母版),本文对应的原始文档位于 translations/bn/18-fine-tuning/README.md;
- 更多自定步调学习资料清单(含 OpenAI / Azure OpenAI 官方微调文档、微软 AI Playbook 微调建议、Continuous Fine Tuning、微调 + 函数调用、微调模型可用性对照表、AI Show 决策讨论,以及数据预检与 token 成本估算、面向 RAG 的微调、Weights & Biases 追踪、Phi-2 QLoRA 社区教程、Hugging Face 2024 微调教程、AutoTrain Advanced 等二级资料)见 18-fine-tuning/RESOURCES.md;
- 微调常与提示工程与检索增强生成对照权衡,建议同时复习 04-prompt-engineering-fundamentals/README.md 与 15-rag-and-vector-databases/README.md,以便在"改提示词 vs 加检索 vs 动模型"之间做出有依据的取舍;相关"开源模型选择"主题可继续阅读 16-open-source-models/README.md(如何挑选可微调的开源底座模型),面向小模型的微调思路则见 19-slm/README.md。
至此,你已经完整走通了"判断是否需要微调 → 盘点四要素 → 准备 JSONL 数据 → 创建并监控训练任务 → 评估并部署使用"的全链路。把教程里的玩具示例替换成你自己的业务数据,即可把这套流程复用到真实场景中。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0625
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00


