Skip to content

[Docs] 面向后训练用户的 RL-Kernel 消融矩阵操作手册(含 MI330X/ROCm) #45

Description

@inaniloquentee

用户背景

我以一个后训练用户的视角使用 vime + RL-Kernel,希望通过一套可复现的消融实验回答:

train/rollout 的 logprob 差异和性能差异究竟来自哪个算子、哪一侧实现、哪一种 reduction/通信协议,还是来自权重同步、batch layout、采样语义等框架因素?

本 issue 希望补充一份面向后训练用户的可执行文档。它是现有 roadmap(#6)、Blackwell mismatch baseline(#24)、标准 alignment adapter(#34)和 strict/audit/auto/off 集成(#43)的操作层补充,不需要引入新的 orchestration layer。

文档需要首先解释的矩阵语义

请在一个稳定的用户文档中明确以下定义:

  • P = production/native 实现;
  • R = RL-Kernel 实现;
  • P/R = training 使用 production/native,rollout 使用 RL-Kernel;
  • R/P = training 使用 RL-Kernel,rollout 使用 production/native;
  • P/P = training 和 rollout 都使用 production/native;
  • R/R = training 和 rollout 都使用 RL-Kernel,是严格对齐基线(如果对应后端在目标硬件上可用)。

必须明确:第一个字符表示 training 侧,第二个字符表示 rollout 侧。矩阵不是一个实现的名称,而是两侧实现的笛卡尔组合。

对每个算子,建议至少提供以下四个格子:

矩阵 改变的模块 需要运行的 case 其它模块
Attention attention R/RP/RR/PP/P FFN=R/R,logp=R/R
FFN FFN R/RP/RR/PP/P attention=R/R,logp=R/R
Selected logprob logp R/RP/RR/PP/P attention=R/R,FFN=R/R

其中 R/R 不能省略。没有共同基线时,P/RR/P 的结果无法判断是单侧实现变化,还是整个实验状态发生了变化。文档也应解释何时可以运行精简矩阵、何时必须运行完整 pairwise 矩阵。

P/P 不是所有问题的“数学真值”。矩阵用于归因,正确性应由声明的 numeric contract、active-token dlogp 指标和实际 route/fallback 共同判定。

一、CUDA/H100 操作流程

1. 预检和环境变量

文档应提供不依赖某个开发者绝对路径的命令。下面是期望的命令形式,脚本应支持这些变量,或者文档应给出等价的公开入口:

export VIME_ROOT=/path/to/vime
export RL_KERNEL_ROOT=/path/to/RL-Kernel
export MEGATRON_ROOT=/path/to/Megatron-LM
export PYTHON_BIN=/path/to/validated/python
export PYTHONPATH="$VIME_ROOT:$RL_KERNEL_ROOT:$MEGATRON_ROOT:${PYTHONPATH:-}"
export PYTHONUNBUFFERED=1
export CUDA_DEVICE_MAX_CONNECTIONS=1

cd "$VIME_ROOT"
"$PYTHON_BIN" -c "import torch, vllm, vime; print('torch', torch.__version__, 'cuda', torch.version.cuda, 'cuda_available', torch.cuda.is_available(), 'gpus', torch.cuda.device_count()); print('vllm', vllm.__version__); print('vime', vime.__file__)"
python -c "import sys; print(sys.version)"
nvidia-smi -L
nvidia-smi topo -m

预检输出应保存到矩阵输出目录。至少要固定并记录:GPU 型号和数量、CUDA/driver、PyTorch、vLLM、vllm-router、Megatron、vime、RL-Kernel commit、Python 环境、TP/CP/PP/EP、colocate/disaggregated 模式、checkpoint 和 tokenizer fingerprint。

2. 先跑一个 R/R 基线

性能矩阵前应先验证完整 R/R 路径和产物完整性。以当前 Qwen3 TP2/CP2 集成为例,建议文档给出类似命令:

cd "$VIME_ROOT"

export RL_KERNEL_MODE=strict
export RL_KERNEL_ALIGNED=1
export RL_KERNEL_ATTENTION_CASE=R/R
export RL_KERNEL_FFN_CASE=R/R
export RL_KERNEL_LOGP_CASE=R/R
export RL_KERNEL_RUN_ID=ablation-rr-cuda-$(date -u +%Y%m%dT%H%M%SZ)
export RL_KERNEL_ARTIFACT_DIR="$VIME_ROOT/outputs/rlkernel/$RL_KERNEL_RUN_ID"

bash "$VIME_ROOT/scripts/run-qwen3-8B-rlkernel-tp2-cp2.sh"

如果该脚本是实验脚本而不是稳定 public API,文档必须标明这一点,并说明如何通过 python train.py 直接完成同样的运行。R/R 基线至少应确认:job 成功、样本数量正确、training/rollout 的实际 backend 与预期一致、没有 fallback、readback 和 validation report 存在、active-token dlogp 指标被记录。

3. 运行单模块消融格子

每个格子只能改变一个模块。建议稳定脚本支持以下方式设置 case:

cd "$VIME_ROOT"

export RL_KERNEL_MODE=audit
export RL_KERNEL_ALIGNED=1
export RL_KERNEL_RUN_ID=attention-pr-cuda-$(date -u +%Y%m%dT%H%M%SZ)
export RL_KERNEL_ARTIFACT_DIR="$VIME_ROOT/outputs/rlkernel/$RL_KERNEL_RUN_ID"

# Attention = P/R;FFN 和 logp 固定为 R/R
env \
  RL_KERNEL_ATTENTION_CASE=P/R \
  RL_KERNEL_FFN_CASE=R/R \
  RL_KERNEL_LOGP_CASE=R/R \
  bash "$VIME_ROOT/scripts/codex-debug-qwen3-8B-rlkernel-tp2-cp2.sh"

其它 attention 格子以及 FFN/logp 格子应给出同样的复制模板。例如:

# Attention = R/P
env RL_KERNEL_ATTENTION_CASE=R/P RL_KERNEL_FFN_CASE=R/R RL_KERNEL_LOGP_CASE=R/R \
  bash "$VIME_ROOT/scripts/codex-debug-qwen3-8B-rlkernel-tp2-cp2.sh"

# FFN = P/R;Attention 和 logp 固定为 R/R
env RL_KERNEL_ATTENTION_CASE=R/R RL_KERNEL_FFN_CASE=P/R RL_KERNEL_LOGP_CASE=R/R \
  bash "$VIME_ROOT/scripts/codex-debug-qwen3-8B-rlkernel-tp2-cp2.sh"

# logp = R/P;Attention 和 FFN 固定为 R/R
env RL_KERNEL_ATTENTION_CASE=R/R RL_KERNEL_FFN_CASE=R/R RL_KERNEL_LOGP_CASE=R/P \
  bash "$VIME_ROOT/scripts/codex-debug-qwen3-8B-rlkernel-tp2-cp2.sh"

实际脚本需要保证每个格子拥有独立的 RL_KERNEL_RUN_IDRL_KERNEL_ARTIFACT_DIR,不能覆盖前一个格子的日志。更理想的用户入口是:

VIME_ROOT="$VIME_ROOT" \
RL_KERNEL_ROOT="$RL_KERNEL_ROOT" \
PYTHON_BIN="$PYTHON_BIN" \
MATRIX_STAMP=20260830 \
MATRIX_ROOT="$VIME_ROOT/outputs/rlkernel/ablation-matrix-20260830" \
bash "$VIME_ROOT/scripts/run-ablation-matrix.sh"

如果当前 run-ablation-matrix.sh 仍然写死仓库路径或 Python 路径,应在文档工作中一并参数化;后训练用户不应为了运行矩阵而编辑开发者脚本。

4. 分析结果

"$PYTHON_BIN" "$VIME_ROOT/scripts/analyze-ablation-matrix.py" \
  --matrix-root "$VIME_ROOT/outputs/rlkernel/ablation-matrix-20260830" \
  --output "$VIME_ROOT/outputs/rlkernel/ablation-matrix-20260830/matrix-report.json"

结果至少要同时回答:

  1. 请求的 case 是什么,实际执行的 case/backend 是什么;
  2. training 和 rollout 是否各自命中了预期实现;
  3. 是否存在 fallback、extension unavailable、unsupported shape 或 runtime error;
  4. checkpoint、token、mask、padding、sampling、weight version 是否可比;
  5. active-token dlogp 的 mean/max/p50/p90/p99、mismatch count 和覆盖数;
  6. rollout、training、weight sync、total step 的 wall-clock 时间;
  7. tokens/sec、峰值显存和 OOM/CUDA/NCCL/HTTP 错误;
  8. 是否使用了 profiler、debug readback、checkpoint 写盘等会污染性能的选项。

建议产物结构如下:

<matrix-root>/
  <module>-<case>/
    matrix-case.env
    exit-code
    run.log
    readbacks/*.json
    train-data/                 # 可选,debug/replay 时生成
    bitwise-validation.json     # strict 验证时生成
  matrix-report.json

文档应明确:进程成功退出不是矩阵格子有效的充分条件;auto 下的 silent fallback 不能作为目标 RL-Kernel backend 的性能证据;跨进程 GPU kernel 累计时间不能直接当成端到端 step time;带 nsys/torch profiler 的结果只能用于定位,不能直接作为生产性能结论。

二、AMD MI330X / ROCm 操作流程

AMD 部分应和 CUDA 共用同一套矩阵语义、artifact schema 和一致性判定,但必须有单独的环境和运行说明。不能把 CUDA/H100 命令原样改几个变量后就声称适用于 MI330X。

1. MI330X/ROCm 预检

export VIME_ROOT=/path/to/vime
export RL_KERNEL_ROOT=/path/to/RL-Kernel
export MEGATRON_ROOT=/path/to/Megatron-LM
export ROCM_HOME=/opt/rocm
export HIP_PATH="$ROCM_HOME"
export ROCM_PATH="$ROCM_HOME"
export PYTHON_BIN=/path/to/validated/rocm/python
export PYTHONPATH="$VIME_ROOT:$RL_KERNEL_ROOT:$MEGATRON_ROOT:${PYTHONPATH:-}"
export PYTHONUNBUFFERED=1

cd "$VIME_ROOT"
"$PYTHON_BIN" - <<'PY'
import torch
import vllm
import vime
print("torch", torch.__version__)
print("torch.version.hip", torch.version.hip)
print("cuda_api_available", torch.cuda.is_available())
print("device_count", torch.cuda.device_count())
for i in range(torch.cuda.device_count()):
    print("device", i, torch.cuda.get_device_name(i))
print("vllm", vllm.__version__)
print("vime", vime.__file__)
PY

rocminfo | grep -m 5 -E 'Name:.*gfx|Marketing Name|Device Type'
rocm-smi

MI330X 的 gfx 目标不能仅凭型号猜测;文档可以以 gfx942 作为常见示例,但必须要求用户以本机 rocminfo 结果为准。预检应保存:MI330X 型号/GPU 数量、节点拓扑、ROCm/HIP、PyTorch ROCm、vLLM、RCCL、compiler、gfx arch、显存和驱动信息。

2. 在 MI330X 上构建/检查 RL-Kernel

如果目标 RL-Kernel backend 已实现并声明支持 ROCm/MI330X,文档应给出匹配当前 PyTorch ROCm 的构建命令:

export PYTORCH_ROCM_ARCH=gfx942   # 仅为示例,必须替换为 rocminfo 检测到的 arch

cd "$RL_KERNEL_ROOT"
ROCM_HOME="$ROCM_HOME" \
HIP_PATH="$HIP_PATH" \
ROCM_PATH="$ROCM_PATH" \
PYTORCH_ROCM_ARCH="$PYTORCH_ROCM_ARCH" \
RL_KERNEL_REQUIRE_EXT=1 \
"$PYTHON_BIN" -m pip install --no-build-isolation -e .

"$PYTHON_BIN" -c "from rl_engine import _C; print('RL-Kernel extension loaded', _C.__file__)"

如果扩展或某个算子不支持 MI330X,不能通过关闭错误检查或伪造 backend 名称让它进入 R。必须在 capability report 中标记 unsupported,并定义 strict/auto/audit/off 的行为。

3. MI330X 原生 P/P 基线

即使 RL-Kernel 在 MI330X 上还没有完整覆盖,也应允许用户先建立 native ROCm 的 P/P 基线:

cd "$VIME_ROOT"

export RL_KERNEL_MODE=off
export RL_KERNEL_ALIGNED=1
export RL_KERNEL_RUN_ID=baseline-pp-mi330x-$(date -u +%Y%m%dT%H%M%SZ)
export RL_KERNEL_ARTIFACT_DIR="$VIME_ROOT/outputs/rlkernel/$RL_KERNEL_RUN_ID"

# 使用 vime 的 MI330X/ROCm 训练-推理启动脚本;如果没有专用脚本,
# 文档应给出等价的 python train.py 命令。
bash "$VIME_ROOT/scripts/run-qwen3-8B-rlkernel-tp2-cp2.sh"

该命令在文档中必须明确使用 ROCm 兼容的 PyTorch/vLLM 配置。不要假定 TransformerEngine、CUDA custom all-reduce、CUDA IPC、CUDA Graph、NCCL 环境变量或 NVIDIA 专用 attention/GEMM backend 在 MI330X 上存在。对于每一项能力,应明确写成“已验证”“不可用”或“未测试”。

4. MI330X R/R strict 探针

当目标 backend 已报告 MI330X/ROCm capability 后,再运行 strict R/R:

cd "$VIME_ROOT"

export RL_KERNEL_MODE=strict
export RL_KERNEL_ALIGNED=1
export RL_KERNEL_ATTENTION_CASE=R/R
export RL_KERNEL_FFN_CASE=R/R
export RL_KERNEL_LOGP_CASE=R/R
export RL_KERNEL_RUN_ID=ablation-rr-mi330x-$(date -u +%Y%m%dT%H%M%SZ)
export RL_KERNEL_ARTIFACT_DIR="$VIME_ROOT/outputs/rlkernel/$RL_KERNEL_RUN_ID"

bash "$VIME_ROOT/scripts/run-qwen3-8B-rlkernel-tp2-cp2.sh"

strict 运行如果 backend 不可用,应当快速、清晰地失败,并指出是 ROCm/MI330X 不支持、构建失败、shape 不支持、通信路径不支持还是 contract 不满足。不能把 native fallback 的成功运行报告成 R/R 成功。

5. MI330X 逐格运行消融矩阵

MI330X 的矩阵和 CUDA 相同,每次只改变一个模块。示例:

cd "$VIME_ROOT"
export RL_KERNEL_MODE=audit
export RL_KERNEL_ALIGNED=1
export RL_KERNEL_RUN_ID=attention-pr-mi330x-$(date -u +%Y%m%dT%H%M%SZ)
export RL_KERNEL_ARTIFACT_DIR="$VIME_ROOT/outputs/rlkernel/$RL_KERNEL_RUN_ID"

# Attention = P/R;其它模块固定 R/R
env \
  RL_KERNEL_ATTENTION_CASE=P/R \
  RL_KERNEL_FFN_CASE=R/R \
  RL_KERNEL_LOGP_CASE=R/R \
  bash "$VIME_ROOT/scripts/codex-debug-qwen3-8B-rlkernel-tp2-cp2.sh"

# Attention = R/P
env \
  RL_KERNEL_ATTENTION_CASE=R/P \
  RL_KERNEL_FFN_CASE=R/R \
  RL_KERNEL_LOGP_CASE=R/R \
  bash "$VIME_ROOT/scripts/codex-debug-qwen3-8B-rlkernel-tp2-cp2.sh"

# FFN = P/P;Attention 和 logp 固定 R/R
env \
  RL_KERNEL_ATTENTION_CASE=R/R \
  RL_KERNEL_FFN_CASE=P/P \
  RL_KERNEL_LOGP_CASE=R/R \
  bash "$VIME_ROOT/scripts/codex-debug-qwen3-8B-rlkernel-tp2-cp2.sh"

# logp = R/R;这是 logp 模块的 aligned baseline 示例
env \
  RL_KERNEL_ATTENTION_CASE=R/R \
  RL_KERNEL_FFN_CASE=R/R \
  RL_KERNEL_LOGP_CASE=R/R \
  bash "$VIME_ROOT/scripts/codex-debug-qwen3-8B-rlkernel-tp2-cp2.sh"

如果某一格在 MI330X 上不支持,报告必须保留该格的 matrix-case.env、capability decision、失败原因和实际 backend,不能简单删除该格。文档应明确:

  • strict:unsupported 时 fail closed;
  • audit:可以运行可用路径,但必须记录请求路径未执行;
  • auto:允许 fallback,但该格不能纳入 RL-Kernel 性能结论;
  • off:native ROCm P/P 基线。

6. AMD 侧通信、Graph 和性能注意事项

AMD 文档至少应提醒:

  • NCCL 和 RCCL 的环境变量、算法选择和日志语义不能未经验证地等同;必须在实际日志中确认通信路径;
  • CUDA IPC、peer memory 和 HIP IPC/peer memory 不能默认等价;
  • CUDA Graph 与 HIP Graph 的支持依赖 ROCm/PyTorch/vLLM 版本,不能默认打开;
  • torch.cuda 是 PyTorch 在 ROCm 下复用的设备 API 名称,不代表代码可以使用 CUDA 专用行为;
  • build-time PYTORCH_ROCM_ARCH、runtime gfx arch 和实际 extension build fingerprint 必须写入报告;
  • MI330X 的 P/P、R/R 和不同 TP/CP 拓扑需要分别验证,不能把 H100 的 backend 覆盖结论迁移过来;
  • profiler、debug readback、权重写盘和首次编译必须从 measured run 中排除;
  • H100 与 MI330X 的原始 wall-clock 不能直接互相宣称“加速”,性能结论必须在同硬件、同 workload、同软件版本和同拓扑内比较。

三、统一的结果判定和报告模板

每个矩阵格子都应给出以下记录:

requested_case
actual_training_implementation
actual_rollout_implementation
training_backend_id
rollout_backend_id
contract_id
build_fingerprint
hardware_fingerprint
fallbacks
exit_code
active_token_count
logprob_abs_diff_mean
logprob_abs_diff_max
logprob_abs_diff_p50/p90/p99
mismatch_count
rollout_wall_time
training_wall_time
weight_sync_wall_time
step_wall_time
tokens_per_second
peak_memory

建议报告表格:

硬件 模块 Case training route rollout route fallback active-token max drift rollout time train time weight sync step time 结论
H100 attention R/R TBD TBD no TBD TBD TBD TBD TBD valid
H100 attention P/R TBD TBD no TBD TBD TBD TBD TBD valid
MI330X attention R/R TBD TBD no TBD TBD TBD TBD TBD valid/unsupported

一致性与性能应分开判定:

  1. route validity:请求 backend 是否实际执行,是否有 fallback;
  2. semantic validity:checkpoint、weight version、tokens、mask、padding、sampling、position/cache metadata 是否一致;
  3. numeric validity:active-token dlogp 是否满足声明的 contract;不要在 vime 文档中复制 RL-Kernel 的 tolerance 常数;
  4. performance validity:使用重复 measured runs 的 wall-clock phase timer,区分 rollout、training、weight sync 和 step;
  5. reproducibility:记录 seed、commit、环境和硬件 fingerprint,说明是单轮一致、跨运行一致还是多轮权重 bitwise 一致。

四、建议的验收标准

  • 英文和中文文档均可从 clean checkout 开始执行,不依赖开发者绝对路径;
  • 明确定义 P/RR/PP/PR/R,包括 training/rollout 字符方向;
  • CUDA/H100 章节包含预检、R/R 基线、单模块矩阵、分析命令和结果解释;
  • AMD MI330X/ROCm 章节包含预检、rocminfo/rocm-smi、ROCm Python/extension 构建、native P/P、strict R/R 探针和逐格矩阵命令;
  • 同时提供 unsupported backend、build failure、runtime fallback 和 contract mismatch 的可识别输出;
  • 每个格子均有独立 artifact 目录、route/readback、fallback 状态和机器可读 report;
  • 文档明确 smoke/bootstrap、debug/profile 和 measured performance run 的区别;
  • 文档明确 GPU 累计时间和端到端 wall-clock 的区别;
  • 文档说明 strict bitwise、train-rollout tolerance 和多轮训练 reproducibility 不是同一个声明;
  • 文档从现有 RL-Kernel integration/consistency 文档可导航到,并包含至少一个可检查的示例 report 或 manual validation recipe;
  • 如果 MI330X 上某些 RL-Kernel 后端尚未实现,文档仍能让用户运行 P/P 基线并看到明确的 R/R unsupported 结果,而不是产生 silent fallback 或错误的覆盖承诺。

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions