> For the complete documentation index, see [llms.txt](https://unsloth.ai/docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://unsloth.ai/docs/zh/bo-ke/500k-context-length-fine-tuning.md).

# 50 万上下文长度微调

了解如何使用 Unsloth 启用超过 50 万 token 的上下文窗口微调。

我们正在 Unsloth 中引入新的算法，将长上下文训练的极限推进到 **任何 LLM 和 VLM**。像 gpt-oss-20b 这样的 LLM 训练现在可以达到 **50 万以上上下文长度** ，并在单张 80GB H100 GPU 上实现，之前仅能达到 8 万，而且没有精度下降。

你可以在**超过 75 万上下文窗口** 的 B200 192GB GPU 上实现。

> **试试在我们的** [**80GB A100 Colab 笔记本**](https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/gpt_oss_\(20B\)_500K_Context_Fine_tuning.ipynb)**.**

上进行 50 万上下文的 gpt-oss-20b 微调。

* **显存使用降低 60%** 替换为 **上下文长度延长 3.2 倍** 借助 Unsloth 新的 [融合与分块交叉熵](#unsloth-loss-refactoring-chunk-and-fuse) 损失，且速度或精度没有任何下降
* Unsloth 中增强的激活卸载 [**梯度检查点**](#unsloth-gradient-checkpointing-enhanced)
* 与 Snowflake 的 Stas Bekman 合作开发 [平铺式 MLP](#tiled-mlp-unlocking-500k)，使上下文数量增加 2 倍

Unsloth 的算法使 gpt-oss-20b QLoRA（4bit）在 H100 上可以实现 29 万上下文，且没有精度损失；启用 Tiled MLP 后可达 50 万以上，总体带来 >**6.4 倍更长的上下文长度。**

<figure><img src="https://2657992854-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxhOjnexMCB3dmuQFQ2Zq%2Fuploads%2F8Ha930qR5XXBOK7M7oiy%2Fline_chart_light_tiled.png?alt=media&amp;token=51467f68-a77b-4037-b9d9-e668223868c5" alt="" width="563"><figcaption></figcaption></figure>

### 📐 Unsloth 损失重构：分块与融合

我们新的融合损失实现加入了 **动态序列分块**：它不再一次性在整个序列上计算语言模型头部 logits 和交叉熵，而是沿着展平后的序列维度处理可管理的切片。这将峰值内存从 GB 级降到更小的分块大小。每个分块仍然通过以下方式运行完整融合的前向 + 反向： `torch.func.grad_and_value` ，并在必要时通过上采样到 float32 来保留混合精度准确性。 **这些更改不会降低训练速度或精度。**

<figure><img src="https://2657992854-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxhOjnexMCB3dmuQFQ2Zq%2Fuploads%2FFF43WA1X8Y4vADBrCi8T%2Fline_chart_light.png?alt=media&amp;token=7afc7f73-bc54-403a-9674-8a16841ec659" alt="" width="563"><figcaption></figcaption></figure>

关键创新在于 **分块大小会在运行时自动选择** ，依据可用显存。

* 如果你有更多空闲显存，就会使用更大的分块以获得更快的运行速度
* 如果显存更少，它会增加分块数量以避免内存爆掉。

这一点 **消除了手动调参** 并使我们的算法在旧 GPU、新 GPU、不同工作负载和不同序列长度下都保持稳健。

{% hint style="success" %}
由于自动调优， **更短的上下文会使用更多显存** （更少的分块）以 **避免不必要的开销**。对于上面的图表，我们调整了损失分块数量，以反映真实的显存档位。在 80GB 显存下，这可带来 >3.2× 更长的上下文。
{% endhint %}

### 🏁 Unsloth 梯度检查点增强

我们的 [Unsloth 梯度检查点](https://unsloth.ai/blog/long-context) 算法， **于 2024 年 4 月推出**，迅速流行起来，并成为行业标准，如今已集成到大多数训练包中。它将激活卸载到 CPU RAM，从而实现了 10 倍更长的上下文长度。我们的新增强利用 CUDA Streams 和其他技巧，最多只会增加 **0.1%** 训练开销，而对精度没有影响。此前它会增加 1% 到 3% 的训练开销。

{% code expandable="true" %}

```python
# 2024 年 4 月发布的原始 Unsloth 版本 - LGPLv3 许可
class Unsloth_Offloaded_Gradient_Checkpointer(torch.autograd.Function):
    @staticmethod
    @torch_amp_custom_fwd
    def forward(ctx, forward_function, hidden_states, *args):
        ctx.device = hidden_states.device
        saved_hidden_states = hidden_states.to("cpu", non_blocking = True)
        with torch.no_grad():
            output = forward_function(hidden_states, *args)
        ctx.save_for_backward(saved_hidden_states)
        ctx.forward_function, ctx.args = forward_function, args
        return output

    @staticmethod
    @torch_amp_custom_bwd
    def backward(ctx, dY):
        (hidden_states,) = ctx.saved_tensors
        hidden_states = hidden_states.to(ctx.device, non_blocking = True).detach()
        hidden_states.requires_grad_(True)
        with torch.enable_grad():
            (output,) = ctx.forward_function(hidden_states, *ctx.args)
        torch.autograd.backward(output, dY)
        return (None, hidden_states.grad,) + (None,)*len(ctx.args)
```

{% endcode %}

通过在激活一产生就立即卸载，我们将峰值激活占用降到最低，并在最需要的时候释放 GPU 内存。这大幅降低了长上下文或大批量训练中的内存压力，在这些场景下，单个解码器层的激活可能超过 2 GB。

> **因此，Unsloth 的新算法与梯度检查点贡献了大部分改进（3.2x），使得可以在单张 H100 上进行 29 万上下文长度的 GPT-OSS QLoRA 微调。**

### 🔓 平铺式 MLP：解锁 50 万以上

在以下帮助下 [Stas Bekman](https://x.com/StasBekman) （Snowflake），我们将 Snowflake 的 Arctic 长序列训练中的 Tiled MLP [论文](https://arxiv.org/abs/2506.13996) 及其博客文章集成了进来。TiledMLP 通过在进行繁重的 MLP 投影之前沿序列维度对隐藏状态进行平铺，减少激活内存并支持更长的序列长度。

**我们还引入了一些体验改进：**

我们在分块的前向重计算之间保留 RNG 状态，因此 dropout 和其他随机操作在前向与反向重放之间保持一致。这使嵌套检查点计算保持稳定，并在数值上完全一致。

{% hint style="success" %}
我们的实现会自动修补任何名称或类型为 `mlp`，因此 **的模块，因此几乎所有带有 MLP 模块的模型都可开箱即用地支持 Tiled MLP。**
{% endhint %}

**需要记住的权衡**

TiledMLP 通过额外的前向传播来节省显存。由于它位于一个已检查点化的 transformer block 内部，而且它本身也是以检查点风格编写的，它实际上会变成一个嵌套检查点：一个 **MLP 现在每步大约执行 3 次前向传播和 1 次反向传播**。作为回报，我们几乎可以把所有中间 MLP 激活从显存中移除，同时仍支持极长序列。

<figure><img src="https://2657992854-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxhOjnexMCB3dmuQFQ2Zq%2Fuploads%2FdeOJEEqucGYtbXbb7nqB%2Fbaseline_vs_unsloth_spike.png?alt=media&amp;token=3b1cdfd3-dd24-4c94-b7ec-5d1366464afb" alt=""><figcaption></figcaption></figure>

这些图比较了在长上下文训练步骤中，单个解码器层前向和反向的活跃内存时间线：不使用 Tiled MLP（左）和使用它（右）。不使用 Tiled MLP 时，峰值显存出现在 MLP 反向阶段；使用 Tiled MLP 时，它会转移到融合损失计算阶段。我们看到显存使用降低约 40%，而且由于融合损失会根据可用显存自动动态分块，在更小的 GPU 上，启用 Tiled MLP 时峰值还会更低。

<figure><img src="https://2657992854-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxhOjnexMCB3dmuQFQ2Zq%2Fuploads%2FUCx0X7S5FvaD3hUsma5j%2Fbaseline_vs_unsloth_nospike.png?alt=media&amp;token=a81b8639-21d0-43aa-a837-8209949e8742" alt=""><figcaption></figcaption></figure>

为了证明交叉熵损失不是新的瓶颈，我们固定其分块大小而不是动态选择，然后将分块数量翻倍。这显著降低了与损失相关的内存尖峰。现在两种情况下最大内存都出现在反向传播期间，总体耗时也相近，不过 Tiled MLP 会带来一点开销：一个大的 GEMM 变成许多顺序的矩阵乘法，再加上上面提到的额外前向传播。

总体而言，这个权衡是值得的：如果没有 Tiled MLP，长上下文训练大约需要 2 倍的内存使用，而有了 **Tiled MLP，单张 GPU 仅需为相同上下文长度付出约 1.3 倍的步时增加。**

**在 Unsloth 中启用 Tiled MLP：**

```py
model, tokenizer = FastLanguageModel.from_pretrained(
    ...,
    unsloth_tiled_mlp = True,
)
```

只需设置 `unsloth_tiled_mlp = True` 在 `from_pretrained` 并启用 Tiled MLP。我们遵循 Arctic 论文中的相同逻辑，并选择 `num_shards = ceil(seq_len/hidden_size)`。每个 tile 将在与模型隐藏维度相同大小的序列长度上运行，以平衡吞吐量和节省显存。

我们还与 Stas Bekman 和 [DeepSpeed](https://github.com/deepspeedai/DeepSpeed/pull/7664) 讨论了 Tiled MLP 的文档更新。

{% hint style="success" %}
下次微调内存不足时，试试开启 `unsloth_tiled_mlp = True`。只要上下文长度长于 LLM 的隐藏维度，这应该能节省一些显存。
{% endhint %}

***

**借助我们的最新更新，现在可以在单张 GPU 上用更小的模型达到 100 万上下文长度！**

**试试在我们的** [**80GB A100 Colab 笔记本**](https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/gpt_oss_\(20B\)_500K_Context_Fine_tuning.ipynb)**.**

如果你已经看到这里，我们将在本周发布一篇关于我们最新训练速度改进的新博客，敬请关注并加入我们的 [Reddit r/unsloth](https://www.reddit.com/r/unsloth/) 或我们的文档。


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://unsloth.ai/docs/zh/bo-ke/500k-context-length-fine-tuning.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
