教程:如何微调 gpt-oss

逐步学习如何使用 Unsloth 在本地训练 OpenAI gpt-oss。

在这篇带截图的指南中,你将学会如何微调你自己的自定义 gpt-oss 模型,方式可以是 在本地 在你的机器上使用 Unsloth 或者通过以下方式免费使用 Google Colab。我们会带你完成整个流程,从环境配置到运行并保存你训练好的模型。

快速开始: 使用我们的以下内容免费微调 gpt-oss-20b: Colab 笔记本

与所有其他 FA2 实现相比,Unsloth 的 gpt-oss 微调可实现 1.5× 更快的训练、70% 的 VRAM 占用减少,以及 10 倍更长的上下文长度——且没有精度损失。

  • QLoRA 需求: gpt-oss-20b = 14GB VRAM • gpt-oss-120b = 65GB VRAM。

  • BF16 LoRA 需求: gpt-oss-20b = 44GB VRAM • gpt-oss-120b = 210GB VRAM。

本地指南Colab 指南

🌐 Colab gpt-oss 微调

本节介绍如何使用我们的 Google Colab 笔记本来微调 gpt-oss。你也可以将 gpt-oss 笔记本保存并在你喜欢的代码编辑器中使用,然后按照我们的 本地 gpt-oss 指南.

1

安装 Unsloth(在 Colab 中)

在 Colab 中,从上到下运行单元格 从上到下。使用 首次执行时选择“全部运行” 。第一个单元格会安装 Unsloth(以及相关依赖),并打印 GPU/内存信息。如果某个单元格报错,只需重新运行它。

2

配置 gpt-oss 和推理强度

我们将加载 gpt-oss-20b 使用 Unsloth 的 线性化版本 (因为其他版本都无法工作)。

配置以下参数:

  • max_seq_length = 1024

    • 建议用于快速测试和初步实验。

  • load_in_4bit = True

    • 使用 False 用于 LoRA 训练(注意:将其设置为 False 将至少需要 43GB VRAM)。你 必须 同时设置 model_name = "unsloth/gpt-oss-20b-BF16"

你应该会看到与下面示例类似的输出。注意:我们显式地将 dtype 改为 float32 更改为以确保正确的训练行为。

3

微调超参数(LoRA)

现在是调整训练超参数的时候了。若想更深入了解如何、何时以及调哪些参数,请查看我们的 详细超参数指南.

为避免 过拟合,请监控训练损失,并避免将这些值设得过高。

此步骤会添加 LoRA 适配器,用于参数高效微调。只有大约 1% 的模型参数会被训练,这使得整个过程更加高效。

4

尝试推理

在笔记本中,有一个名为 “Reasoning Effort” 的部分,用于演示 gpt-oss 在 Colab 中进行推理。你可以跳过这一步,但在完成微调后,之后仍然需要运行该模型。

5

数据准备

在这个示例中,我们将使用 HuggingFaceH4/Multilingual-Thinking。该数据集包含从用户问题翻译而来的、带有思维链推理的示例,原始问题从英语翻译成另外四种语言。

这与 OpenAI 的微调 cookbook 中引用的同一数据集。

使用多语言数据集的目标,是帮助模型学习并泛化跨多种语言的推理模式。

gpt-oss 引入了一个推理强度系统,用于控制模型执行多少推理。默认情况下,推理强度设为 ,但你可以通过设置 reasoning_effort 参数为 , .

示例:

tokenizer.apply_chat_template(
    text, 
    tokenize = False, 
    add_generation_prompt = False,
    reasoning_effort = "medium",
)

为了格式化数据集,我们应用 gpt-oss 提示词的自定义版本:

from unsloth.chat_templates import standardize_sharegpt
dataset = standardize_sharegpt(dataset)
dataset = dataset.map(formatting_prompts_func, batched = True,)

让我们通过打印第一个示例来检查数据集:

print(dataset[0]['text'])

gpt-oss 的一个独特特性是使用 OpenAI Harmony 格式, ,它支持结构化对话、推理输出以及工具调用。此格式包含诸如 <|start|> , <|message|> ,以及 <|return|> .

🦥 Unsloth 已修复聊天模板,以确保其正确。请查看这条 推文 了解我们模板修复的技术细节。

你可以自由调整提示词和结构,以适配你自己的数据集或使用场景。更多指导请参考我们的 数据集指南.

6

训练模型

我们已经预先选择了训练超参数以获得最佳结果。不过,你可以根据自己的具体使用场景进行修改。请参考我们的 超参数指南.

在这个示例中,我们训练 60 步以加快过程。若要进行完整训练,请设置 num_train_epochs=1 并通过设置 max_steps=None.

来禁用步数限制。在训练过程中,请监控损失,确保它随着时间下降。这可以确认训练过程正在正常运行。

7

推理:运行你训练好的模型

现在是使用你微调后的模型进行推理的时候了。你可以修改指令和输入,但请保持输出为空。

在这个示例中,我们通过在系统提示中添加一条特定指令,并按照我们数据集中使用的相同结构,测试模型用法语进行推理的能力。

这应该会产生类似如下的输出:

8

保存/导出你的模型

要保存你微调后的模型,你可以将其导出为 bf16 格式, 使用我们的 按需反量化 MXFP4 基础模型,采用 save_method="merged_16bit"或者以原生 MXFP4 Safetensors 格式,采用 save_method="mxfp4" .

MXFP4 原生合并格式相比 bf16 格式具有显著的性能提升:它最多可节省 75% 的磁盘空间,将 VRAM 占用减少 50%,使合并速度提升 5-10 倍,并且能更快地转换为 GGUF 格式。

在微调完你的 gpt-oss 模型后,你可以将其合并为 MXFP4 格式,命令如下:

model.save_pretrained_merged(save_directory, tokenizer, save_method="mxfp4)

如果你更希望直接合并模型并推送到 hugging-face hub:

model.push_to_hub_merged(repo_name, tokenizer=tokenizer, token= hf_token, save_method="mxfp4")

保存到 Llama.cpp

  1. 获取最新的 llama.cppGitHub 这里。你也可以按照下面的构建说明操作。将 -DGGML_CUDA=ON 改为 -DGGML_CUDA=OFF 如果你没有 GPU,或者只想进行 CPU 推理。

    apt-get update
    apt-get install pciutils build-essential cmake curl libcurl4-openssl-dev -y
    git clone https://github.com/ggml-org/llama.cpp
    cmake llama.cpp -B llama.cpp/build \
        -DBUILD_SHARED_LIBS=OFF -DGGML_CUDA=ON -DLLAMA_CURL=ON
    cmake --build llama.cpp/build --config Release -j --clean-first --target llama-cli llama-gguf-split
    cp llama.cpp/build/bin/llama-* llama.cpp
  2. 转换 MXFP4 合并后的模型:

    python3 llama.cpp/convert_hf_to_gguf.py gpt-oss-finetuned-merged/ --outfile gpt-oss-finetuned-mxfp4.gguf
  3. 在量化后的模型上运行推理:

    llama.cpp/llama-cli --model gpt-oss-finetuned-mxfp4.gguf \
        --jinja -ngl 99 --threads -1 --ctx-size 16384 \
        --temp 1.0 --top-p 1.0 --top-k 0 \
         -p "生命、宇宙以及一切的意义是"

🖥️ 本地 gpt-oss 微调

本章介绍如何在你的本地设备上微调 gpt-oss。虽然 gpt-oss-20b 微调最低只需 14GB VRAM,但我们建议至少提供 16GB VRAM,以确保训练运行稳定可靠。

我们建议从我们的 Colab 中下载或借用一些元素 笔记本 到你的本地环境中,以便更容易使用。

1

在本地安装 Unsloth

确保你的设备 兼容 Unsloth ,并且你可以阅读我们的详细 安装指南.

你也可以通过我们的 Docker 镜像.

来安装 Unsloth。请注意, pip install unsloth 不适用于此设置,因为我们需要使用最新的 PyTorch、Triton 及相关软件包。请使用以下特定命令安装 Unsloth:

# 我们正在安装最新的 Torch、Triton、OpenAI 的 Triton 内核、Transformers 和 Unsloth!
!pip install --upgrade -qqq uv
try: import numpy; install_numpy = f"numpy=={numpy.__version__}"
except: install_numpy = "numpy"
!uv pip install -qqq \
    "torch>=2.8.0" "triton>=3.4.0" {install_numpy} \
    "unsloth_zoo[base] @ git+https://github.com/unslothai/unsloth-zoo" \
    "unsloth[base] @ git+https://github.com/unslothai/unsloth" \
    torchvision bitsandbytes \
    git+https://github.com/huggingface/transformers \
    git+https://github.com/triton-lang/triton.git@05b2c186c1b6c9a08375389d5efe9cb4c401c075#subdirectory=python/triton_kernels
2

配置 gpt-oss 和推理强度

我们将加载 gpt-oss-20b 使用 Unsloth 的 线性化版本 (因为 QLoRA 微调只能在没有其他版本支持的情况下工作)。配置以下参数:

  • max_seq_length = 2048

    • 建议用于快速测试和初步实验。

  • load_in_4bit = True

    • 使用 False 用于 LoRA 训练(注意:将其设置为 False 将至少需要 43GB VRAM)。你 必须 同时设置 model_name = "unsloth/gpt-oss-20b-BF16"

from unsloth import FastLanguageModel
import torch
max_seq_length = 1024
dtype = None

# 我们支持的 4bit 预量化模型,可实现 4 倍更快下载 + 不会 OOM。
fourbit_models = [
    "unsloth/gpt-oss-20b-unsloth-bnb-4bit", # 使用 bitsandbytes 4bit 量化的 20B 模型
    "unsloth/gpt-oss-120b-unsloth-bnb-4bit",
    "unsloth/gpt-oss-20b", # 使用 MXFP4 格式的 20B 模型
    "unsloth/gpt-oss-120b",
] # 更多模型见 https://huggingface.co/unsloth

model, tokenizer = FastLanguageModel.from_pretrained(
    model_name = "unsloth/gpt-oss-20b",
    dtype = dtype, # 自动检测时设为 None
    max_seq_length = max_seq_length, # 为长上下文任意选择!
    load_in_4bit = True,  # 使用 4bit 量化以减少内存
    full_finetuning = False, # [NEW!] 我们现在支持全参数微调!
    # token = "hf_...", # 如果使用受限模型,请使用这个
)

你应该会看到与下面示例类似的输出。注意:我们显式地将 dtype 改为 float32 更改为以确保正确的训练行为。

3

微调超参数(LoRA)

现在是调整训练超参数的时候了。若想更深入了解如何、何时以及调哪些参数,请查看我们的 详细超参数指南.

为避免 过拟合,请监控训练损失,并避免将这些值设得过高。

此步骤会添加 LoRA 适配器,用于参数高效微调。只有大约 1% 的模型参数会被训练,这使得整个过程更加高效。

model = FastLanguageModel.get_peft_model(
    model,
    r = 8, # 选择任意大于 0 的数!建议 8、16、32、64、128
    target_modules = ["q_proj", "k_proj", "v_proj", "o_proj",
                      "gate_proj", "up_proj", "down_proj",],
    lora_alpha = 16,
    lora_dropout = 0, # 支持任意值,但 = 0 是经过优化的
    bias = "none",    # 支持任意值,但 = "none" 是经过优化的
    # [NEW] "unsloth" 可减少 30% 的 VRAM,占用空间可支持 2 倍更大的 batch size!
    use_gradient_checkpointing = "unsloth", # 对于超长上下文,True 或 "unsloth"
    random_state = 3407,
    use_rslora = False,  # 我们支持 rank stabilized LoRA
    loftq_config = None, # 以及 LoftQ
)
4

数据准备

在这个示例中,我们将使用 HuggingFaceH4/Multilingual-Thinking。该数据集包含从用户问题翻译而来的、带有思维链推理的示例,原始问题从英语翻译成另外四种语言。

这与 OpenAI 的微调 cookbook 中引用的同一数据集。使用多语言数据集的目标,是帮助模型学习并泛化跨多种语言的推理模式。

def formatting_prompts_func(examples):
    convos = examples["messages"]
    texts = [tokenizer.apply_chat_template(convo, tokenize = False, add_generation_prompt = False) for convo in convos]
    return { "text" : texts, }
pass

from datasets import load_dataset

dataset = load_dataset("HuggingFaceH4/Multilingual-Thinking", split="train")
dataset

gpt-oss 引入了一个推理强度系统,用于控制模型执行多少推理。默认情况下,推理强度设为 ,但你可以通过设置 reasoning_effort 参数为 , .

示例:

tokenizer.apply_chat_template(
    text, 
    tokenize = False, 
    add_generation_prompt = False,
    reasoning_effort = "medium",
)

为了格式化数据集,我们应用 gpt-oss 提示词的自定义版本:

from unsloth.chat_templates import standardize_sharegpt
dataset = standardize_sharegpt(dataset)
dataset = dataset.map(formatting_prompts_func, batched = True,)

让我们通过打印第一个示例来检查数据集:

print(dataset[0]['text'])

gpt-oss 的一个独特特性是使用 OpenAI Harmony 格式, ,它支持结构化对话、推理输出以及工具调用。此格式包含诸如 <|start|> , <|message|> ,以及 <|return|> .

🦥 Unsloth 已修复聊天模板,以确保其正确。请查看这条 推文 了解我们模板修复的技术细节。

你可以自由调整提示词和结构,以适配你自己的数据集或使用场景。更多指导请参考我们的 数据集指南.

5

训练模型

我们已经预先选择了训练超参数以获得最佳结果。不过,你可以根据自己的具体使用场景进行修改。请参考我们的 超参数指南.

在这个示例中,我们训练 60 步以加快过程。若要进行完整训练,请设置 num_train_epochs=1 并通过设置 max_steps=None.

from trl import SFTConfig, SFTTrainer
trainer = SFTTrainer(
    model = model,
    tokenizer = tokenizer,
    train_dataset = dataset,
    args = SFTConfig(
        per_device_train_batch_size = 1,
        gradient_accumulation_steps = 4,
        warmup_steps = 5,
        # num_train_epochs = 1, # 将其设置为完整训练 1 轮。
        max_steps = 30,
        learning_rate = 2e-4,
        logging_steps = 1,
        optim = "adamw_8bit",
        weight_decay = 0.01,
        lr_scheduler_type = "linear",
        seed = 3407,
        output_dir = "outputs",
        report_to = "none", # 用于 WandB 等
    ),
)

来禁用步数限制。在训练过程中,请监控损失,确保它随着时间下降。这可以确认训练过程正在正常运行。

6

推理:运行你训练好的模型

现在是使用你微调后的模型进行推理的时候了。你可以修改指令和输入,但请保持输出为空。

在这个示例中,我们通过在系统提示中添加一条特定指令,并按照我们数据集中使用的相同结构,测试模型用法语进行推理的能力。

messages = [
    {"role": "system", "content": "reasoning language: French\n\nYou are a helpful assistant that can solve mathematical problems."},
    {"role": "user", "content": "Solve x^5 + 3x^4 - 10 = 3."},
]
inputs = tokenizer.apply_chat_template(
    messages,
    add_generation_prompt = True,
    return_tensors = "pt",
    return_dict = True,
    reasoning_effort = "medium",
).to(model.device)
from transformers import TextStreamer
_ = model.generate(**inputs, max_new_tokens = 2048, streamer = TextStreamer(tokenizer))

这应该会产生类似如下的输出:

7

保存并导出你的模型

要保存你微调后的模型,它可以使用我们新的 Safetensors 格式导出,借助 按需反量化 MXFP4 基础模型(如 gpt-oss)在 LoRA 合并过程中。这使得可以 将你微调后的模型导出为 bf16 格式.

在微调完你的 gpt-oss 模型后,你可以使用以下命令将其合并为 16 位格式:

model.save_pretrained_merged(save_directory, tokenizer)

如果你更希望直接合并模型并推送到 hugging-face hub:

model.push_to_hub_merged(repo_name, tokenizer=tokenizer, token= hf_token)

保存到 Llama.cpp

  1. 获取最新的 llama.cppGitHub 这里。你也可以按照下面的构建说明操作。将 -DGGML_CUDA=ON 改为 -DGGML_CUDA=OFF 如果你没有 GPU,或者只想进行 CPU 推理。

    apt-get update
    apt-get install pciutils build-essential cmake curl libcurl4-openssl-dev -y
    git clone https://github.com/ggml-org/llama.cpp
    cmake llama.cpp -B llama.cpp/build \
        -DBUILD_SHARED_LIBS=OFF -DGGML_CUDA=ON -DLLAMA_CURL=ON
    cmake --build llama.cpp/build --config Release -j --clean-first --target llama-cli llama-gguf-split
    cp llama.cpp/build/bin/llama-* llama.cp
  2. 转换并量化合并后的模型:

    python3 llama.cpp/convert_hf_to_gguf.py gpt-oss-finetuned-merged/ --outfile gpt-oss-finetuned.gguf
    llama.cpp/llama-quantize gpt-oss-finetuned.gguf  gpt-oss-finetuned-Q8_0.gguf Q8_0
  3. 在量化后的模型上运行推理:

    llama.cpp/llama-cli --model gpt-oss-finetuned-Q8_0.gguf \
        --jinja -ngl 99 --threads -1 --ctx-size 16384 \
        --temp 1.0 --top-p 1.0 --top-k 0 \
         -p "生命、宇宙以及一切的意义是"

🏁 就这样!

你已经使用 Unsloth 完成了 gpt-oss 的微调。我们目前正在开发 RL 和 GRPO 的实现,以及改进模型保存和运行功能,敬请期待。

一如既往,如果你需要任何帮助,欢迎来我们的 DiscordReddit

❓FAQ(常见问题)

1. 之后我可以将模型导出以用于 Hugging Face、llama.cpp GGUF 或 vLLM 吗?

是的,你现在可以 保存/导出你经过 gpt-oss 微调的 模型,使用 Unsloth 的最新更新!

2. 我可以对 gpt-oss 进行 fp4 或 MXFP4 训练吗?

不可以,目前没有任何框架支持 fp4 或 MXFP4 训练。不过,Unsloth 是唯一支持该模型进行 QLoRA 4 位微调的框架,可使 VRAM 占用减少 4 倍以上。

3. 训练后我可以将模型导出为 MXFP4 格式吗?

不可以,目前没有任何库或框架支持这一点。

4. 我可以对 gpt-oss 进行强化学习(RL)或 GRPO 吗?

可以!Unsloth 现在支持使用 GRPO/GSPO 对 gpt-oss 进行 RL。我们已经在免费的 Kaggle 笔记本上实现,并达到了 RL 的最快推理速度。 在这里阅读更多


致谢: 特别感谢 Eyera 为本指南做出的贡献!

最后更新于

这有帮助吗?