VeRL 昇腾 NPU 与 GPU 精度对齐实战指南:从环境复现到打桩定界的完整流程
2026/9/13 4:59:13 网站建设 项目流程

VeRL 昇腾 NPU 与 GPU 精度对齐实战指南:从环境复现到打桩定界的完整流程

【免费下载链接】verlverl/HybridFlow: A Flexible and Efficient RL Post-Training Framework项目地址: https://gitcode.com/GitHub_Trending/ve/verl

在 VeRL(HybridFlow)强化学习框架中,同一套训练脚本从 GPU 迁移到昇腾 NPU 后,经常会出现 reward 曲线、梯度范数或生成文本不一致的现象。本文基于 precision_alignment.md 的系统化方法,完整讲解环境与权重对齐、输入数据对齐、确定性固定、训练精度打桩验证、推理精度定界以及 msprobe 数据 dump 对比这一整套精度对齐与问题定位流程。读完本文,你将掌握一套可复现的 NPU/GPU 精度对齐操作清单,以及用 rollout 数据复用(skip)与数据 dump 快速定位精度偏差来源的实战手段。

1. 为什么 NPU 与 GPU 之间需要精度对齐

强化学习训练是一个多阶段、长链条的迭代过程:rollout 采样 → log_prob 计算 → reward 打分 → advantage 估计 → actor/critic 更新。任何一环出现细微数值差异,都会被后续迭代逐步放大,最终表现为:

  • 两端 rewards / pg_loss / grad_norm 曲线趋势背离;
  • 同一 prompt 下生成文本乱码或与预期偏离;
  • 训练过程中出现 NaN/Inf 数值不稳定。

因此,精度对齐是 VeRL 中确保训练可复现、可调试的关键环节,其核心思路是"分层定界":先保证外部条件一致(环境、权重、数据、配置、随机性),再分别验证训练精度与推理精度,最后用数据 dump 精确定位到具体阶段。

2. 环境与权重对齐:复现的前提

2.1 依赖版本强对齐

VeRL 与 transformers 的版本必须强对齐,否则会直接影响精度结果。其他关键依赖(torch、megatron、vllm)如无法做到强对齐,也需优先保持版本一致或相近。

这是因为 VeRL 依赖 transformers 的模型实现与 tokenizer 行为,版本差异可能改变算子实现、默认参数甚至数值计算路径;megatron 负责训练侧并行,vllm 负责推理侧采样,它们的 kernel 选择同样会影响浮点结果。

2.2 模型权重对齐

检查模型权重和config.json文件是否完全一致。建议直接对比两端使用的模型目录(weights + config)的文件哈希,避免出现"看似相同、实则不同"的权重来源。

3. 输入数据对齐:消除采样差异

在训练启动脚本中显式关闭数据 shuffle,保证两端拿到完全相同的训练与验证数据顺序:

data.shuffle=False data.validation_shuffle=False

该参数可叠加在 ppo_trainer.yaml 的data分组下,通过 CLI 覆盖传入。

4. 配置对齐:逐项比对运行配置

NPU 与 GPU 精度对齐时,需检查配置是否完全对齐,包含两种手段:

  1. 直接对比脚本写入配置:将两端启动脚本逐项比对,确保网络结构、超参数、并行策略等显式配置一致;
  2. 对比运行日志中的配置:运行过程中保存日志,收集打屏输出的配置进行对比。这一手段可以暴露默认参数差异——脚本未显式写入、由各端默认值决定的参数,需要保证关键参数对齐。

5. 固定确定性:消除随机性与通信差异

5.1 固定随机种子:msprobe 的 seed_all

在环境中安装msprobe

pip install mindstudio-probe

在 worker 文件开头添加确定性函数:

from msprobe.pytorch import seed_all seed_all(mode=True)

seed_all(mode=True)会统一固定 Python、NumPy、PyTorch 等各层随机种子,确保两端随机初始化与数据采样路径一致。该确定性函数应加在 worker 入口(如 FSDP worker、megatron worker)文件开头,覆盖训练进程全生命周期。

5.2 固定通信环境变量

多卡通信下,通信库的确定性开关对精度对齐至关重要:

HCCL 通信(默认场景)

export CLOSE_MATMUL_K_SHIFT=1 export ATB_MATMUL_SHUFFLE_K_ENABLE=0 export HCCL_DETERMINISTIC="true" export VLLM_ENABLE_V1_MULTIPROCESSING=0

LCCL 通信(通过export HCCL_OP_EXPANSION_MODE="AIV"使能):

export CLOSE_MATMUL_K_SHIFT=1 export ATB_MATMUL_SHUFFLE_K_ENABLE=0 export LCCL_DETERMINISTIC=1 export ATB_LLM_LCOC_ENABLE=0 export VLLM_ENABLE_V1_MULTIPROCESSING=0

单卡无通信场景

export CLOSE_MATMUL_K_SHIFT=1 export ATB_MATMUL_SHUFFLE_K_ENABLE=0 export VLLM_ENABLE_V1_MULTIPROCESSING=0

各变量的作用:

环境变量作用
CLOSE_MATMUL_K_SHIFT=1关闭 matmul 在 K 维度的移位优化,保证归约顺序确定
ATB_MATMUL_SHUFFLE_K_ENABLE=0关闭 ATB 的 K 维度 shuffle,确保矩阵乘累加顺序确定
HCCL_DETERMINISTIC="true"/LCCL_DETERMINISTIC=1使能集合通信的确定性模式
ATB_LLM_LCOC_ENABLE=0LCCL 场景下关闭 LCOC(LLM 通信融合)优化
VLLM_ENABLE_V1_MULTIPROCESSING=0关闭 vLLM 多进程模式,保证推理侧的确定性采样路径

注意:VLLM_ENABLE_V1_MULTIPROCESSING=0在三种场景下都需要设置,因为推理引擎的进程模型同样会影响采样与张量分发行为。

6. 验证训练精度:打桩(rollout 数据复用)

6.1 什么是打桩

打桩即保留当前阶段的输入输出数据,便于从结果上对比分析。精度问题排查时,打桩是辅助定位的核心手段——最常见的做法是直接将 rollout 阶段生成的数据 dump 下来,让两端在完全相同的推理结果上继续训练,从而隔离出训练侧(log_prob、advantage、update)的差异。

6.2 第一步:在 GPU 环境生成基准数据

先跑一次 GPU 脚本,开启如下配置:

trainer.rollout_data_dir='/path/dump/data_json'

该参数在 ppo_trainer.yaml 中默认为null(见trainer.rollout_data_dir)。设置为路径后,ray_trainer.py 会在每步训练后将 rollout 结果(batch、reward 附加信息等)以 jsonl 形式保存到指定目录,作为 GPU 端的基准数据。

6.3 第二步:在 NPU 环境复现验证

NPU 上开启如下参数,复用 GPU 生成的序列,端到端运行:

skip.rollout.enable=True \ skip.rollout.dump_dir=/path/to/rollout_dump \

skip配置组在 ppo_trainer.yaml 中对应verl.utils.skip.SkipManagerConfig

  • skip.rollout.enable:是否启用 RolloutSkip,默认False
  • skip.rollout.dump_dir:rollout 数据存放目录,默认~/.verl/rollout_dump
  • skip.rollout.action:跳过时的动作,cache(按 step 精确读取对应步数据)或repeat(复用最近一次 dump 的数据),默认cache
  • skip.rollout.steps:需要跳过 rollout 的步号列表,默认空。

从源码 rollout_skip.py 可以看到其工作机理:RolloutSkip通过prepare_data在生成后将gen_batch.dpmeta.json写入{dump_dir}/{exp_name}_{project_name}/GBS{gbs}_N{n}_in{prompt_length}_out{response_length}/{step}目录;当meet_precondition检测到目标 step 已有 dump 数据时,warp_function直接通过DataProto.load_from_disk加载缓存结果,从而跳过推理采样,实现"GPU 出数据、NPU 复现训练"。

6.4 第三步:对比指标

在打桩输入相同推理结果、训练配置保持一致、随机性固定的前提下,比较 NPU 与 GPU 的rewards / pg_loss / grad_norm值是否存在差异。若这些指标一致,说明差异来源于推理/采样阶段;若不一致,则问题在训练侧(如 log_prob 计算、advantage、优化器更新)。

7. 验证推理精度:乱码定界

7.1 resharding 与 dummy run

推理正式开始前,vLLM 会进行dummy run:通过推理一个 token 来评估推理时的显存占用,进而分配显存。可以通过 vLLM 的 LLM 初始化参数load_format指定 dummy run 使用的是随机初始化的权重(dummy)还是真实权重(safetensors)。在 VeRL 中,通过参数actor_rollout_ref.rollout.load_format指定(默认值为dummy)。

关键经验:当出现推理乱码现象时,如果引擎初始化方式为load_format=dummy,则 sharding 高概率存在问题——即使换用safetensors后吐字恢复正常,sharding 问题依然存在,需要对比前向计算。

7.2 推理结果对齐

