把机器人训练从 GPU 搬到昇腾 NPU:启元 Q1 起身动作 PPO 训练全记录
把机器人训练从 GPU 搬到昇腾 NPU:启元 Q1 起身动作 PPO 训练全记录
作者:叶毅翔(天津商业大学 · GewisLab)
平台:AtomGit CANNLab 云端昇腾 NPU 环境
关键词:启元 PrimeBot Q1 / 昇腾 Ascend 910 / torch_npu / PPO / MuJoCo / 具身智能
博客文档由 GewisLab leader lhwLHWjackl的个人 a小lo爱吃棒棒糖 的博客代发,博客撰写叶毅翔同学
在真实的华为昇腾 NPU 上,用"CPU 物理仿真 + NPU 策略训练"的异构架构,完整跑通了启元 Q1 人形机器人起身(getUp)动作的 3000 轮 PPO 训练:
| 指标 | 训练开始 | 训练结束(第 3000 轮) |
|---|---|---|
| 单步奖励 mean_rew | -1.54 | 2.24 |
| 回合回报 ep_ret | -53.5 | 153.7 |
| 回合长度 ep_len | 21 | 68 |
| 吞吐 sps | ~2.1 万 | ~2.77 万 |
全程 44 分钟,占用 NPU 0.74 卡时,稳态吞吐 2.8 万 env-step/s,与官方 GPU 训练结果(约 2.5 万 step/s)吻合。
一、背景:为什么要把训练搬到 NPU
启元 PrimeBot Q1 是一款面向个人与家庭场景的人形机器人,高约 88 cm、重约 16 kg、含 22 个自由度,售价约 19999 元起。它开放二次开发接口,硬件为双板结构:运动控制板用瑞芯微芯片,大脑板用 NVIDIA Jetson Orin;软件层基于 ROS2 + FastDDS。
问题在于:机器人的强化学习策略原本是绑死在 NVIDIA CUDA 生态上的,而团队手上只有昇腾 910 系列算力。于是有了这次迁移任务——把 PPO 策略网络的训练从 GPU 搬到昇腾 NPU。
先说两个重要的结论性判断:
- 昇腾缺的不是算力,而是物理仿真的软件生态。 MuJoCo 的 Warp 后端没有 NPU 版本,所以物理仿真必须留在 CPU。
- SuperMimic 类项目跑不了昇腾。 全项目无
torch_npu,设备逻辑只接受 cpu/cuda,底层warp-lang是 CUDA-only。最终选用已完成昇腾适配的q1-task-bench(q1_ascend)实现同一目标。
二、整体架构:CPU 仿真 + NPU 策略
整体是一套异构分工架构:CPU 侧跑物理仿真,NPU 侧跑神经网络,两侧每个训练步只做两次数据搬运。

架构要点:
- 左侧(CPU):原生 MuJoCo 物理仿真,以多进程(spawn)方式并行跑 1024 个环境;Warp 无 NPU 后端,仿真固定在 CPU。
- 右侧(NPU):Actor-Critic 策略网络 + PPO 优化,前向推理输出 22 维动作,反向传播算梯度,全部张量计算由
torch_npu驱动。 - 每步两次拷贝:观测 obs(119 维)从 CPU 送到 NPU(H2D),动作 act(22 维)从 NPU 送回 CPU(D2H)。
- 设备抽象层:
devices.py按PRIMEBOT_DEVICE>CUDA_VISIBLE_DEVICES>ASCEND_RT_VISIBLE_DEVICES> 回退cpu的优先级自动解析,业务代码无需改动;在没有 NPU 的机器上自动回退 CPU,保证同一份代码在任何环境都能跑。
一句话:仿真交给擅长得多的 CPU,策略交给算力更强的 NPU,中间只搬两次数据。
三、运行环境与版本矩阵
本次验证在 CANNLab 提供的 A3 规格 NPU 实例上完成:
| 项目 | 实测值 |
|---|---|
| 实例规格 | ASCEND 1×NPU,40 vCPUs,240 GiB 内存 |
| 硬件型号 | Ascend910_9362(64 GB HBM) |
| 操作系统 | Linux(aarch64) |
| Python | 3.11.4 |
| PyTorch | 2.7.1+cpu |
| torch_npu | 2.7.1.post4 |
| MuJoCo | 3.17.0 |
| CANN | 9.1.0 系列镜像 |
| 设备可见数 | torch.npu.device_count() = 2 |
版本兼容说明:PyTorch、torch_npu、CANN 三者需保持同系列严格对应。本次镜像的 torch_npu 为 post4,与版本矩阵文档中的 post10 同属 2.7.1 系列,小规模与完整训练均正常,证明同系列兼容。
四、先验证 NPU 真的可用
启动训练前,先确认 NPU 不是"看得见"而是"能算":
import torch
import torch_npu
print(torch.npu.is_available()) # True
print(torch.npu.device_count()) # 2
print(torch.npu.get_device_name(0)) # Ascend910_9362
同时用 npu-smi 确认硬件健康、HBM 占用正常、无异常进程。然后在 NPU 上跑一个矩阵乘法并 synchronize,验证算子计算与同步链路通畅。
运行中出现的
Permission mismatchUserWarning 与NPUCachingAllocator padding size提示均为无害告警,不影响训练结果。
五、核心:3000 轮起身动作训练
5.1 训练配置
| 参数 | 值 |
|---|---|
| num_envs | 1024 |
| num_workers | 32(1024 能被 32 整除) |
| max_iterations | 3000 |
| steps_per_env | 24 |
| device | npu:0 |
| 观测维度 OBS_DIM | 119 |
| 动作维度 act_dim | 22 |
5.2 训练曲线
下图为真实 train.csv 关键节点采样,双 Y 轴分别展示回合回报与单步奖励:

可以清楚看到两个阶段的上升:前 500 轮快速拉起来(机器人从"躺平"到能发力),中段进入平台期打磨细节,最后 500 轮再次冲刺,回合回报从 83 冲到 153.7——对应的是从"勉强撑起"到"稳定站住"的过程。
5.3 起点与终点对比
| 指标 | 第 1 步 | 第 3000 步 |
|---|---|---|
| 单步奖励 mean_rew | -1.54 | 2.24 |
| 回合回报 ep_ret | -53.5 | 153.7 |
| 回合长度 ep_len | 21 | 68 |
| 吞吐 sps | 约 2.1 万 | 约 2.77 万 |
回合长度从 21 步涨到 68 步是最直观的信号:早期机器人撑不起来、动作早早结束,后期能完整跟完整个起身序列。
5.4 资源与耗时
- 总耗时约 44 分钟,NPU 占用约 0.74 卡时。
- 稳态吞吐约 2.8 万 env-step/s,与仓库官方 GPU 结果(约 2.5 万 step/s)吻合,反向验证了昇腾适配的正确性。
- 训练每 50 步自动存档,CSV 实时 flush,中断也不丢数据。
5.5 训练产物
运行目录 logs/getup-full/2026-11-06_11-56-50/:
| 文件 | 说明 |
|---|---|
args.yaml |
完整训练配置 |
train.csv |
3000 行指标 + 9 项奖励分项 |
model_3000.pt |
最终收敛策略权重 |
model_best.pt |
最优策略权重 |
5.6 起身动作演示
通过 MuJoCo 离屏渲染对 350 帧起身参考动作逐帧回放,合成 640×480、50fps、时长 7 秒的 H.264 视频,完整呈现机器人从平躺、蜷缩翻身、半蹲撑起到完全站立的过程:
q1-getup-mujoco
视频文件为
video/q1-getup-mujoco.mp4,由diagram-src/render_getup_video.py离屏渲染生成。
六、协作流程:Fork → PR
所有代码改动通过个人 fork + Pull Request 提交,保证主干稳定、改动可评审:

本次实际提交:
- 个人 fork:
https://atomgit.com/gcw_Gc5ycp3R/q1-task-bench - 分支:
fix/vec-env-obs-env-obs-dim - PR #1:修复 vec_env 测试中观测维度硬编码(122)的问题,统一使用
OBS_DIM(实际 119)。无冲突,等待团队审核。
几个容易被忽略的工程细节:
- Git 身份使用 UTF-8 无 BOM 配置,避免中文用户名乱码;
- 凭据通过令牌(PAT)写入凭据管理器,不在命令行暴露敏感信息;
- 对外提交遵循"先 issue 后 PR"的团队约定。
七、如何训练一个新动作
跑通 getUp 之后,真正有价值的沉淀是:训练任意新动作时,无需改动训练脚本与 PPO 配置,只需换一个动作文件。

六个阶段:
| 阶段 | 核心动作 | 产出物 |
|---|---|---|
| 1 资产准备 | 把动作做成合格的 .npz 并回放校验 |
50fps npz |
| 2 环境配置 | 设置 Q1_XML、Q1_MOTION,确认 NPU 可用 |
环境就绪 |
| 3 冒烟验证 | 小规模跑通,确认 device 是 npu:0 | [DONE] |
| 4 完整训练 | 放大规模训练到策略收敛 | model + train.csv |
| 5 评估部署 | evaluate 定量评估,sim2sim 回放,导出 ONNX | eval.json + ONNX |
| 6 沉淀协作 | fork → PR,写文档,打包归档 | 可复用资产 |
核心认知:新动作"新"在一个参考动作文件(.npz)。训练"起身"就让 Q1_MOTION 指向 q1_getUp.npz,训练新动作就指向新 npz——训练代码一行不用改。
八、踩坑记录
这部分对复现的人最有价值:
- spawn RuntimeError:多进程环境下主脚本缺少
if __name__ == "__main__"保护,子进程重新导入时会递归创建进程。 - 长命令被终端拆分:复杂的内联
python -c在 xterm 中易被截断,应写成独立.py再用短命令运行。 - 中文路径报错:MuJoCo C 库无法直接打开中文路径,需先切换到模型目录再用英文文件名。
- SuperMimic 不支持 NPU:仅支持 cpu/cuda,不能用于昇腾训练。
torch.logcumsumexp走 CPU fallback:个别算子在 NPU 上回退到 CPU,属正常现象。- NPU 奖励算子的 H2D/D2H 开销:环境规模较小时自定义 NPU 奖励算子未必更快,默认用 CPU 奖励,大规模环境才体现优势。
- num_envs 必须能被 num_workers 整除,否则启动即报错。
- 指标出现 NaN/Inf:先查动作数据是否有异常帧、学习率是否过大,不要带着 NaN 继续训练。
- NPU 相关 UserWarning(padding size、owner 提示等)多为镜像或分配器的无害提示。
九、复现指南
在 CANNLab WebIDE 终端中:
# 1. 设置模型与起身动作资产
export Q1_XML=/home/developer/primebot_rl_mjlab/src/assets/robots/q1_v3/xml/q1_v3_mc_without_scene.xml
export Q1_MOTION=/home/developer/primebot_rl_mjlab/src/assets/motions/q1/q1_getUp.npz
# 2. 进入项目目录
cd /mnt/workspace/q1-task-bench
# 3a. 小规模验证(约 1 分钟)
python3 scripts/run_getup_npu.py
# 3b. 完整训练(约 44 分钟,建议后台运行)
nohup python3 scripts/run_getup_full.py > full_train.log 2>&1 &
换动作只需把 Q1_MOTION 指向新的 .npz。
十、总结
- 在真实昇腾 NPU(Ascend910)上完整跑通了 Q1 起身动作的 PPO 训练,策略收敛,指标与官方 GPU 结果吻合。
- 验证了"CPU 物理仿真 + NPU 策略训练"异构架构的可行性与性能:44 分钟、0.74 卡时、2.8 万 env-step/s。
- 沉淀出"资产准备 → NPU 验证 → 完整训练 → 评估部署 → fork/PR 协作"的标准流程,可直接复用于后续任意新动作。
昇腾适配的真正门槛不在算力,而在软件生态的补齐——把 MuJoCo、PPO、设备抽象一层层对到 torch_npu 上。这一步走通之后,剩下的就是换 npz 文件而已。
附录:奖励函数与观测维度
奖励函数共 9 项:
| 类别 | 项目 | 说明 |
|---|---|---|
| 跟踪类 | root_pos、root_ori、body_pos、body_ori、body_lin_vel、body_ang_vel | 指数形式,衡量与参考动作的贴合度 |
| 约束类 | action_rate(-0.1) | 惩罚动作剧烈变化 |
| 约束类 | joint_limit(-10) | 惩罚关节越限 |
| 约束类 | self_collision(-10) | 惩罚自碰撞 |
观测维度 OBS_DIM = 119,由以下部分组成:
- 参考关节位置 22 + 参考关节速度 22
- 参考锚点重力 3 + 投影重力 3 + 基座角速度 3
- 当前关节位置(相对)22 + 关节速度 22 + 上一动作 22
动作维度 act_dim = 22。模型实测 nq = 29、nv = 28、nu = 22。
至于 sim2real……奈何小编目前还没能把 Q1 请到实验室,暂时只能在数字世界里反复折腾。真机验证这一步,就先留个 TODO 了。🥲启元机器人开发者社区 https://dev.primebot.com/
更多推荐




所有评论(0)