* update checkpoint-transfer flow and control update_weights params * test: add update_weights route validation
11 KiB
权重清除与更新
FastDeploy 支持面向 RL / RLHF Rollout 服务的动态权重清除、显存卸载和权重更新,主要用于解决以下两类问题:
- Rollout 引擎空闲时释放 GPU 显存;
- Trainer 产出新 checkpoint 后,推理服务在不重启进程的情况下切换到新权重。
本文档介绍 FastDeploy 当前支持的权重控制接口、各接口的语义,以及它们在 RLHF 训练中的典型用法。
前置条件
在 RLHF 场景下,FastDeploy 主要通过在线服务模式提供该能力。启动服务时,需要开启动态权重加载:
python -m fastdeploy.entrypoints.openai.api_server \
--model /path/to/model \
--dynamic-load-weight \
--load-strategy ipc_snapshot
--dynamic-load-weight 用于开启动态权重控制能力,--load-strategy 用于指定具体的权重更新方式。当前支持的更新模式如下:
| 模式 | load_strategy |
典型场景 | 说明 |
|---|---|---|---|
| CUDA IPC | ipc |
训练进程与推理进程同机,直接共享实时张量 | 更新来源是训练侧产出的 IPC 元信息。 |
| IPC 快照 | ipc_snapshot |
Rollout 从训练侧产出的权重快照文件重载 | 当前仓库里的 RL rollout 示例主要使用该模式。 |
| RDMA / rsync | rsync |
Trainer 发布新版本,Rollout 远端拉取 | POST /v1/update_weights 是这一模式的显式接口。 |
接口说明
旧版接口
在 FastDeploy <= 2.5 版本中,主要提供以下简化接口,保留给旧版 RL 控制流使用。
| 接口 | 方法 | 含义 | 可用条件 |
|---|---|---|---|
/clear_load_weight |
GET |
清除或卸载当前已加载权重 | 需要 dynamic_load_weight=True |
/update_model_weight |
GET |
在清除/卸载后重新加载权重 | 需要 dynamic_load_weight=True |
V1 新版接口
在 FastDeploy >= 2.6 版本中,底层控制信号通信链路经过优化,并引入了 V1 控制接口。相较于旧版接口,V1 接口在通信与执行链路上更稳定,语义更清晰,同时提供了更灵活的控制方式,包括以下接口:
| 接口 | 方法 | 请求参数 | 语义 |
|---|---|---|---|
/v1/pause |
POST |
无 | 暂停请求生成,中断 running/inflight 请求,重置调度器,并在开启 cache transfer 时暂停 cache transfer。 |
/v1/resume |
POST |
无 | 恢复请求生成和 cache transfer。 |
/v1/is_paused |
GET |
无 | 返回 {"is_paused": bool}。 |
/v1/sleep |
POST |
?tags=weight,kv_cache |
卸载指定 GPU 内存对象。支持 weight 与 kv_cache;不传时默认同时处理两者。 |
/v1/wakeup |
POST |
?tags=weight,kv_cache |
重新加载之前被卸载的权重和/或 KV Cache。成功后会自动 resume。 |
/v1/update_weights |
POST |
JSON {"version":"...", "verify_checksum": false} |
通过 worker 控制链路原地刷新模型权重。该接口主要面向 load_strategy=rsync 的远端版本更新。 |
兼容性说明
底层通信链路的优化同样适用于旧版接口。通过设置环境变量 FD_ENABLE_V1_UPDATE_WEIGHTS=1,可以将旧版接口切换到新的控制链路,在保留兼容接口形式的同时,获得更明确的执行路径和更好的可观测性。
FD_ENABLE_V1_UPDATE_WEIGHTS=0:走旧版基于共享内存的控制链路。FD_ENABLE_V1_UPDATE_WEIGHTS=1:/clear_load_weight底层等价于执行/v1/sleep,/update_model_weight底层等价于执行/v1/wakeup。对应的 pause/resume 动作分别由sleep和wakeup内部处理。
注意:无论是否设置 V1 环境变量,旧版接口都不是 RLHF 场景下推荐的标准使用方式,后续版本中也可能逐步废弃。建议优先使用 /v1/* 控制接口。
各接口语义
/v1/pause
/v1/pause 是变更模型状态前的安全边界。
它会执行以下动作:
- 停止新请求生成;
- 中断当前 running 和 inflight 请求;
- 重置调度器状态;
- 在启用多级缓存或 KV Cache 存储时暂停 cache 传输。
如果需要在每一轮 rollout 与下一轮训练之间建立清晰的切换边界,建议先调用该接口。
/v1/sleep
/v1/sleep 用于从 GPU 显存中卸载指定的运行时状态。
当前支持的 tags:
weight:清除设备上的模型权重;如果开启了相关配置,还可能一并释放通信组和 DeepEP buffer。kv_cache:清除 KV Cache;如果投机解码采用 MTP,还会同步清理 MTP cache。
如果不传 tags 参数,FastDeploy 默认等价于:
/v1/sleep?tags=weight,kv_cache
当前实现中,sleep 会自动先执行一次 pause。但新的接入方不应长期依赖这一隐式行为。
/v1/wakeup
/v1/wakeup 用于恢复通过 /v1/sleep 卸载的状态。
根据 tags 和运行配置,FastDeploy 可能执行:
- 重建通信组;
- 重建 DeepEP buffer;
- 从当前配置的数据源重新加载模型权重;
- 重建 KV Cache;
- 重新捕获 CUDA Graph。
wakeup 成功后,FastDeploy 会自动调用一次 resume。
/v1/update_weights
/v1/update_weights 用于在不卸载模型权重显存占用的情况下,直接刷新模型参数。
当前支持的请求字段:
version:可选字符串,用于指定目标 checkpoint 版本。verify_checksum:可选布尔值;默认为false。设置为true时,会在权重同步过程中校验数据完整性。
关键语义:
- 调用前引擎必须已经处于暂停状态,否则请求会失败;
- 实际更新动作只在 worker 侧执行;
- 该接口主要用于显式权重刷新,尤其是
rsync路径; - 它不会自动执行
resume。
推荐调用顺序:
POST /v1/pausePOST /v1/update_weightsPOST /v1/resume
如果除更新权重外,还希望在 rollout 轮次之间回收 GPU 显存,则更适合使用 sleep / wakeup 组合。
请求示例
基础接口
暂停引擎:
curl -X POST http://127.0.0.1:8000/v1/pause
恢复引擎:
curl -X POST http://127.0.0.1:8000/v1/resume
Sleep / Wakeup 接口
卸载权重和 KV Cache
# 同时卸载权重和 KV Cache
curl -X POST "http://127.0.0.1:8000/v1/sleep?tags=weight,kv_cache"
# 只卸载权重
curl -X POST "http://127.0.0.1:8000/v1/sleep?tags=weight"
# 不传参数,默认同时卸载两者
curl -X POST "http://127.0.0.1:8000/v1/sleep"
恢复权重和 KV Cache
# 恢复权重和 KV Cache
curl -X POST "http://127.0.0.1:8000/v1/wakeup?tags=weight,kv_cache"
# 只恢复权重
curl -X POST "http://127.0.0.1:8000/v1/wakeup?tags=weight"
# 不传参数,默认同时恢复两者
curl -X POST "http://127.0.0.1:8000/v1/wakeup"
注意:当 use_cudagraph=True 时,必须先恢复 KV Cache 再恢复权重。这意味着调用 /v1/wakeup 时如果只包含 weight tag 而不包含 kv_cache,会报错。建议保持 sleep 和 wakeup 的 tags 参数一致。
Update Weights 接口
切换到远端发布的新版本权重:
curl -X POST http://127.0.0.1:8000/v1/update_weights \
-H "Content-Type: application/json" \
-d '{
"version": "global_step_1200",
"verify_checksum": false
}'
在 RLHF 中如何使用
推荐的 Rollout 服务配置
在 RLHF 场景下,FastDeploy 的 Rollout 服务通常采用以下配置:
dynamic_load_weight=Trueload_strategy=ipc_snapshot,适合本地快照式刷新;- 或
load_strategy=rsync,适合远端版本化刷新。
仓库中的 RL rollout 工具已经按该方式接入。典型写法如下:
from fastdeploy.rl.rollout_config import RolloutModelConfig
from fastdeploy.rl.rollout_model import RolloutModel
rollout_config = RolloutModelConfig(
model_name_or_path=model_path,
tensor_parallel_size=ranks,
dynamic_load_weight=True,
load_strategy="ipc_snapshot",
)
rollout_model = RolloutModel(rollout_config)
FastDeploy 对训练侧的支持
除服务接口外,FastDeploy 还提供以下两类 RLHF 训练侧对接能力:
RolloutModel.state_dict():暴露 rollout 侧的推理参数;RolloutModel.get_name_mappings_to_training():暴露推理参数名到训练参数名的映射关系。
这两个接口可用于训练侧 checkpoint 与 rollout 侧权重布局对齐,尤其适用于推理态和训练态参数命名不完全一致的场景。
RLHF 常见工作流
以下给出 RLHF 场景下几种常见调用方式。示例中假设服务地址为 http://127.0.0.1:8000。
工作流 1:显存卸载与恢复
适用于 rollout 服务常驻,但需要在训练阶段前后释放并恢复显存的场景。推荐流程为 (pause) -> sleep -> wakeup -> (resume),其中括号内步骤为可选。
# 可选:先显式暂停引擎,建立清晰的切换边界
curl -X POST http://127.0.0.1:8000/v1/pause
# 卸载权重和 KV Cache
curl -X POST "http://127.0.0.1:8000/v1/sleep?tags=weight,kv_cache"
# 训练完成后恢复权重和 KV Cache
curl -X POST "http://127.0.0.1:8000/v1/wakeup?tags=weight,kv_cache"
# 可选:如业务侧需要显式恢复,可手动调用
curl -X POST http://127.0.0.1:8000/v1/resume
工作流 2:原地刷新到新 checkpoint
适用于服务常驻、仅需要切换到新版本权重的场景。推荐流程为 pause -> update_weights -> resume。
# 先暂停引擎
curl -X POST http://127.0.0.1:8000/v1/pause
# 原地刷新到新版本权重
curl -X POST http://127.0.0.1:8000/v1/update_weights \
-H "Content-Type: application/json" \
-d '{
"version": "global_step_1200",
"verify_checksum": false
}'
# 更新完成后恢复服务
curl -X POST http://127.0.0.1:8000/v1/resume
工作流 3:兼容旧版接口
旧版 RL 客户端仍可继续使用兼容接口,流程为 clear_load_weight -> update_model_weight。
# 清除或卸载当前权重
curl -X GET http://127.0.0.1:8000/clear_load_weight
# 训练侧完成 checkpoint 更新后,重新加载权重
curl -X GET http://127.0.0.1:8000/update_model_weight
对于新的接入方,建议优先使用 /v1/* 接口,因为其控制链路更显式,日志排查和故障定位也更直接。
其他相关配置
通信组的销毁与重建
FastDeploy 支持通过 --shutdown-comm-group-if-worker-idle 和 --no-shutdown-comm-group-if-worker-idle,显式控制在卸载权重时是否同时销毁通信组。
保留通信组通常有助于提升权重清除和重新加载过程中的稳定性;相应地,代价是卸载权重后仍会保留更多显存占用,同时 sleep / wakeup 的执行时间也可能更长。
默认情况下:
- 在 EP 场景下,默认不销毁通信组;
- 在非 EP 场景下,默认销毁通信组。
CPU 缓存的清除与重建
启用 --swap-space 后,可以通过以下环境变量控制在执行 /v1/sleep 时,是否同步清理 CPU 侧缓存,以降低训练阶段的内存压力。
默认情况下,FastDeploy 不会主动清理 CPU Cache。如需在 sleep 时一并清理,可设置:
export FD_ENABLE_SWAP_SPACE_CLEARING=1