trainer.rollout_data_dir='/path/dump/data_json'

保存每步推理结果为 jsonl 文件后,可以直接打开 jsonl 文件快速确认整网推理结果是否乱码,用于推理精度问题定界。

缩小复现成本:在 dump 推理数据之前,若复现推理精度问题占用的资源较多,可以先缩小复现规模,减少需要 dump 和对比的数据量。在多 batch、长序列场景下,可以通过发送单 batch 请求、减少序列长度尝试复现。

8. dump 对比:msprobe 精细定位

定位到问题出现的阶段之后,可以通过 msprobe 工具进行数据 dump 来细致定位。完整用法见 precision_debugger.md。

8.1 适用场景

在推理或训练过程中,模型可能出现输出偏离预期、生成异常、甚至产生 NaN/Inf 等数值不稳定问题。要定位根因,需要对模型执行路径进行精细化监控,采集中间特征、权重、激活值以及各关键层的输入输出,并记录提示词、张量 dtype、硬件配置等上下文信息。通过捕获这些核心张量及元数据,可以系统性地追踪精度退化或数值错误的来源。

8.2 VeRL 侧集成方式

VeRL 通过统一 profiler 接口集成 PrecisionDebugger:global_profiler.tool=precision_debugger选择工具,global_profiler.global_tool_config.precision_debugger配置 msprobe 参数,各 role 的profiler.enable=True开启对应阶段采集:

global_profiler: tool: precision_debugger steps: [1, 2] save_path: "outputs/profile" global_tool_config: precision_debugger: _target_: verl.utils.profiler.config.PrecisionDebuggerToolConfig config_path: /path/to/config.json stages: - actor_compute_log_prob - ref_compute_log_prob - actor_update strict: False actor_rollout_ref: actor: profiler: enable: True ref: profiler: enable: True

CLI 等价写法:

python3 -m verl.trainer.main_ppo \ global_profiler.tool=precision_debugger \ global_profiler.steps='[1,2]' \ global_profiler.save_path=outputs/profile \ +global_profiler.global_tool_config.precision_debugger.config_path=/path/to/config.json \ actor_rollout_ref.actor.profiler.enable=True \ actor_rollout_ref.ref.profiler.enable=True

支持的采集阶段包括actor_updateactor_compute_log_probref_compute_log_probcompute_valuescritic_updatecompute_rm_score(rollout 生成阶段被有意跳过)。dump 输出位于{global_profiler.save_path}/step_{global_step}/{stage},msprobe 内部再按step*/rank*组织目录,可使用msprobe compare --target-path ... --golden-path ...对同一阶段的两端 dump 结果进行对比。

8.3 开销提示

PrecisionDebugger 属于重量级精度调试工具而非轻量 profiler:实测 Qwen2-0.5B 上,被采集的 L0 步骤耗时约为基线稳态的 3~4 倍,L1 步骤约为 9~10 倍;L1 每步 dump 约 11 MB,L0 约 4.4 MB。因此建议先采集少量代表性 step,再按需收窄阶段范围。

9. 完整精度对齐操作清单

将上述流程整理为可直接执行的对齐清单:

  1. 对齐版本:VeRL 与 transformers 强对齐,torch/megatron/vllm 尽量一致;
  2. 对齐权重:确认模型权重与config.json完全一致;
  3. 对齐数据:设置data.shuffle=Falsedata.validation_shuffle=False
  4. 对齐配置:直接比对脚本配置,并收集运行日志比对默认参数;
  5. 固定随机性:安装 msprobe 并在 worker 开头执行seed_all(mode=True),按 HCCL/LCCL/单卡场景设置通信确定性环境变量;
  6. 验证训练精度:GPU 上开启trainer.rollout_data_dir打桩出数据 → NPU 上开启skip.rollout.enable=True+skip.rollout.dump_dir复用数据端到端运行 → 对比 rewards/pg_loss/grad_norm;
  7. 验证推理精度:确认actor_rollout_ref.rollout.load_format的 sharding 行为,dump jsonl 检查乱码,必要时缩小复现规模;
  8. 精细 dump 对比:通过 msprobe PrecisionDebugger 采集各训练阶段张量,使用msprobe compare对比两端 dump.json 定位根因。

遵循这套流程,即可系统性地将 NPU 训练精度对齐到 GPU 基线,并能在偏差出现时快速定界到推理侧或训练侧、最终定位到具体阶段与张量。

【免费下载链接】verlverl/HybridFlow: A Flexible and Efficient RL Post-Training Framework项目地址: https://gitcode.com/GitHub_Trending/ve/verl

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询