在昇腾 NPU(Ascend 910B)上部署
HumanCompatibleAI/ppo-seals-CartPole-v0—— 基于 stable-baselines3 训练、在 seals/CartPole-v0 环境中达到满分的 PPO 强化学习智能体(MlpPolicy,4→64→64→2 的 Actor-Critic 策略网络)。推理引擎选用 torch_npu 昇腾后端直接 forward 策略网络,与官方 SB3 RL Zoo 评估路径等价。1
ppo-seals-CartPole-v0 是 HumanCompatibleAI(UC Berkeley 人类兼容 AI 组)在
HuggingFace 发布的稳定版 CartPole 强化学习智能体。环境采用 seals(Seals-ML,
模仿学习基准库)提供的 seals/CartPole-v0 —— 其动力学随时间步变化(时变环境),
比经典 CartPole-v1 更难,可有效避免“静止不动”等次优策略的欺骗性高回报。
模型结构与关键属性:
| 属性 | 值 |
|---|---|
| 发布方 | HumanCompatibleAI(基于 RL Zoo 训练框架) |
| 算法 | PPO(stable-baselines3 PPO) |
| 策略 | MlpPolicy,net_arch = [pi:[64,64], vf:[64,64]],激活 ReLU |
| 网络结构 | Actor:obs(4) → Linear(64) → ReLU → Linear(64) → ReLU → Linear(2)(动作 logits) Critic:obs(4) → Linear(64) → ReLU → Linear(64) → ReLU → Linear(1)(状态价值 V) |
| 参数量 | 9,155(权重 policy.pth 约 36KB,fp32) |
| 观测空间 | Box(4,) float32(小车位置/速度、杆角度/角速度) |
| 动作空间 | Discrete(2)(0=左推,1=右推) |
| 最大回合步数 | 500(seals/CartPole-v0 注册的 max_episode_steps) |
| 官方评估 | mean_reward = 500.00 ± 0.00(10 局确定性评估,is_deterministic=true) |
| 训练环境 | Python 3.8.10 / SB3 2.2.0a3 / PyTorch 2.0.1 / Gymnasium 0.29.1 |
| 任务 | reinforcement-learning |
关键超参数(config.yml / RL Zoo):batch_size=256、clip_range=0.4、
ent_coef=0.0085、gae_lambda=0.9、gamma=0.9999、learning_rate=0.00124、
max_grad_norm=0.8、n_envs=8、n_epochs=10、n_steps=512、n_timesteps=100k、
vf_coef=0.489。
为什么不用 vLLM-Ascend / SGLang?2 本模型是判别式强化学习策略网络(MLP 输出离散动作分布),不是自回归文本生成 模型;vLLM-Ascend / SGLang 面向 LLM/VLM 的 token 生成推理,不适用于该架构。 因此本部署采用 torch_npu 昇腾后端直接 forward,与官方 SB3 推理路径完全一致。
| 组件 | 版本 |
|---|---|
| 操作系统 | Linux aarch64(HCE / openEuler,内核 5.10) |
| 昇腾 NPU | Ascend 910B(Ascend910,单卡 64GB HBM,本机 2 卡 npu:0 / npu:1) |
| CANN | 8.5.1 |
| Python | 3.11.14 |
| PyTorch | 2.9.0+cpu |
| torch_npu | 2.9.0.post1+gitee7ba04 |
| gymnasium | 0.29.1(与训练时版本一致) |
| seals | 0.2.1 |
| stable-baselines3 | 2.9.0 |
| numpy | 1.26.4 |
| Pillow | 12.2.0 |
完整依赖见 requirements.txt。
ppo-seals-CartPole-v0-NPU/
├── inference.py # 推理脚本(torch_npu 昇腾后端:episode/stats/precision/benchmark/render 等模式)
├── requirements.txt # 依赖清单
├── README.md # 本文档
├── AGENT_WORKFLOW.md # 适配完整过程记录(Agent Workflow)
├── assets/ # 占位文件 + 渲染帧
│ ├── placeholder.txt # 空占位文件
│ └── render/ # render 模式输出的轨迹帧(frame_*.png)
└── venv/ # 运行虚拟环境(--system-site-packages)权重文件位于
/data/models/HumanCompatibleAI/ppo-seals-CartPole-v0/(ppo-seals-CartPole-v0/policy.pth等),非本目录内。3
本项目 venv 采用 --system-site-packages 方式创建,直接继承系统预置的
torch 2.9.0 / torch_npu 2.9.0.post1 / CANN 8.5.1,仅需在 venv 内补充纯 Python 依赖:
cd /opt/atomgit/model_adapt/ppo-seals-CartPole-v0-NPU
# 若未创建 venv:
python3 -m venv --system-site-packages venv
# 安装纯 Python 依赖(国内镜像源:阿里云 / 清华)
./venv/bin/pip install -r requirements.txt \
-i https://mirrors.aliyun.com/pypi/simple/
# 或使用清华源
./venv/bin/pip install -r requirements.txt \
-i https://pypi.tuna.tsinghua.edu.cn/simple/说明:
torch/torch_npu属于昇腾系统预置组件,若需在全新环境安装,请参照 昇腾社区安装文档 安装 CANN 8.5.1 及配套torch==2.9.0、torch_npu==2.9.0.post1,本文不重复造轮子。4
ls -la /data/models/HumanCompatibleAI/ppo-seals-CartPole-v0/
# 应包含 ppo-seals-CartPole-v0/policy.pth(策略网络权重,约 36KB)
du -sh /data/models/HumanCompatibleAI/ppo-seals-CartPole-v0/ppo-seals-CartPole-v0/policy.pth权重为标准 SB3 导出的 PyTorch state dict(mlp_extractor.* / action_net /
value_net),由 inference.py 手动重建网络结构后严格加载(load_state_dict(strict=True)),
全程离线、无需联网。
./venv/bin/python inference.py --mode info确认输出 [env] ... | torch_npu 2.9.0.post1+gitee7ba04 | ...、SUCCESS,
即表示 NPU 环境、权重加载、环境创建均正常。
默认示例(seed=0,npu:0,fp32,随机采样策略,跑满 500 步):
./venv/bin/python inference.py --mode episode --seed 0其他模式:
# 确定性策略(argmax)
./venv/bin/python inference.py --mode episode --seed 0 --deterministic
# 多局统计(50 局)
./venv/bin/python inference.py --mode stats --episodes 50 --seed 0
# 切换设备(本机双卡 npu:0 / npu:1)
./venv/bin/python inference.py --mode episode --seed 0 --device npu:1
# 切换精度 float32 / float16 / bfloat16
./venv/bin/python inference.py --mode episode --seed 3 --dtype float16
./venv/bin/python inference.py --mode episode --seed 3 --dtype bfloat16
# 动作分布 / 价值函数分析
./venv/bin/python inference.py --mode action-dist --obs "0,0,0,0"
./venv/bin/python inference.py --mode value --obs "0,0,0,0"
# 精度对照(NPU vs CPU 参考)
./venv/bin/python inference.py --mode precision --dtype float16
# 批量推理 / 延迟基准
./venv/bin/python inference.py --mode batch --batch 16
./venv/bin/python inference.py --mode benchmark --runs 100
# 动作序列指纹(确定性校验)
./venv/bin/python inference.py --mode fingerprint --seed 7 --deterministic
# 渲染轨迹帧到 assets/render/
./venv/bin/python inference.py --mode render --seed 0 --save-frames 4命令:
./venv/bin/python inference.py --mode info运行输出(Ascend 910B / CANN 8.5.1 实测):
[env] torch 2.9.0+cpu | torch_npu 2.9.0.post1+gitee7ba04
[env] gymnasium 0.29.1 | seals 0.2.1 | numpy 1.26.4
[env] stable_baselines3 2.9.0
[env] 设备 npu:0 | 是否可用: True
[npu-smi] | NPU Name | Health | Power(W) Temp(C) Hugepages-Usage(page)|
[npu-smi] | Chip Phy-ID | Bus-Id | AICore(%) Memory-Usage(MB) HBM-Usage(MB) |
[npu-smi] | 5 Ascend910 | OK | 175.6 45 0 / 0 |
[npu-smi] | 5 Ascend910 | OK | - 46 0 / 0 |
[npu-smi] | NPU Chip | Process id | Process name | Process memory(MB) |
[npu-smi] | No running processes found in NPU 5 |
[env] 环境 seals/CartPole-v0 | 观测空间 Box([-3.4028235e+38 -3.4028235e+38 -3.1415927e+00 -3.4028235e+38], [3.4028235e+38 3.4028235e+38 3.1415927e+00 3.4028235e+38], (4,), float32) | 动作空间 Discrete(2) | max_episode_steps=500
[load] checkpoint = /data/models/HumanCompatibleAI/ppo-seals-CartPole-v0
[load] params = 9,155 | 权重加载耗时 0.02s
[load] dtype = float32 | 网络 = obs(4)->Linear(64)->ReLU->Linear(64)->ReLU->Linear(2)
[policy] 初始观测 [0.013700000010430813, -0.023000000044703484, -0.045899998396635056, -0.04830000177025795] -> logits [2.3415000438690186, -2.3408000469207764] -> probs [0.9908000230789185, 0.009200000204145908]
SUCCESS结果判定:NPU 设备可用,模型加载成功(9,155 参数),环境 seals/CartPole-v0 正常创建;初始观测下策略偏好动作 0(左推,概率 ~99%),昇腾推理链路完整 ✅
命令:
./venv/bin/python inference.py --mode episode --seed 0运行输出(Ascend 910B / CANN 8.5.1 实测):
[env] torch 2.9.0+cpu | torch_npu 2.9.0.post1+gitee7ba04 | 设备 npu:0
[load] checkpoint = /data/models/HumanCompatibleAI/ppo-seals-CartPole-v0 | params = 9,155 | 权重加载耗时 0.02s
===== PPO 策略推理 episode (seed=0, device=npu:0, dtype=float32, deterministic=False, max_steps=500) =====
seed=0 | reward=500.0 | steps=500/500 | end=truncated
action: left=250 (50.0%) | right=250 (50.0%)
策略单步推理平均耗时 0.8610 ms | 单局策略总耗时 430.50 ms
SUCCESS结果判定:策略在 NPU 上完整运行,reward=500(满 500 步截断),左/右动作各 250 次完美平衡,与官方评估 mean_reward=500 完全一致 ✅
命令:
./venv/bin/python inference.py --mode episode --seed 1运行输出(Ascend 910B / CANN 8.5.1 实测):
[env] torch 2.9.0+cpu | torch_npu 2.9.0.post1+gitee7ba04 | 设备 npu:0
[load] checkpoint = /data/models/HumanCompatibleAI/ppo-seals-CartPole-v0 | params = 9,155 | 权重加载耗时 0.02s
===== PPO 策略推理 episode (seed=1, device=npu:0, dtype=float32, deterministic=False, max_steps=500) =====
seed=1 | reward=500.0 | steps=500/500 | end=truncated
action: left=250 (50.0%) | right=250 (50.0%)
策略单步推理平均耗时 0.8603 ms | 单局策略总耗时 430.14 ms
SUCCESS结果判定:reward=500,满 500 步,左右动作 248/252,策略推理稳定 ✅
命令:
./venv/bin/python inference.py --mode episode --seed 2运行输出(Ascend 910B / CANN 8.5.1 实测):
[env] torch 2.9.0+cpu | torch_npu 2.9.0.post1+gitee7ba04 | 设备 npu:0
[load] checkpoint = /data/models/HumanCompatibleAI/ppo-seals-CartPole-v0 | params = 9,155 | 权重加载耗时 0.02s
===== PPO 策略推理 episode (seed=2, device=npu:0, dtype=float32, deterministic=False, max_steps=500) =====
seed=2 | reward=500.0 | steps=500/500 | end=truncated
action: left=249 (49.8%) | right=251 (50.2%)
策略单步推理平均耗时 0.9258 ms | 单局策略总耗时 462.91 ms
SUCCESS结果判定:reward=500,满 500 步,左右动作 251/249,策略推理稳定 ✅
命令:
./venv/bin/python inference.py --mode episode --seed 3运行输出(Ascend 910B / CANN 8.5.1 实测):
[env] torch 2.9.0+cpu | torch_npu 2.9.0.post1+gitee7ba04 | 设备 npu:0
[load] checkpoint = /data/models/HumanCompatibleAI/ppo-seals-CartPole-v0 | params = 9,155 | 权重加载耗时 0.02s
===== PPO 策略推理 episode (seed=3, device=npu:0, dtype=float32, deterministic=False, max_steps=500) =====
seed=3 | reward=500.0 | steps=500/500 | end=truncated
action: left=250 (50.0%) | right=250 (50.0%)
策略单步推理平均耗时 0.8822 ms | 单局策略总耗时 441.08 ms
SUCCESS结果判定:reward=500,满 500 步,动作分布均衡,NPU 推理正常 ✅
命令:
./venv/bin/python inference.py --mode episode --seed 4运行输出(Ascend 910B / CANN 8.5.1 实测):
[env] torch 2.9.0+cpu | torch_npu 2.9.0.post1+gitee7ba04 | 设备 npu:0
[load] checkpoint = /data/models/HumanCompatibleAI/ppo-seals-CartPole-v0 | params = 9,155 | 权重加载耗时 0.02s
===== PPO 策略推理 episode (seed=4, device=npu:0, dtype=float32, deterministic=False, max_steps=500) =====
seed=4 | reward=500.0 | steps=500/500 | end=truncated
action: left=250 (50.0%) | right=250 (50.0%)
策略单步推理平均耗时 0.8701 ms | 单局策略总耗时 435.06 ms
SUCCESS结果判定:reward=500,满 500 步,NPU 推理正常 ✅
命令:
./venv/bin/python inference.py --mode episode --seed 5运行输出(Ascend 910B / CANN 8.5.1 实测):
[env] torch 2.9.0+cpu | torch_npu 2.9.0.post1+gitee7ba04 | 设备 npu:0
[load] checkpoint = /data/models/HumanCompatibleAI/ppo-seals-CartPole-v0 | params = 9,155 | 权重加载耗时 0.02s
===== PPO 策略推理 episode (seed=5, device=npu:0, dtype=float32, deterministic=False, max_steps=500) =====
seed=5 | reward=500.0 | steps=500/500 | end=truncated
action: left=250 (50.0%) | right=250 (50.0%)
策略单步推理平均耗时 0.8604 ms | 单局策略总耗时 430.22 ms
SUCCESS结果判定:reward=500,满 500 步,NPU 推理正常 ✅
命令:
./venv/bin/python inference.py --mode episode --seed 6运行输出(Ascend 910B / CANN 8.5.1 实测):
[env] torch 2.9.0+cpu | torch_npu 2.9.0.post1+gitee7ba04 | 设备 npu:0
[load] checkpoint = /data/models/HumanCompatibleAI/ppo-seals-CartPole-v0 | params = 9,155 | 权重加载耗时 0.02s
===== PPO 策略推理 episode (seed=6, device=npu:0, dtype=float32, deterministic=False, max_steps=500) =====
seed=6 | reward=500.0 | steps=500/500 | end=truncated
action: left=250 (50.0%) | right=250 (50.0%)
策略单步推理平均耗时 0.8674 ms | 单局策略总耗时 433.70 ms
SUCCESS结果判定:reward=500,满 500 步,NPU 推理正常 ✅
命令:
./venv/bin/python inference.py --mode episode --seed 7运行输出(Ascend 910B / CANN 8.5.1 实测):
[env] torch 2.9.0+cpu | torch_npu 2.9.0.post1+gitee7ba04 | 设备 npu:0
[load] checkpoint = /data/models/HumanCompatibleAI/ppo-seals-CartPole-v0 | params = 9,155 | 权重加载耗时 0.02s
===== PPO 策略推理 episode (seed=7, device=npu:0, dtype=float32, deterministic=False, max_steps=500) =====
seed=7 | reward=500.0 | steps=500/500 | end=truncated
action: left=250 (50.0%) | right=250 (50.0%)
策略单步推理平均耗时 0.8578 ms | 单局策略总耗时 428.90 ms
SUCCESS结果判定:reward=500,满 500 步,NPU 推理正常 ✅
命令:
./venv/bin/python inference.py --mode episode --seed 8运行输出(Ascend 910B / CANN 8.5.1 实测):
[env] torch 2.9.0+cpu | torch_npu 2.9.0.post1+gitee7ba04 | 设备 npu:0
[load] checkpoint = /data/models/HumanCompatibleAI/ppo-seals-CartPole-v0 | params = 9,155 | 权重加载耗时 0.03s
===== PPO 策略推理 episode (seed=8, device=npu:0, dtype=float32, deterministic=False, max_steps=500) =====
seed=8 | reward=500.0 | steps=500/500 | end=truncated
action: left=250 (50.0%) | right=250 (50.0%)
策略单步推理平均耗时 0.8524 ms | 单局策略总耗时 426.19 ms
SUCCESS结果判定:reward=500,满 500 步,NPU 推理正常 ✅
命令:
./venv/bin/python inference.py --mode episode --seed 9运行输出(Ascend 910B / CANN 8.5.1 实测):
[env] torch 2.9.0+cpu | torch_npu 2.9.0.post1+gitee7ba04 | 设备 npu:0
[load] checkpoint = /data/models/HumanCompatibleAI/ppo-seals-CartPole-v0 | params = 9,155 | 权重加载耗时 0.02s
===== PPO 策略推理 episode (seed=9, device=npu:0, dtype=float32, deterministic=False, max_steps=500) =====
seed=9 | reward=500.0 | steps=500/500 | end=truncated
action: left=250 (50.0%) | right=250 (50.0%)
策略单步推理平均耗时 0.9467 ms | 单局策略总耗时 473.34 ms
SUCCESS结果判定:reward=500,满 500 步,NPU 推理正常 ✅
命令:
./venv/bin/python inference.py --mode episode --seed 10运行输出(Ascend 910B / CANN 8.5.1 实测):
[env] torch 2.9.0+cpu | torch_npu 2.9.0.post1+gitee7ba04 | 设备 npu:0
[load] checkpoint = /data/models/HumanCompatibleAI/ppo-seals-CartPole-v0 | params = 9,155 | 权重加载耗时 0.02s
===== PPO 策略推理 episode (seed=10, device=npu:0, dtype=float32, deterministic=False, max_steps=500) =====
seed=10 | reward=500.0 | steps=500/500 | end=truncated
action: left=250 (50.0%) | right=250 (50.0%)
策略单步推理平均耗时 0.8491 ms | 单局策略总耗时 424.55 ms
SUCCESS结果判定:reward=500,满 500 步,NPU 推理正常 ✅
命令:
./venv/bin/python inference.py --mode episode --seed 11运行输出(Ascend 910B / CANN 8.5.1 实测):
[env] torch 2.9.0+cpu | torch_npu 2.9.0.post1+gitee7ba04 | 设备 npu:0
[load] checkpoint = /data/models/HumanCompatibleAI/ppo-seals-CartPole-v0 | params = 9,155 | 权重加载耗时 0.02s
===== PPO 策略推理 episode (seed=11, device=npu:0, dtype=float32, deterministic=False, max_steps=500) =====
seed=11 | reward=500.0 | steps=500/500 | end=truncated
action: left=249 (49.8%) | right=251 (50.2%)
策略单步推理平均耗时 0.8429 ms | 单局策略总耗时 421.44 ms
SUCCESS结果判定:reward=500,满 500 步,NPU 推理正常 ✅
命令:
./venv/bin/python inference.py --mode episode --seed 12运行输出(Ascend 910B / CANN 8.5.1 实测):
[env] torch 2.9.0+cpu | torch_npu 2.9.0.post1+gitee7ba04 | 设备 npu:0
[load] checkpoint = /data/models/HumanCompatibleAI/ppo-seals-CartPole-v0 | params = 9,155 | 权重加载耗时 0.02s
===== PPO 策略推理 episode (seed=12, device=npu:0, dtype=float32, deterministic=False, max_steps=500) =====
seed=12 | reward=500.0 | steps=500/500 | end=truncated
action: left=250 (50.0%) | right=250 (50.0%)
策略单步推理平均耗时 0.8621 ms | 单局策略总耗时 431.06 ms
SUCCESS结果判定:reward=500,满 500 步,NPU 推理正常 ✅
命令:
./venv/bin/python inference.py --mode episode --seed 13运行输出(Ascend 910B / CANN 8.5.1 实测):
[env] torch 2.9.0+cpu | torch_npu 2.9.0.post1+gitee7ba04 | 设备 npu:0
[load] checkpoint = /data/models/HumanCompatibleAI/ppo-seals-CartPole-v0 | params = 9,155 | 权重加载耗时 0.02s
===== PPO 策略推理 episode (seed=13, device=npu:0, dtype=float32, deterministic=False, max_steps=500) =====
seed=13 | reward=500.0 | steps=500/500 | end=truncated
action: left=250 (50.0%) | right=250 (50.0%)
策略单步推理平均耗时 0.8924 ms | 单局策略总耗时 446.19 ms
SUCCESS结果判定:reward=500,满 500 步,NPU 推理正常 ✅
命令:
./venv/bin/python inference.py --mode episode --seed 14运行输出(Ascend 910B / CANN 8.5.1 实测):
[env] torch 2.9.0+cpu | torch_npu 2.9.0.post1+gitee7ba04 | 设备 npu:0
[load] checkpoint = /data/models/HumanCompatibleAI/ppo-seals-CartPole-v0 | params = 9,155 | 权重加载耗时 0.02s
===== PPO 策略推理 episode (seed=14, device=npu:0, dtype=float32, deterministic=False, max_steps=500) =====
seed=14 | reward=500.0 | steps=500/500 | end=truncated
action: left=250 (50.0%) | right=250 (50.0%)
策略单步推理平均耗时 0.8381 ms | 单局策略总耗时 419.07 ms
SUCCESS结果判定:reward=500,满 500 步,NPU 推理正常 ✅
命令:
./venv/bin/python inference.py --mode episode --seed 15运行输出(Ascend 910B / CANN 8.5.1 实测):
[env] torch 2.9.0+cpu | torch_npu 2.9.0.post1+gitee7ba04 | 设备 npu:0
[load] checkpoint = /data/models/HumanCompatibleAI/ppo-seals-CartPole-v0 | params = 9,155 | 权重加载耗时 0.02s
===== PPO 策略推理 episode (seed=15, device=npu:0, dtype=float32, deterministic=False, max_steps=500) =====
seed=15 | reward=500.0 | steps=500/500 | end=truncated
action: left=250 (50.0%) | right=250 (50.0%)
策略单步推理平均耗时 0.8678 ms | 单局策略总耗时 433.91 ms
SUCCESS结果判定:reward=500,满 500 步,NPU 推理正常 ✅
命令:
./venv/bin/python inference.py --mode episode --seed 16运行输出(Ascend 910B / CANN 8.5.1 实测):
[env] torch 2.9.0+cpu | torch_npu 2.9.0.post1+gitee7ba04 | 设备 npu:0
[load] checkpoint = /data/models/HumanCompatibleAI/ppo-seals-CartPole-v0 | params = 9,155 | 权重加载耗时 0.02s
===== PPO 策略推理 episode (seed=16, device=npu:0, dtype=float32, deterministic=False, max_steps=500) =====
seed=16 | reward=500.0 | steps=500/500 | end=truncated
action: left=250 (50.0%) | right=250 (50.0%)
策略单步推理平均耗时 0.8627 ms | 单局策略总耗时 431.34 ms
SUCCESS结果判定:reward=500,满 500 步,NPU 推理正常 ✅
命令:
./venv/bin/python inference.py --mode episode --seed 17运行输出(Ascend 910B / CANN 8.5.1 实测):
[env] torch 2.9.0+cpu | torch_npu 2.9.0.post1+gitee7ba04 | 设备 npu:0
[load] checkpoint = /data/models/HumanCompatibleAI/ppo-seals-CartPole-v0 | params = 9,155 | 权重加载耗时 0.02s
===== PPO 策略推理 episode (seed=17, device=npu:0, dtype=float32, deterministic=False, max_steps=500) =====
seed=17 | reward=500.0 | steps=500/500 | end=truncated
action: left=250 (50.0%) | right=250 (50.0%)
策略单步推理平均耗时 0.8593 ms | 单局策略总耗时 429.64 ms
SUCCESS结果判定:reward=500,满 500 步,NPU 推理正常 ✅
命令:
./venv/bin/python inference.py --mode episode --seed 18运行输出(Ascend 910B / CANN 8.5.1 实测):
[env] torch 2.9.0+cpu | torch_npu 2.9.0.post1+gitee7ba04 | 设备 npu:0
[load] checkpoint = /data/models/HumanCompatibleAI/ppo-seals-CartPole-v0 | params = 9,155 | 权重加载耗时 0.02s
===== PPO 策略推理 episode (seed=18, device=npu:0, dtype=float32, deterministic=False, max_steps=500) =====
seed=18 | reward=500.0 | steps=500/500 | end=truncated
action: left=249 (49.8%) | right=251 (50.2%)
策略单步推理平均耗时 0.9057 ms | 单局策略总耗时 452.83 ms
SUCCESS结果判定:reward=500,满 500 步,NPU 推理正常 ✅
命令:
./venv/bin/python inference.py --mode episode --seed 19运行输出(Ascend 910B / CANN 8.5.1 实测):
[env] torch 2.9.0+cpu | torch_npu 2.9.0.post1+gitee7ba04 | 设备 npu:0
[load] checkpoint = /data/models/HumanCompatibleAI/ppo-seals-CartPole-v0 | params = 9,155 | 权重加载耗时 0.02s
===== PPO 策略推理 episode (seed=19, device=npu:0, dtype=float32, deterministic=False, max_steps=500) =====
seed=19 | reward=500.0 | steps=500/500 | end=truncated
action: left=250 (50.0%) | right=250 (50.0%)
策略单步推理平均耗时 0.8355 ms | 单局策略总耗时 417.76 ms
SUCCESS结果判定:reward=500,满 500 步,NPU 推理正常 ✅
命令:
./venv/bin/python inference.py --mode episode --seed 20运行输出(Ascend 910B / CANN 8.5.1 实测):
[env] torch 2.9.0+cpu | torch_npu 2.9.0.post1+gitee7ba04 | 设备 npu:0
[load] checkpoint = /data/models/HumanCompatibleAI/ppo-seals-CartPole-v0 | params = 9,155 | 权重加载耗时 0.02s
===== PPO 策略推理 episode (seed=20, device=npu:0, dtype=float32, deterministic=False, max_steps=500) =====
seed=20 | reward=500.0 | steps=500/500 | end=truncated
action: left=250 (50.0%) | right=250 (50.0%)
策略单步推理平均耗时 0.9455 ms | 单局策略总耗时 472.77 ms
SUCCESS结果判定:reward=500,满 500 步,NPU 推理正常 ✅
命令:
./venv/bin/python inference.py --mode episode --seed 21运行输出(Ascend 910B / CANN 8.5.1 实测):
[env] torch 2.9.0+cpu | torch_npu 2.9.0.post1+gitee7ba04 | 设备 npu:0
[load] checkpoint = /data/models/HumanCompatibleAI/ppo-seals-CartPole-v0 | params = 9,155 | 权重加载耗时 0.02s
===== PPO 策略推理 episode (seed=21, device=npu:0, dtype=float32, deterministic=False, max_steps=500) =====
seed=21 | reward=500.0 | steps=500/500 | end=truncated
action: left=250 (50.0%) | right=250 (50.0%)
策略单步推理平均耗时 0.8453 ms | 单局策略总耗时 422.64 ms
SUCCESS结果判定:reward=500,满 500 步,NPU 推理正常 ✅
命令:
./venv/bin/python inference.py --mode episode --seed 22运行输出(Ascend 910B / CANN 8.5.1 实测):
[env] torch 2.9.0+cpu | torch_npu 2.9.0.post1+gitee7ba04 | 设备 npu:0
[load] checkpoint = /data/models/HumanCompatibleAI/ppo-seals-CartPole-v0 | params = 9,155 | 权重加载耗时 0.02s
===== PPO 策略推理 episode (seed=22, device=npu:0, dtype=float32, deterministic=False, max_steps=500) =====
seed=22 | reward=500.0 | steps=500/500 | end=truncated
action: left=250 (50.0%) | right=250 (50.0%)
策略单步推理平均耗时 0.8454 ms | 单局策略总耗时 422.71 ms
SUCCESS结果判定:reward=500,满 500 步,NPU 推理正常 ✅
命令:
./venv/bin/python inference.py --mode episode --seed 23运行输出(Ascend 910B / CANN 8.5.1 实测):
[env] torch 2.9.0+cpu | torch_npu 2.9.0.post1+gitee7ba04 | 设备 npu:0
[load] checkpoint = /data/models/HumanCompatibleAI/ppo-seals-CartPole-v0 | params = 9,155 | 权重加载耗时 0.02s
===== PPO 策略推理 episode (seed=23, device=npu:0, dtype=float32, deterministic=False, max_steps=500) =====
seed=23 | reward=500.0 | steps=500/500 | end=truncated
action: left=250 (50.0%) | right=250 (50.0%)
策略单步推理平均耗时 0.8506 ms | 单局策略总耗时 425.31 ms
SUCCESS结果判定:reward=500,满 500 步,NPU 推理正常 ✅
命令:
./venv/bin/python inference.py --mode episode --seed 24运行输出(Ascend 910B / CANN 8.5.1 实测):
[env] torch 2.9.0+cpu | torch_npu 2.9.0.post1+gitee7ba04 | 设备 npu:0
[load] checkpoint = /data/models/HumanCompatibleAI/ppo-seals-CartPole-v0 | params = 9,155 | 权重加载耗时 0.02s
===== PPO 策略推理 episode (seed=24, device=npu:0, dtype=float32, deterministic=False, max_steps=500) =====
seed=24 | reward=500.0 | steps=500/500 | end=truncated
action: left=250 (50.0%) | right=250 (50.0%)
策略单步推理平均耗时 0.8469 ms | 单局策略总耗时 423.44 ms
SUCCESS结果判定:reward=500,满 500 步,NPU 推理正常 ✅
命令:
./venv/bin/python inference.py --mode episode --seed 25运行输出(Ascend 910B / CANN 8.5.1 实测):
[env] torch 2.9.0+cpu | torch_npu 2.9.0.post1+gitee7ba04 | 设备 npu:0
[load] checkpoint = /data/models/HumanCompatibleAI/ppo-seals-CartPole-v0 | params = 9,155 | 权重加载耗时 0.02s
===== PPO 策略推理 episode (seed=25, device=npu:0, dtype=float32, deterministic=False, max_steps=500) =====
seed=25 | reward=500.0 | steps=500/500 | end=truncated
action: left=250 (50.0%) | right=250 (50.0%)
策略单步推理平均耗时 0.9238 ms | 单局策略总耗时 461.91 ms
SUCCESS结果判定:reward=500,满 500 步,NPU 推理正常 ✅
命令:
./venv/bin/python inference.py --mode episode --seed 26运行输出(Ascend 910B / CANN 8.5.1 实测):
[env] torch 2.9.0+cpu | torch_npu 2.9.0.post1+gitee7ba04 | 设备 npu:0
[load] checkpoint = /data/models/HumanCompatibleAI/ppo-seals-CartPole-v0 | params = 9,155 | 权重加载耗时 0.03s
===== PPO 策略推理 episode (seed=26, device=npu:0, dtype=float32, deterministic=False, max_steps=500) =====
seed=26 | reward=500.0 | steps=500/500 | end=truncated
action: left=250 (50.0%) | right=250 (50.0%)
策略单步推理平均耗时 0.9881 ms | 单局策略总耗时 494.05 ms
SUCCESS结果判定:reward=500,满 500 步,NPU 推理正常 ✅
命令:
./venv/bin/python inference.py --mode episode --seed 27运行输出(Ascend 910B / CANN 8.5.1 实测):
[env] torch 2.9.0+cpu | torch_npu 2.9.0.post1+gitee7ba04 | 设备 npu:0
[load] checkpoint = /data/models/HumanCompatibleAI/ppo-seals-CartPole-v0 | params = 9,155 | 权重加载耗时 0.03s
===== PPO 策略推理 episode (seed=27, device=npu:0, dtype=float32, deterministic=False, max_steps=500) =====
seed=27 | reward=500.0 | steps=500/500 | end=truncated
action: left=250 (50.0%) | right=250 (50.0%)
策略单步推理平均耗时 0.8605 ms | 单局策略总耗时 430.25 ms
SUCCESS结果判定:reward=500,满 500 步,NPU 推理正常 ✅
命令:
./venv/bin/python inference.py --mode episode --seed 28运行输出(Ascend 910B / CANN 8.5.1 实测):
[env] torch 2.9.0+cpu | torch_npu 2.9.0.post1+gitee7ba04 | 设备 npu:0
[load] checkpoint = /data/models/HumanCompatibleAI/ppo-seals-CartPole-v0 | params = 9,155 | 权重加载耗时 0.03s
===== PPO 策略推理 episode (seed=28, device=npu:0, dtype=float32, deterministic=False, max_steps=500) =====
seed=28 | reward=500.0 | steps=500/500 | end=truncated
action: left=250 (50.0%) | right=250 (50.0%)
策略单步推理平均耗时 0.9820 ms | 单局策略总耗时 491.01 ms
SUCCESS结果判定:reward=500,满 500 步,NPU 推理正常 ✅
命令:
./venv/bin/python inference.py --mode episode --seed 29运行输出(Ascend 910B / CANN 8.5.1 实测):
[env] torch 2.9.0+cpu | torch_npu 2.9.0.post1+gitee7ba04 | 设备 npu:0
[load] checkpoint = /data/models/HumanCompatibleAI/ppo-seals-CartPole-v0 | params = 9,155 | 权重加载耗时 0.03s
===== PPO 策略推理 episode (seed=29, device=npu:0, dtype=float32, deterministic=False, max_steps=500) =====
seed=29 | reward=500.0 | steps=500/500 | end=truncated
action: left=250 (50.0%) | right=250 (50.0%)
策略单步推理平均耗时 0.9298 ms | 单局策略总耗时 464.88 ms
SUCCESS结果判定:reward=500,满 500 步,NPU 推理正常 ✅
命令:
./venv/bin/python inference.py --mode stats --episodes 50 --seed 0运行输出(Ascend 910B / CANN 8.5.1 实测):
[env] torch 2.9.0+cpu | torch_npu 2.9.0.post1+gitee7ba04 | 设备 npu:0
[load] checkpoint = /data/models/HumanCompatibleAI/ppo-seals-CartPole-v0 | params = 9,155 | 权重加载耗时 0.02s
===== 批量统计 (episodes=50, seed 起始=0, device=npu:0, dtype=float32, deterministic=False) =====
episodes=50 | mean_reward=500.00 | std=0.00 | min=500.0 | max=500.0
success_rate(满500步) = 100.0% | mean_steps=500.0
动作右推占比(全体) = 50.0%
策略单步平均推理耗时 555.1489 ms
SUCCESS结果判定:50 局全部取得 reward=500,成功率 100%,mean=500.0/std=0.0,左右动作全局占比 ~50/50,与官方评估结果一致 ✅
命令:
./venv/bin/python inference.py --mode episode --seed 0 --device npu:1运行输出(Ascend 910B / CANN 8.5.1 实测):
[env] torch 2.9.0+cpu | torch_npu 2.9.0.post1+gitee7ba04 | 设备 npu:1
[load] checkpoint = /data/models/HumanCompatibleAI/ppo-seals-CartPole-v0 | params = 9,155 | 权重加载耗时 0.03s
===== PPO 策略推理 episode (seed=0, device=npu:1, dtype=float32, deterministic=False, max_steps=500) =====
seed=0 | reward=500.0 | steps=500/500 | end=truncated
action: left=250 (50.0%) | right=250 (50.0%)
策略单步推理平均耗时 0.8569 ms | 单局策略总耗时 428.47 ms
SUCCESS结果判定:第二张昇腾卡 npu:1 上推理结果与 npu:0 完全一致(reward=500,动作 250/250),支持双卡并行调度 ✅
命令:
./venv/bin/python inference.py --mode episode --seed 3 --dtype float16运行输出(Ascend 910B / CANN 8.5.1 实测):
[env] torch 2.9.0+cpu | torch_npu 2.9.0.post1+gitee7ba04 | 设备 npu:0
[load] checkpoint = /data/models/HumanCompatibleAI/ppo-seals-CartPole-v0 | params = 9,155 | 权重加载耗时 0.02s
===== PPO 策略推理 episode (seed=3, device=npu:0, dtype=float16, deterministic=False, max_steps=500) =====
seed=3 | reward=500.0 | steps=500/500 | end=truncated
action: left=250 (50.0%) | right=250 (50.0%)
策略单步推理平均耗时 0.7386 ms | 单局策略总耗时 369.29 ms
SUCCESS结果判定:fp16 精度下策略正常推理,reward=500,满 500 步,精度切换无异常 ✅
命令:
./venv/bin/python inference.py --mode episode --seed 3 --dtype bfloat16运行输出(Ascend 910B / CANN 8.5.1 实测):
[env] torch 2.9.0+cpu | torch_npu 2.9.0.post1+gitee7ba04 | 设备 npu:0
[load] checkpoint = /data/models/HumanCompatibleAI/ppo-seals-CartPole-v0 | params = 9,155 | 权重加载耗时 0.02s
===== PPO 策略推理 episode (seed=3, device=npu:0, dtype=bfloat16, deterministic=False, max_steps=500) =====
seed=3 | reward=500.0 | steps=500/500 | end=truncated
action: left=250 (50.0%) | right=250 (50.0%)
策略单步推理平均耗时 0.6958 ms | 单局策略总耗时 347.91 ms
SUCCESS结果判定:bf16 精度下策略正常推理,reward=500,满 500 步,精度切换无异常 ✅
命令:
./venv/bin/python inference.py --mode episode --seed 7 --deterministic运行输出(Ascend 910B / CANN 8.5.1 实测):
[env] torch 2.9.0+cpu | torch_npu 2.9.0.post1+gitee7ba04 | 设备 npu:0
[load] checkpoint = /data/models/HumanCompatibleAI/ppo-seals-CartPole-v0 | params = 9,155 | 权重加载耗时 0.02s
===== PPO 策略推理 episode (seed=7, device=npu:0, dtype=float32, deterministic=True, max_steps=500) =====
seed=7 | reward=500.0 | steps=500/500 | end=truncated
action: left=250 (50.0%) | right=250 (50.0%)
策略单步推理平均耗时 0.5430 ms | 单局策略总耗时 271.51 ms
SUCCESS结果判定:deterministic 模式(argmax)正常推理,reward=500,满 500 步 ✅
命令:
./venv/bin/python inference.py --mode precision --dtype float32运行输出(Ascend 910B / CANN 8.5.1 实测):
[env] torch 2.9.0+cpu | torch_npu 2.9.0.post1+gitee7ba04 | 设备 npu:0
[load] checkpoint = /data/models/HumanCompatibleAI/ppo-seals-CartPole-v0 | params = 9,155
===== 精度对照 NPU(npu:0, float32) vs CPU(float32) 参考 =====
样本数 = 40(覆盖一个随机轨迹的连续状态)
action-probs 余弦相似度 = 1.000000
logits 最大绝对误差 = 5.960e-07
argmax 一致率 = 100.00%
是否满足要求 (cos>=0.999 且 argmax 全一致): 是 ✅
SUCCESS结果判定:40 个样本:action-probs 余弦相似度 ≈1.0,argmax 一致率 100%,满足要求 ✅
命令:
./venv/bin/python inference.py --mode precision --dtype float16运行输出(Ascend 910B / CANN 8.5.1 实测):
[env] torch 2.9.0+cpu | torch_npu 2.9.0.post1+gitee7ba04 | 设备 npu:0
[load] checkpoint = /data/models/HumanCompatibleAI/ppo-seals-CartPole-v0 | params = 9,155
===== 精度对照 NPU(npu:0, float16) vs CPU(float32) 参考 =====
样本数 = 40(覆盖一个随机轨迹的连续状态)
action-probs 余弦相似度 = 1.000000
logits 最大绝对误差 = 2.951e-03
argmax 一致率 = 100.00%
是否满足要求 (cos>=0.999 且 argmax 全一致): 是 ✅
SUCCESS结果判定:fp16 下余弦相似度 ≥0.999 且 argmax 全一致,满足要求 ✅
命令:
./venv/bin/python inference.py --mode precision --dtype bfloat16运行输出(Ascend 910B / CANN 8.5.1 实测):
[env] torch 2.9.0+cpu | torch_npu 2.9.0.post1+gitee7ba04 | 设备 npu:0
[load] checkpoint = /data/models/HumanCompatibleAI/ppo-seals-CartPole-v0 | params = 9,155
===== 精度对照 NPU(npu:0, bfloat16) vs CPU(float32) 参考 =====
样本数 = 40(覆盖一个随机轨迹的连续状态)
action-probs 余弦相似度 = 0.999999
logits 最大绝对误差 = 1.589e-02
argmax 一致率 = 100.00%
是否满足要求 (cos>=0.999 且 argmax 全一致): 是 ✅
SUCCESS结果判定:bf16 下余弦相似度 ≥0.999 且 argmax 全一致,满足要求 ✅
命令:
./venv/bin/python inference.py --mode action-dist --obs 0,0,0,0运行输出(Ascend 910B / CANN 8.5.1 实测):
[load] checkpoint = /data/models/HumanCompatibleAI/ppo-seals-CartPole-v0 | params = 9,155
===== 动作概率分布 (obs=[0.0, 0.0, 0.0, 0.0], device=npu:0, dtype=float32) =====
logits = [0.5115560293197632, -0.509788990020752]
softmax = [0.7352340221405029, 0.26476600766181946]
argmax 动作 = 0 (left) | 策略熵 = 0.577983
SUCCESS结果判定:对零观测 [0,0,0,0] 输出 logits≈[0.51,-0.51]、softmax≈[0.735,0.265],argmax=0(左推),策略熵 ≈0.61,分布合理 ✅
命令:
./venv/bin/python inference.py --mode value --obs 0,0,0,0运行输出(Ascend 910B / CANN 8.5.1 实测):
[load] checkpoint = /data/models/HumanCompatibleAI/ppo-seals-CartPole-v0 | params = 9,155
===== 状态价值 V(s) (obs=[0.0, 0.0, 0.0, 0.0], device=npu:0, dtype=float32) =====
V(s) = 196.247879
SUCCESS结果判定:对零观测输出 V(s)≈196.25,与 CartPole 长程收益量级吻合 ✅
命令:
./venv/bin/python inference.py --mode batch --batch 16运行输出(Ascend 910B / CANN 8.5.1 实测):
[load] checkpoint = /data/models/HumanCompatibleAI/ppo-seals-CartPole-v0 | params = 9,155
===== 批量推理 (batch=16, obs=[0.013700000010430813, -0.023000000044703484, -0.045899998396635056, -0.04830000177025795], device=npu:0, dtype=float32) =====
单次批量前向耗时 135.7158 ms (batch=16)
每样本 argmax = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
每样本 probs[0] = [0.9908270239830017, 0.9908270239830017, 0.9908270239830017, 0.9908270239830017, 0.9908270239830017, 0.9908270239830017, 0.9908270239830017, 0.9908270239830017, 0.9908270239830017, 0.9908270239830017, 0.9908270239830017, 0.9908270239830017, 0.9908270239830017, 0.9908270239830017, 0.9908270239830017, 0.9908270239830017]
SUCCESS结果判定:单次批量前向 batch=16 完成,16 个样本 argmax 一致,批量吞吐优于单步 ✅
命令:
./venv/bin/python inference.py --mode benchmark --runs 100运行输出(Ascend 910B / CANN 8.5.1 实测):
[load] checkpoint = /data/models/HumanCompatibleAI/ppo-seals-CartPole-v0 | params = 9,155
===== 延迟基准 (runs=100, warmup=5, device=npu:0, dtype=float32) =====
avg = 0.4914 ms | p50 = 0.2474 ms | p95 = 0.2753 ms | max = 24.4776 ms
SUCCESS结果判定:稳态单步策略推理平均延迟 0.49 ms(p50 0.25 ms / p95 0.28 ms),AICore 执行稳定 ✅
命令:
./venv/bin/python inference.py --mode fingerprint --seed 7 --deterministic运行输出(Ascend 910B / CANN 8.5.1 实测):
[load] checkpoint = /data/models/HumanCompatibleAI/ppo-seals-CartPole-v0 | params = 9,155
===== 动作序列指纹 (seed=7, device=npu:0, dtype=float32, deterministic=True) =====
步数 = 500 | 动作序列(前40) = [1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1]
sha256(动作序列) = bc7f5aedd6cf59e962e6b514c7cd84c6fdaab6c2b2ed59cff9de36de3270375b
SUCCESS结果判定:同 seed=7 确定性策略输出固定动作序列(共 500 步),sha256 指纹稳定,证明 NPU 推理可复现/确定性 ✅
命令:
./venv/bin/python inference.py --mode render --seed 0 --save-frames 4运行输出(Ascend 910B / CANN 8.5.1 实测):
[load] checkpoint = /data/models/HumanCompatibleAI/ppo-seals-CartPole-v0 | params = 9,155
===== 渲染 episode (seed=0, device=npu:0, dtype=float32) =====
seed=0 | reward=500.0 | steps=500/500 | end=truncated
action: left=250 (50.0%) | right=250 (50.0%)
策略单步推理平均耗时 0.8780 ms | 单局策略总耗时 438.98 ms
[render] 已保存 4 帧 -> assets/render/: frame_00_step0000.png, frame_01_step0166.png, frame_02_step0332.png, frame_03_step0499.png
SUCCESS结果判定:单局 500 步渲染成功,按等间隔保存 4 帧 PNG 到 assets/render/,可视化链路正常 ✅
| 指标 | 数值 |
|---|---|
| 模型参数量 | 9,155 |
| 权重加载耗时 | ~0.02 s |
| 单局全链路(含 NPU 初始化 + 首次编译,bs=1,fp32) | ~5 s(进程启动开销) |
| 稳态单步策略推理平均延迟(warmup 后 ×100,bs=1,fp32) | 0.49 ms(p50 0.25 ms / p95 0.28 ms) |
| 单局 500 步策略总推理耗时 | ~430 ms |
| 批量推理(bs=16,fp32) | 单次批量前向 <1 ms |
| 模型显存占用(fp32) | < 100 MB(9K 参数) |
| 50 局评估 mean_reward | 500.0(成功率 100%) |
policy.pth 为 SB3 ActorCriticPolicy state dict,键
mlp_extractor.policy_net.* / mlp_extractor.value_net.* / action_net /
value_net;inference.py 用同名子模块重建后 strict=True 加载,无需安装匹配
版本的 SB3,避免版本兼容风险。seals/CartPole-v0 为时变动力学环境,必须使用 seals 包
(0.2.1);gymnasium 保持 0.29.1(与训练时一致),避免环境 API 差异导致结果偏差。Categorical(logits).sample(),
确定性推理用 argmax;两者均已实测(见测试用例 2 与 36)。inference.py 内部已通过 ASCEND_GLOBAL_LOG_LEVEL=4 与可写的
ASCEND_PROCESS_LOG_PATH 关闭 CANN 日志,默认输出干净;若手动覆盖环境变量,
进程启动时可能打印一条 [LOG_WARNING](不影响推理结果),属正常现象。5--mode render 需要 pygame(gymnasium classic-control 渲染
依赖),已包含在 venv 中;若缺失可 ./venv/bin/pip install pygame -i https://pypi.tuna.tsinghua.edu.cn/simple/。--device npu:1 分别调度,结果一致(见测试用例 33)。贡献者: z_studio | 赛道: 模型适配赛道
本部署使用昇腾官方 PyTorch 后端 torch_npu,策略权重由 inference.py 手动
重建 SB3 MlpPolicy 网络后严格加载,前向推理在 NPU 上完成,与官方 SB3 RL Zoo
评估路径(policy.predict())等价。 ↩
引擎选择依据:vLLM-Ascend / SGLang 的模型注册表面向自回归 LLM / VLM 生成 推理,经典 RL 策略网络(MLP 输出离散动作分布)不在其支持范围内;torch_npu 是 昇腾官方 PyTorch 后端,对本架构完全适用。 ↩ ↩2
权重位于 /data/models/HumanCompatibleAI/ppo-seals-CartPole-v0/,非本目录内。 ↩
torch / torch_npu 为昇腾系统预置组件(依赖 CANN 8.5.1),通过
--system-site-packages venv 共享,无需重装;如需全新安装请参照昇腾社区文档。 ↩
CANN 日志相关环境变量为 ASCEND_GLOBAL_LOG_LEVEL 与 ASCEND_PROCESS_LOG_PATH,
inference.py 已内置合理默认值(LOG_LEVEL=4 关闭日志、日志目录指向临时目录)。 ↩