首页
/ generative-ai-for-beginners 第 18 课:LLM 微调(Fine-Tuning)原理、决策框架与 OpenAI 实战全流程

generative-ai-for-beginners 第 18 课:LLM 微调(Fine-Tuning)原理、决策框架与 OpenAI 实战全流程

2026-09-04 09:08:06作者:卓炯娓

本篇技术指南聚焦于生成式 AI 课程第 18 课「微调你的 LLM」。你将理解什么是语言模型微调、它在「提示工程 / RAG」之外的独特价值、何时应当启动微调的完整决策框架,以及一套可复制的 OpenAI 微调实战流程(从 JSONL 训练数据、文件上传、训练任务、事件追踪,到模型 ID 提取与 Playground 对比验证)。学完本篇,你既能建立「是否微调」的工程判断力,也能动手跑通一个真实微调任务。

为什么需要微调:从「改提示」到「重训模型」

大型语言模型(LLM)本身是预训练(pre-trained)模型——它们在来自互联网等海量文本上完成训练。前序课程已经介绍了两类「不改动模型本身、只修改提示输入」来提升响应质量的技术:

  • 提示工程(Prompt Engineering):通过指令(显式引导)或示例(隐式引导)来约束模型输出。
  • 检索增强生成(RAG):用检索到的数据对提示进行增强。

其中一种流行的提示技巧是「少样本学习」(few-shot learning)——给模型若干示例(指令或示例对)来引导期望输出。但它有两个固有限制:

  • Token 上限限制:模型上下文窗口有限,能塞进提示的示例数量受限,从而影响效果;
  • Token 成本限制:每次请求都要附带示例,会增加 token 开销,并降低灵活性。

微调(fine-tuning) 正是针对这些痛点的第三种技术路线:它不再修改提示,而是用额外数据对模型本身进行再训练。在语言模型语境下,我们用「面向特定任务或应用领域的精选示例集」来微调预训练模型,产出一个定制模型(custom model)——它对特定任务/领域通常更准确、更相关。附带收益是:微调后模型对少样本示例的依赖下降,从而减少 token 使用与相关成本。

微调语言模型的学习路线插图指南(从概念、动机到数据准备、训练评估、部署与最佳实践)

说明:上图是官方为该课绘制的学习路线插图,覆盖七大环节——基础概念、为何微调(Why Fine-Tune)、流程与挑战(数据收集/格式化/训练/评估/迭代/部署)、数据准备、训练与评估、部署与使用、最佳实践。它可作为本文的总览导航。

何时、为何应当微调:一个可落地的决策框架

本课程的「微调」特指监督式微调(supervised fine-tuning)——即通过加入不属于原始训练集的新数据来再训练模型。它与「无监督微调」不同:后者是在原始数据上、用不同超参数重新训练。

需要牢记:微调是一项进阶技术,需要一定专业水平才能拿到理想效果。如果操作不当,它可能无法带来预期提升,甚至降低模型在目标领域的表现。因此,在学「怎么微调」之前,先要回答「为什么」和「何时」开始。官方给出的自检清单如下:

  • 使用场景(Use Case):你微调的用途是什么?你希望改进当前预训练模型的哪个方面?
  • 替代方案(Alternatives):你是否尝试过其他技术达到相同目标?用它们建立对比基线。
    • 提示工程:尝试 few-shot(附相关提示/响应示例),并评估响应质量。
    • RAG:尝试用检索到的查询结果增强提示,并评估响应质量。
  • 成本(Costs):你识别出微调的成本了吗?
    • 可微调性(Tunability)——目标预训练模型是否支持微调?
    • 工作量(Effort)——准备训练数据、评估与迭代模型的人力成本。
    • 算力(Compute)——跑微调任务、部署微调模型所需的计算资源。
    • 数据(Data)——是否能获取足够数量、足够质量的示例来支撑微调效果。
  • 收益(Benefits):你确认了微调的收益吗?
    • 质量(Quality)——微调模型是否胜过基线?
    • 成本(Cost)——是否通过简化提示降低了 token 使用?
    • 可扩展性(Extensibility)——能否把基座模型复用到新领域?

决策原则:只有当收益大于成本时,微调才是合理路线。理想情况下,你应当先有基线(提示工程/RAG),再判断微调是否值得投入。

微调一个预训练模型需要哪些要素

官方将微调的「四要素」归纳为:

  1. 一个可供微调的预训练模型(并非所有基座模型都支持微调,需先确认);
  2. 一份用于微调的数据集(精选的训练示例);
  3. 一个可运行微调任务的训练环境
  4. 一个可部署微调模型的主机环境

