内存高效 RL
我们很高兴在 Unsloth 中引入更高效的强化学习 (RL),包含多项算法改进:
上下文长度提高 1.2 到 1.7 倍 无任何速度变慢且无需额外内存!
强化学习训练运行加速 10% 通过重构内核和异步数据移动实现
快 2 倍
torch.compile次 在模型加载期间
Unsloth 已经 相较于所有其他使用 FA2 的配置,提升了 RL 训练速度、上下文窗口并将 VRAM 使用减少 50–90%,但现在 Unsloth 的待机(Standby) 进一步改进了这一点。我们的 Standby 功能在限制速度下降方面独具优势,有时还能使训练更快!
现在,Qwen3-32B LoRA 16 位在单个 H100 80GB GPU 上可以达到 6,144 的上下文长度,而此前为 3,600(长 1.7 倍)。Llama-3.1-8B QLoRA 4 位可以达到 47,500 长度,而此前为 42,000(长 1.13 倍)。
我们通过各种内核优化使 RL 运行加速 10%,并在从训练切换到推理模式时移除了 CPU 与 GPU 之间的 LoRA 通信通道。最后,我们使用自定义 torch.compile 标志使 vLLM 的 rollout 加速 10%,并将编译时间减少 2 倍。
✨如何启用优化
要启用 Unsloth 的待机(Standby) 功能,请在任何 Unsloth 导入之前设置环境变量 UNSLOTH_VLLM_STANDBY 然后设置 gpu_memory_utilization = 0.95 就这样!
import os
os.environ["UNSLOTH_VLLM_STANDBY"] = "1"
from unsloth import FastLanguageModel
import torch
model, tokenizer = FastLanguageModel.from_pretrained(
model_name = "unsloth/Qwen3-8B-Base",
max_seq_length = 2048, # 对于更长的推理轨迹可以增加
load_in_4bit = False, # LoRA 16 位时为 False
fast_inference = True,
max_lora_rank = 32, # 更大的秩 = 更聪明,但更慢
gpu_memory_utilization = 0.95,
)🎓不再需要 gpu_memory_utilization!
gpu_memory_utilization!有了 Unsloth 的新 RL 改进,您再也不必担心调整或设置 gpu_memory_utilization 了——只需将其设置为 90% 或 95% 的 GPU 利用率即可——可惜 100% 无法使用,因为仍需为小张量保留一些空间。此前需要将其从 30% 调整到 95%——现在不必了!设到最大值,Unsloth 会处理剩下的!
⁉️为什么 RL 要使用这么多内存?
GRPO(以及许多 RL 变体)在很大程度上依赖生成,而生成主要由 vLLM 驱动。但这代价很高,因为它需要持续的 GPU 内存用于权重、激活和 KV 缓存.
推理占用大量 VRAM

训练也会使用 VRAM!

这意味着 RL 需要在 GPU 上同时保留两套 VRAM/内存:
推理引擎(包含模型权重、KV 缓存)
训练引擎(包含模型权重、激活、梯度、优化器状态)
当前的 RL 框架不得不在 80GB GPU 上 50/50 划分,50% 给推理,50% 给训练。从训练模式切换到推理模式时移动权重可能需要相当长的时间。
模型权重
16GB
16GB
KV 缓存
24GB
激活、梯度、优化器状态
24GB
之前的 Unsloth 版本已经智能地优化了上述内容,因为我们 直接共享 vLLM 的权重空间,这消除了模型权重的双重内存使用。例如,这释放了 16GB 的空间,可用于增加上下文长度或提高生成速度。此外,我们不需要进行内存移动,这也使训练更快。
模型权重
16GB 共享
<<< 共享
KV 缓存
24GB + 8GB = 32GB
激活、梯度、优化器状态
24GB + 8GB =32GB
🦥Unsloth 待机(Standby)
但我们可以走得更远——我们首先注意到 RL 会交替进行推理然后训练然后再推理再训练等。

这意味着理论上推理和训练的内存空间可以被重复使用,因为推理和训练是不同的模式——这就是 vLLM 的睡眠(sleep)模式功能 的作用,它有两个选项:
level = 1将权重复制到 CPU 并删除 KV 缓存level = 2删除权重并删除 KV 缓存
但请注意在 Unsloth 中我们共享 vLLM 的权重内存空间——这意味着我们需要一种新的方法来删除 KV 缓存并忽略删除权重,我们称之为 Unsloth Standby。
模型权重
16GB 共享
<<< 共享
多用途
64GB 空间
KV 缓存
激活、梯度、优化器状态
要启用此功能,只需在任何 Unsloth 导入之前将以下内容添加到所有 RL / GRPO 训练运行中:
🧪性能实验
在这里您将看到我们如何为 GRPO 基准测试内存使用和上下文长度。请注意我们进行 每个提示 2 次生成,因为为了使 GRPO 生效,我们需要至少 2 次生成以计算样本均值和方差。 如果没有 2 次生成,单样本的标准差为 0。这会导致使用该值的优势 (reward - mean)/std 变得未定义.
这意味着就 GRPO 而言,Qwen-3 32B 的最大上下文长度 6,144 实际上是乘以 2 次生成,即长度为 12,288。
我们下面提供了针对 Llama-3.1 8B 在 LoRA(16 位)和 QLoRA(4 位)两种情况下的实验:

如果您注意到任何训练时间差异,也不会太大。在我们同条件比较中,我们注意到 <1% 的训练时间减慢或甚至加速,这可能归因于误差范围。
我们还推测,由于内存压力降低,可能会出现提速,因此 CUDA 内存分配器端的内存清理可能减少。

在上图中,您可以看到在单个 T4 GPU 上 Qwen 3 4B 的基线模式与待机模式之间的差异。 我们可以将 vLLM 的 gpu_memory_utilisation 拉高到高达 0.95,而不用担心会影响训练。这意味着您可以容纳更高的上下文长度序列并处理更多序列。例如在第一个案例中,我们有足够的内存来容纳并处理 32K 长度的序列,前提是训练允许,而此前任何超过 2K 的输入可能都无法放入并导致 OOM(内存不足)。
standby True
vllm_gpu_util 0.95
num_gen 2
grad_acc_steps 2
运行 40 步 / 40 分钟
14.5 GiB(由 vllm_gpu_util 设置)
足够容纳 32K KVCache,使用 2-4K 的分块,或例如 16K KVCache + 16K 分块
standby True
vllm_gpu_util 0.9
num_gen 2
grad_acc_steps 2
在 40 分钟内运行 32 步
13.8 GiB(由… 设置)
大概足够容纳约 28K 的 KVCache,使用 2-4K 的分块,或例如 15K KVCache + 15K 分块
standby False
vllm_gpu_util 0.9
num_gen 2
grad_acc_steps 2
模型加载但无法训练,因为即使批次大小为 1 也无法放下
OOM(内存不足)
standby False
vllm_gpu_util 0.8
num_gen 2
grad_acc_steps 2
模型加载但无法训练,因为即使批次大小为 1 也无法放下
OOM(内存不足)
standby False
vllm_gpu_util 0.7
num_gen 2
grad_acc_steps 2
训练正常
28 步耗时 39 分钟
约 15.1 GiB
任何稍长的输入都会在 colab 上导致 OOM
standby True
vllm_gpu_util 0.7
num_gen 2
grad_acc_steps 2
训练正常
29 步耗时 40 分钟
13 GiB,但大多数时间在 10–11GB 左右
在相同配置下,我们节省了 2 GiB,即 15% 的内存。 对更长的序列而言节省可能更高
H100 实验
Qwen2.5-14B-Instruct
NVIDIA H100 80GB PCIe
32,768
8
4
在我们下面可折叠的结果中,您可以看到峰值内存使用存在 9 GiB 的差异(请注意在我们的情况中 90% 的时间 GPU 内存使用等同于峰值内存)。 作为对比,使用 TRL 和 LoRA 我们最多只能微调一个 8B 参数模型,并且最大上下文长度为 1024(少 32 倍)。 任何具有更高序列长度的配置(在相似配置下)都会导致进程因 OOM 而失败。
下图显示了待机与非待机训练在 Unsloth 中的比较。数据取三次运行的平均以确保指标不噪声化。事实上,如果放大观察,您会发现启用待机还能使其更快,这很可能如前所述是由于内存压力减少。

之前的 A100 40GB 实验
在我们之前针对 A100 40GB GPU、使用 Qwen-2.5-3b-instruct 且每个样本 8 次生成的实验中,我们观察到在未启用待机时,GRPO 训练(模型以 16 位加载、LoRA、仅权重可训练)最多只能容纳 6K 的序列长度。使用我们的待机功能,我们能够容纳 10K 及更高! 相比之下,TRL 在保持相同批次大小的情况下最多只能给出 1K 的上下文长度。

🎉其他优化
我们现在选择了更好的编译标志并将编译时间减少了 50% 或更多。我们还成功对任意 vLLM 版本进行动态补丁以处理 gc.collect 为向后兼容性做得更好,灵感来自这个 vLLM pull request(拉取请求)。这将编译时间从 2 分钟缩短到不到 40 秒。
我们还对 torch.compile 标志进行了优化并尝试开启某些标志——不幸的是 combo_kernels 和 multi_kernel 在 vLLM 0.10 与 Torch 2.8/2.9 nightly 上无法正常工作,并且 coordinate_descent_tuning 使得所有内核的自动调优显著变慢。以前编译不到一分钟,但启用后耗时超过 13 分钟以上,且性能提升很小。
📚GRPO 笔记本
我们所有的 GRPO 笔记本默认开启 Unsloth Standby 并应用所有优化!请参见 https://docs.unsloth.ai/get-started/unsloth-notebooks 获取我们所有的 GRPO 笔记本,或试试下面的:
Qwen3(4B) - 高级 GRPO LoRA
DeepSeek-R1-0528-Qwen3(8B) (用于多语言用例)
Llama 3.2(3B) - 高级 GRPO LoRA
最后更新于
这有帮助吗?

