Chapter 02
安装与依赖
2.1 装之前要先承认的事
verl 不是装一个 pip 包就完事的"应用层框架",它本质上是一组 Ray Actor 编排 + 训练后端 + 采样后端的集成器。这件事带来两个后果:
- 必须有一个能跑的 Ray 集群(单机也可以);
- 必须先装好 训练后端(FSDP-based PyTorch 或 Megatron-Core)和 采样后端(vLLM / SGLang)。
仓库的依赖矩阵很复杂,docker/ 目录下针对不同组合都有现成 Dockerfile:
docker/
├── Dockerfile.stable.sglang
├── Dockerfile.stable.trtllm
├── Dockerfile.stable.vllm
├── verl0.4-cu124-torch2.6-fa2.7.4
├── verl0.5-cu126-torch2.7-fa2.7.4
├── verl0.5-cu126-torch2.7.1-fa2.8.0
├── verl0.5-preview-cu128-torch2.7.1-fa2.8.0
├── verl0.6-cu128-torch2.8.0-fa2.7.4
├── verl0.6.1-experimental
├── ascend/ # 昇腾 NPU
├── aws/ # AWS 优化版
└── rocm/ # AMD ROCm
对新手强烈建议直接拉对应 Docker 镜像,不要自己装。
2.2 硬性依赖(来自 requirements.txt)
| 依赖 | 作用 | 注意事项 |
|---|---|---|
ray[default] | 分布式编排 | ≥ 2.40,建议最新 |
hydra-core | 配置系统 | 第 8 章会讲 |
tensordict | 张量字典容器 | >=0.8.0,<=0.10.0,!=0.9.0 锁版本严格 |
transformers | HF 模型加载 | 跟着 vLLM 版本走 |
accelerate + peft | FSDP 路径用到 | — |
liger-kernel | fused 算子加速 | 可选但推荐 |
torchdata | 数据 pipeline | — |
vllm | 采样后端默认 | requirements 里被注释掉,实际单装 |
numpy<2.0.0 | — | vLLM / Ray 兼容性 |
TransferQueue | 异步数据队列 | verl 自家轻量库 |
math_verify | 数学题 reward 验证 | R1 风格训练用 |
2.3 推荐安装路线
路线 A:Docker 镜像(最省心)
# 拉最新稳定版 vLLM 后端
docker pull verlai/verl:app-verl0.6-cu128-torch2.8.0-fa2.7.4
# 启动容器(共享主机 IPC / GPU / 网络)
docker run --gpus all -it --rm --ipc=host --net=host \
-v $(pwd):/workspace \
verlai/verl:app-verl0.6-cu128-torch2.8.0-fa2.7.4 bash
# 进容器后克隆代码(如果镜像没自带)
cd /workspace
git clone https://github.com/verl-project/verl.git
cd verl
pip install -e .
小提示
Docker tag 命名 =
app-<verl 版本>-cu<CUDA>-torch<X.Y>-fa<flash-attn>。
你拿到的硬件一旦定下来(CUDA 版 / FA 版),挑对应那一行的 tag就能避免一大半装机问题。
路线 B:源码 + venv
# 1. 装 PyTorch(CUDA 12.4 / 12.6 / 12.8 三选一)
pip install torch==2.7.1 torchvision --index-url https://download.pytorch.org/whl/cu126
# 2. 装 FlashAttention
pip install flash-attn==2.8.0 --no-build-isolation
# 3. 克隆 verl 并装
git clone https://github.com/verl-project/verl.git
cd verl
git submodule update --init --recursive recipe # ★ recipe 是独立子仓
pip install -e .
# 4. 装采样后端(任选其一)
pip install vllm==0.8.4 # vLLM
# 或
pip install "sglang[all]" # SGLang
# 5. 训练后端如要走 Megatron 路径
pip install megatron-core # 详见第 6 章
路线 C:从本地已克隆 repo 装
本项目已克隆 verl 到 repos/verl/(commit 9c38b8bb1876):
cd /Users/zjw/Documents/LLM/train/repos/verl
git submodule update --init --recursive recipe
pip install -e .
2.4 NPU / ROCm / AWS 特殊镜像
| 场景 | 镜像 / 文件 |
|---|---|
| 华为昇腾 NPU | docker/ascend/ + requirements-npu.txt |
| AMD ROCm GPU | docker/rocm/ |
| AWS Trainium | docker/aws/ |
| SGLang 后端 | docker/Dockerfile.stable.sglang |
| TensorRT-LLM 后端 | docker/Dockerfile.stable.trtllm |
2.5 recipe 子仓库
README 提到 recipe/ 已经被拆成独立仓库 + git submodule。这意味着:
- clone verl 后必须
git submodule update --init --recursive recipe才能拿到 recipe; - recipe 里有大量"业界 R1/DAPO/RLHF 训练 recipe"参考。新手通常先从这看起。
2.6 验证安装
# 1. import 不报错
python -c "import verl; print(verl.__version__)"
# 2. Ray 能起来
python -c "import ray; ray.init(); print(ray.available_resources())"
# 3. 训练入口能识别
python -m verl.trainer.main_ppo --help | head -20
# 4. vLLM 后端能 import
python -c "import vllm; print(vllm.__version__)"
# 5. 跑 unit test(约 5 分钟)
pytest tests/test_protocol.py -x
2.7 启动期 / 第一次跑训练前的最小自检
| 序 | 检查 | 命令 / 思路 |
|---|---|---|
| 1 | Ray 单机能启动 | ray start --head 看 dashboard |
| 2 | NCCL 多卡通信通 | torchrun --nproc_per_node=2 -m verl.tests.nccl_check |
| 3 | vLLM 单卡能 generate | python -c "from vllm import LLM; LLM('Qwen/Qwen3-0.6B').generate(['hello'])" |
| 4 | HF 模型能下来 | huggingface-cli download Qwen/Qwen3-4B-Instruct-2507 |
| 5 | 磁盘充足 | 训练产生大量 rollout 数据,每条 trajectory 可能几 MB |
| 6 | 共享文件系统就绪(多机) | 所有节点都能访问同路径 |
2.8 装不上的常见原因
| 报错 / 现象 | 原因 | 修复 |
|---|---|---|
ImportError: tensordict version mismatch | tensordict 版本不在锁定范围 | 装 tensordict==0.8.3 等中间稳定版 |
| vLLM import 报 CUDA 版本错 | PyTorch / CUDA / vLLM 不匹配 | 用 docker 镜像;或换 PyTorch wheel |
| Ray dashboard 起不来 | 缺 ray[default] | pip install -U "ray[default]" |
flash-attn 编译 OOM | 没限并行 | MAX_JOBS=4 pip install flash-attn --no-build-isolation |
recipe 目录为空 | submodule 没拉 | git submodule update --init --recursive recipe |
| Megatron 安装失败 | nvcc / arch list 没设 | export TORCH_CUDA_ARCH_LIST="8.0;9.0" |
2.9 真实 import 体检脚本
ds_report 那种"一键体检"verl 没有等价物,但下面这串 import 检测可以代替。把它存成 check_verl_env.py:
import importlib, sys
CORE = [
("verl", None, "✗ 核心包没装"),
("ray", "2.40", "✗ ray[default] 缺;分布式起不来"),
("hydra", None, "✗ Hydra 没装;配置系统不可用"),
("tensordict", None, "✗ tensordict 缺;DataProto 用不了"),
("torch", "2.6", "✗ torch 缺或太老"),
("transformers", None, "✗ HF 模型加载缺"),
]
ROLLOUT = [
("vllm", None, "○ vLLM 后端未装"),
("sglang", None, "○ SGLang 后端未装"),
("tensorrt_llm", None, "○ TRT-LLM 后端未装"),
]
TRAIN = [
("torch.distributed.fsdp", None, "○ FSDP 不可用(torch 太老)"),
("megatron.core", None, "○ Megatron-Core 未装;用不了 megatron 路径"),
("liger_kernel", None, "○ liger_kernel 未装;fused 算子缺"),
("flash_attn", None, "○ flash-attn 未装;Attention 慢"),
]
def chk(group, items):
print(f"\n== {group} ==")
for mod, ver, msg in items:
try:
m = importlib.import_module(mod)
v = getattr(m, "__version__", "?")
print(f" {mod:<28} [OK] {v}")
except Exception as e:
print(f" {mod:<28} {msg} ({e.__class__.__name__})")
chk("Core (必须 OK)", CORE)
chk("Rollout 后端(至少一个)", ROLLOUT)
chk("训练后端 / 加速", TRAIN)
运行 python check_verl_env.py,关注:
- Core 段必须全 OK,缺一个都跑不起来;
- Rollout 段至少一个 OK,
vllm是最常见选择; flash_attn不装训练也能跑,但 attention 慢 2-4×,强烈建议装。
2.10 关键环境变量速查
verl 启动期会去读一组环境变量。第一次跑训练前先扫一眼这张表,省得后面跟着 hang / OOM 撞墙:
| 变量 | 含义 | 典型值 |
|---|---|---|
RAY_DEDUP_LOGS | 多 worker 重复日志去重 | 0(调试时关掉) |
VLLM_LOGGING_LEVEL | vLLM 日志级别 | WARN(trainer/constants_ppo.py:30 默认) |
VLLM_ALLOW_RUNTIME_LORA_UPDATING | 允许运行时切换 LoRA 权重 | true(PEFT 路径必开) |
VLLM_DISABLE_COMPILE_CACHE | vLLM 编译 cache 关掉 | 1(绕开 vllm issue#31199) |
CUDA_DEVICE_MAX_CONNECTIONS | NCCL 内核启动并发数 | 1 |
TORCH_NCCL_AVOID_RECORD_STREAMS | 避免 NCCL stream 记录卡内存 | 1(runtime_env.yaml 默认) |
VERL_AUTO_PADDING | DataProto 自动 padding | true(短样本批不齐时用) |
VERL_DATAPROTO_SERIALIZATION_METHOD | 跨 worker 序列化方式 | numpy / torch |
TRANSFER_QUEUE_ENABLE | 启用 TransferQueue 异步管道 | 1 |
HCCL_* | 华为 NPU NCCL 等价 | 跑 NPU 时设 |
这些变量被 verl/trainer/constants_ppo.py 里 PPO_RAY_RUNTIME_ENV 注入到所有 Ray worker 里——本地 shell 设了的会优先(get_ppo_ray_runtime_env() line 50 起会跳过已存在的)。