对应到 OpenAI 平台的完整流程,可拆解为四步:

  1. 准备训练数据并上传
  2. 运行训练任务,得到微调模型
  3. 评估微调模型并迭代优化质量
  4. 满意后部署微调模型用于推理

实战:用仓库自带样例跑通一个 OpenAI 微调任务

本仓库在 微调任务 Notebook 中提供了一个可参考的完整样例,配套训练数据见 training-data.jsonl。它要训练一个聊天机器人 「Elle」——用五行打油诗(limerick) 回答元素周期表中某个元素的问题。这是一个刻意简化的「玩具样例」,目的是快速演示流程而非真实生产数据集;真实场景需要大得多的示例集(质量与成本/时间之间的权衡)。

适用前提与重要提示:该 Notebook 的示例输出是在 gpt-3.5-turbo 上生成的,而 gpt-3.5-turbo 如今已同时退出推理与微调(Azure OpenAI / OpenAI 均已弃用)。若你现在要开启一个新微调任务,请改用一个当前受支持的模型(例如 gpt-4o-minigpt-4.1-mini),并以官方「可微调模型列表」为准。本文的流程与概念仍然适用。

步骤一:准备并上传训练数据

针对 gpt-3.5-turbo 这类单轮(single-turn) 聊天补全场景,训练数据采用 JSONL 格式:每行一条记录,每条记录是一个 JSON 对象,必须写在一行内(不能像普通格式化 JSON 那样拆多行)。样例中一条记录长这样(来自 training-data.jsonl):

{ "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 定义助手人设(Elle 用 limerick 回答元素问题),user 是问题,assistant 是期望输出格式。完整样例集共 10 条元素示例(Gallium、Hydrogen、Helium、Boron、Iron、Carbon、Cobalt、Titanium、Silver、Mercury)。

若期望多轮对话内容,则应改用「多轮示例格式」,其中包含一个 weight 参数,用于标记哪些消息应(或不应)参与微调过程。本教程为简化起见采用单轮格式。

上传前,需满足两个前置条件(来自 课程本地配置指南):

  • 已安装 openai Python 包(为获得最新特性,使用版本 >= 0.28.0);
  • 已设置 OPENAI_API_KEY 环境变量为你的 API 密钥。

随后用 Files API 上传本地 JSONL 文件:

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)

上传成功后会返回一个文件对象(含 idfilename='training-data.jsonl'purpose='fine-tune'status='processed' 等字段),记下其中的 File ID 供后续创建任务使用。

步骤二:创建并跟踪微调任务

fine_tuning.jobs.create 创建任务,传入训练文件 ID 与目标基座模型:

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)

从返回的任务对象可观察到关键信息:hyperparameters 初始为全 auton_epochsbatch_sizelearning_rate_multiplier 均由平台自动选择),status 初始为 validating_files(平台会先校验训练文件格式)。

client.fine_tuning.jobs 提供一组常用操作,便于管理与监控:

  • 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=<b>) —— 列出最多 n 条任务事件。

轮询状态直到训练完成:

# 训练数据校验通过后,跟踪任务状态
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)

事件流会输出每一步的训练 loss(如 Step 85/100: training loss=0.14Step 100/100: training loss=0.00)、检查点创建信息(如 Checkpoint created at step 80 with Snapshot ID: ft:gpt-3.5-turbo-0125:...:ckpt-step-80),最终以 New fine-tuned model created: ft:gpt-3.5-turbo-0125:bitnbot::9OFWzNjzThe job has successfully completed 收尾。

在 OpenAI 控制台(平台的 Fine-tuning 分区)可可视化查看任务状态、历史运行、训练指标(训练 token 数、epochs、batch size、LR multiplier、seed、checkpoints、训练 loss 曲线等)。该截图同时展示了「上一次因 JSON 记录格式错误而失败、修正后第二次运行成功」的真实经历——这正说明了数据格式正确性是微调成败的关键之一。

OpenAI Fine-tuning 控制台任务详情:状态、训练 token 数、epochs、batch size、LR multiplier、seed、checkpoints 与训练 loss 曲线

步骤三:提取模型 ID 并验证微调效果

任务完成后,先从任务对象里取出微调模型的 ID:

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)

随后有两种验证方式:

方式一:在代码中直接调用。 用微调后的模型 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)

方式二:在 Playground 中并排对比。 在 Playground 的模型下拉框里选择新微调模型,或直接在微调面板里点击「Playground」入口,会进入一个对比视图(comparitive view),把基座模型微调模型并排放置,快速评估差异:

Playground 对比视图:同一问题「Tell me about Carbon」在基座模型与微调模型上的输出与延迟差异

填入训练数据中使用的 system 上下文与测试问题,两侧会自动填入相同的上下文与问题。运行对比后可以观察到:微调模型按你示例中提供的格式(limerick 结构)渲染响应,而基座模型只是泛泛地遵循 system 提示。同时对比视图还会给出每个模型的 token 数推理耗时

客观提醒(与仓库说明一致):这是一个用来演示流程的极简样例,并不代表真实数据集或场景;本例中两侧 token 数相同(system 上下文与 user 提示一致),而微调模型推理耗时反而更长(自定义模型)。在真实场景(如面向客服的产品目录)里,要达到同等质量,基座模型往往需要更复杂的提示工程,从而增加 token 使用与潜在推理耗时——这正是微调「简化提示、降低成本」价值的体现。

微调生态与工具选型

除了仓库自带的 OpenAI 样例,官方还梳理了多套可用于实际微调的提供商/工具,它们覆盖不同技术栈与使用习惯:

  • OpenAI:通过 Cookbook 的「如何微调聊天模型」示例,用「食谱助手(recipe assistant)」这一特定领域做完整演练——准备训练数据、运行微调任务、用微调模型做推理。
  • Azure OpenAI:提供 GPT 系列微调教程,涵盖创建并上传训练数据、运行微调任务、部署并使用新模型的完整链路(支持门户 / Python SDK / 命令行 / REST)。
  • Hugging Face:面向开源 LLM(如 CodeLlama 7B)的微调,使用 transformersTRL(Transformer Reinforcement Learning)与 Hugging Face datasets 库,支持在 Hugging Face 上微调开放模型。
  • AutoTrain(AutoTrain Advanced):Hugging Face 的 Python 库,支持包括 LLM 微调在内的多种任务;提供**无代码(no-code)**方案,支持 Web GUI、CLI 以及基于 YAML 配置文件训练,可部署在你自己的云、Hugging Face Spaces 或本地。
  • Unsloth:开源框架,支持 LLM 微调与强化学习(RL),提供开箱即用的 notebook,并支持文本转语音(TTS)、BERT 与多模态模型,简化本地训练、评估与部署流程。

选型建议:若目标是托管闭源模型(OpenAI / Azure OpenAI),走平台 API + JSONL 数据集路线;若目标是开源/本地模型,优先考虑 Hugging Face 生态(TRL + transformers)或 AutoTrain / Unsloth 等降低门槛的工具。

数据准备与训练评估的关键检查项

结合该课插图指南与 RESOURCES 页的自我引导资料,微调工程落地的核心检查点可以归纳为:

  • 数据准备:训练数据规模(示例数量)、示例格式(依模型而定)、数据表征(广度 vs 质量)、需求覆盖度(质量)。
  • 训练与评估:上传训练数据 → 创建微调任务 → 监控任务状态 → 测试微调模型。
  • 部署与使用:区域可用性(约束条件)、模型速率限制(共享)、在 Playground 中验证、集成到 SDK/应用。
  • 最佳实践:拥有明确用例、先尝试其他替代方案、评估成本与收益、制定维护策略。

其中「成本/数据准备/质量度量」三类官方参考资料尤其值得深入:数据准备与分析(格式校验、基本统计、token 估算以预估微调成本)、连续微调(continuous fine-tuning,即把已微调模型作为新的基座继续微调)、以及与函数调用(function calling)结合的微调(可获得更准确、一致、格式统一且更省成本的输出)。

小结

微调是继提示工程、RAG 之后的第三类「提升 LLM 输出质量」的技术,其本质是用新数据重训模型本身,以换取更强的任务/领域表现与潜在的 token 成本下降。落地时应遵循「先建基线(提示工程/RAG)→ 评估成本收益 → 再决定是否微调」的决策框架,并严格把控数据格式正确性、训练质量评估与迭代、部署验证三个环节。本仓库的 微调任务 Notebook样例数据集 提供了一个端到端、可参考的 OpenAI 微调实例;配套延伸阅读见 RESOURCES。注意:样例所基于的 gpt-3.5-turbo 已退出微调,实际作业请改投当前受支持的模型,并以官方可微调模型列表为准。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.12 K
2.72 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
528
588
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
906
1.83 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
854
1.34 K
docsdocs
暂无描述
Markdown
891
5.78 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.53 K
1.01 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.34 K
1.45 K
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
987
506
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
540
384