生成式 AI 初学者课程第 18 课:LLM 微调(Fine-Tuning)实战指南
【免费下载链接】generative-ai-for-beginners21 Lessons, Get Started Building with Generative AI项目地址: https://gitcode.com/GitHub_Trending/ge/generative-ai-for-beginners
大型语言模型(LLM)在生成式 AI 应用中的核心挑战,是确保模型针对给定用户请求生成内容的质量(准确性与相关性)。此前课程讨论的提示工程(prompt engineering)与检索增强生成(RAG)都通过修改输入模型的 prompt来缓解该问题;而本课介绍的第三种技术——微调(fine-tuning)——则通过用附加数据重新训练模型本身来应对挑战。本文将基于generative-ai-for-beginners仓库第 18 课内容,讲清微调的概念、适用时机、成本收益评估,并结合仓库内的 OpenAI 微调 Jupyter Notebook 与训练数据样例,带你走通"准备数据 → 上传 → 训练 → 评估 → 部署"的完整实战流程。
什么是语言模型微调?
按定义,LLM 是在互联网等多样来源的海量文本上预训练出来的。为了让模型对用户问题(prompt)给出高质量回答,我们通常需要提示工程或 RAG 等技巧。一种流行的提示工程技术是给模型更多关于期望输出的指引——要么通过指令(显式指引),要么通过给出几个示例(隐式指引),即few-shot 学习。但它有两个固有局限:
- token 窗口限制:模型 token 上限限制了你能塞进 prompt 的示例数量,进而限制效果;
- token 成本:每个 prompt 都携带示例会推高成本、降低灵活性。
微调正是针对这些局限的常见机器学习实践:拿一个预训练模型,用新数据重新训练,以提升其在特定任务上的表现。对语言模型而言,就是用针对某任务或应用领域精心整理的示例集去微调预训练模型,产出一个自定义模型(custom model),使其在该任务或领域上更准确、更相关。微调的附带好处是:它还能减少 few-shot 学习所需的示例数量,从而降低 token 用量和相关成本。
模型退役提示:本课及仓库 Notebook 示例输出基于
gpt-35-turbo/gpt-3.5-turbo生成,该模型在 Azure OpenAI(Microsoft Foundry)与 OpenAI 平台均已退役(推理与微调均不再支持)。若你今天启动新的微调任务,请改用当前受支持的可微调模型,例如gpt-4o-mini或gpt-4.1-mini;本课中的概念与步骤仍然适用。可微调模型清单请查阅 Azure AI Foundry 的"Fine-tuning models"官方列表。
何时、为何要微调模型?
本课讨论的微调特指监督式微调(supervised fine-tuning):重新训练通过加入原始训练数据集之外的新数据完成。这与无监督式微调(在原始数据上以不同超参数重新训练)不同。
需要牢记:微调是高级技术,需要一定专业水平才能获得理想结果。若操作不当,它可能不会带来预期提升,甚至可能降低模型在你目标领域上的表现。因此在学习"如何"微调之前,必须先弄清"为何"走这条路、"何时"启动。请先自问以下四组问题:
使用场景(Use Case)
你的微调使用场景是什么?你希望改进当前预训练模型的哪个方面?
替代方案(Alternatives)
你是否尝试过其他技术来达成目标?请用它们建立对比基线(baseline):
- 提示工程:尝试 few-shot prompting,在 prompt 中加入相关的"提示-响应"示例,评估响应质量;
- 检索增强生成(RAG):尝试用检索数据得到的查询结果增强 prompt,评估响应质量。
成本(Costs)
你是否已识别微调的成本构成?
- 可微调性(Tunability):该预训练模型是否支持微调?
- 精力(Effort):准备训练数据、评估与迭代模型所需的人力;
- 算力(Compute):运行微调任务、部署微调后模型所需的计算资源;
- 数据(Data):能否获得足够数量、足够质量的示例,使微调产生实际效果。
收益(Benefits)
你是否已确认微调的收益?
- 质量(Quality):微调后的模型是否超越了基线?
- 成本(Cost):是否因 prompt 简化而降低了 token 用量?
- 可扩展性(Extensibility):能否将基础模型迁移到新领域?
回答完这些问题,你就能判断微调是否是当前场景的正确方案——理想情况下,只有收益大于成本时才值得走这条路。确认要推进后,才轮到思考"如何"微调。
如何微调一个预训练模型?
微调预训练模型需要四类要素:
- 一个可供微调的预训练模型;
- 用于微调的数据集;
- 运行微调任务的训练环境;
- 部署微调后模型的托管环境。
微调实战:仓库内的完整可运行示例
英文原版课程提供了多家平台的实战教程(OpenAI、Azure OpenAI、Hugging Face、🤗 AutoTrain、🦥 Unsloth),而本仓库进一步在 oai-assignment.ipynb 中提供了一份基于 OpenAI 官方微调指南、可在本地直接运行的端到端 Notebook。它把微调拆成 4 个步骤:① 准备并上传训练数据 → ② 运行训练任务 → ③ 评估微调模型并迭代质量 → ④ 满意后部署模型用于推理。下面结合 Notebook 代码与数据逐步骤拆解。
步骤 1:准备训练数据(JSONL 格式)
Notebook 的示例目标是打造一个"元素周期表知识聊天机器人":当用户询问某个元素时,模型用**五行打油诗(limerick)**回答。真实场景需要成百上千条示例,这里仅用 10 条样例快速走通流程。完整样例数据见 training-data.jsonl。
数据采用JSONL 格式(每行一条 JSON 记录),针对gpt-3.5-turbo这类单轮 chat completion 任务,使用如下 chat 格式:
{ "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(期望的理想回答)。注意:每条记录必须是一整行,不能像普通格式化 JSON 那样跨行。若你的应用需要多轮对话,应使用多轮示例格式,并可通过weight参数标记哪些消息参与(或不参与)微调。10 条样例数据里,每条 system 指令保持一致、assistant 回答均以押韵打油诗格式呈现——这正是要让模型学到的"输出风格"。
步骤 2:上传数据集并创建微调任务
运行 Notebook 前需完成环境准备:安装openaiPython 包(Notebook 建议版本 >= 0.28.0),并设置OPENAI_API_KEY环境变量(可参考课程设置指南 02-setup-local.md)。
先通过 Files API 上传 JSONL 文件,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)随后用返回的ft_file.id创建微调任务:
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)任务创建后,第一阶段会校验训练文件格式,随后进入训练流程。Notebook 还汇总了client.fine_tuning.jobs的常用 API:
client.fine_tuning.jobs.list(limit=n):列出最近 n 个微调任务;client.fine_tuning.jobs.retrieve(job_id):获取指定任务详情;client.fine_tuning.jobs.cancel(job_id):取消微调任务;client.fine_tuning.jobs.list_events(fine_tuning_job_id=job_id, limit=n):列出任务事件,用于监控进度。
步骤 3:监控训练进度
训练是异步的,可用retrieve轮询状态(status字段会经历validating_files→running→ 完成等阶段,trained_tokens记录已训练 token 数):
response = client.fine_tuning.jobs.retrieve(ft_filejob.id) print("Job ID:", response.id) print("Status:", response.status) print("Trained Tokens:", response.trained_tokens)更细粒度地,可拉取事件列表直到看到The job has successfully completed:
response = client.fine_tuning.jobs.list_events(ft_filejob.id) events = response.data events.reverse() for event in events: print(event.message)Notebook 记录的真实训练事件展示了完整生命周期——从 100 步训练中training loss逐步收敛到 0.00,到分阶段生成 checkpoint(例如第 80 步、第 90 步的 Snapshot ID),最终创建微调模型并完成任务:
Step 100/100: training loss=0.00 Checkpoint created at step 80 with Snapshot ID: ft:gpt-3.5-turbo-0125:bitnbot::9OFWyyF2:ckpt-step-80 Checkpoint created at step 90 with Snapshot ID: ft:gpt-3.5-turbo-0125:bitnbot::9OFWyzhK:ckpt-step-90 New fine-tuned model created: ft:gpt-3.5-turbo-0125:bitnbot::9OFWzNjz The job has successfully completed你也可以在 OpenAI 平台的Fine-tuning页面可视化查看任务状态与历史记录。下图展示了微调任务状态面板(示例中第一次运行因 JSON 记录格式错误而失败,修正后第二次运行成功):
步骤 4:评估并调用微调模型
任务完成后,先通过retrieve拿到微调模型 ID(response.fine_tuned_model,形如ft:gpt-3.5-turbo-0125:bitnbot::9OFWzNjz),即可在代码中直接推理。Notebook 用 Responses API 测试了一个训练数据中没出现过的元素 "Strontium",模型按打油诗格式作答:
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, a metal so bright - It's in fireworks, a dazzling sight - It's in bones, you see - And in tea, it's the key - It's the fortieth, so pure, that's the right此外,可在 Playground 的模型下拉框中选中微调模型,或从 Fine-tuning 面板直接启动基座模型与微调模型的并排对比视图:填入与训练数据相同的 system 上下文和测试问题,即可直观看到两者输出的差异——微调模型会严格按照训练示例中的格式作答,而基座模型只是跟着 system prompt 泛泛回应。对比视图还会给出两个模型的 token 用量与推理耗时。
需要强调的是,本示例属于"玩具级"演示,意在展示流程而非真实业务场景。真实场景中,你应对业务数据(如产品目录、客服语料)微调,此时要让基座模型达到同等响应质量,往往需要更复杂的提示工程,从而增加 token 用量与推理时间——微调的价值会体现得更明显。
平台教程速览
| 平台 | 教程要点 |
|---|---|
| OpenAI | 官方 Cookbook 教程:为特定领域("食谱助手")微调 chat 模型,涵盖训练数据准备、运行微调任务、使用微调模型推理 |
| Azure OpenAI | Azure 官方教程:在 Azure 上微调gpt-35-turbo-0613,逐步完成数据集创建与上传、运行微调任务、部署并使用新模型 |
| Hugging Face | 社区博客教程:用transformers库与 TRL(Transformer Reinforcement Learning)在 Hugging Face 开放数据集上微调开源 LLM(如CodeLlama 7B) |
| 🤗 AutoTrain | Hugging Face 出品的 Python 库,支持包括 LLM 在内的多类任务微调;无代码方案,可在自有云、Hugging Face Spaces 或本地执行,同时支持 Web GUI、CLI 与 yaml 配置训练 |
| 🦥 Unsloth | 开源微调框架,支持 LLM 微调与强化学习(RL),提供开箱即用的 Notebook 简化本地训练、评估与部署,还支持 TTS、BERT 与多模态模型 |
本课教程中的旧模型(
gpt-35-turbo/gpt-3.5-turbo)已退役,开始新微调任务时请改用当前支持的模型(如gpt-4o-mini、gpt-4.1-mini),概念与步骤不变。
作业与进阶资源
作业:从上方教程中任选一个完整走一遍(仓库可能后续补充对应 Jupyter Notebook 作为参考,请以原始来源的最新版本为准)。
完成本课后,可继续阅读仓库内配套的 RESOURCES.md 获取进阶学习资料,涵盖:Azure OpenAI 微调概念与"何时考虑微调"的官方建议、连续微调(Continuous Fine-Tuning,将已微调模型作为基座继续迭代)、微调与函数调用(function calling)结合、OpenAI Cookbook 的聊天模型训练数据准备与 RAG 微调示例、以及基于 Phi-2 的 QLoRA 微调等社区教程。
版权说明:本文内容整理自
generative-ai-for-beginners仓库第 18 课文档及其匈牙利语翻译版(translations/hu/18-fine-tuning/README.md),并辅以仓库内 Notebook 与训练数据的实现细节,仅供学习参考。
【免费下载链接】generative-ai-for-beginners21 Lessons, Get Started Building with Generative AI项目地址: https://gitcode.com/GitHub_Trending/ge/generative-ai-for-beginners
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考