z
z_studio/ppo-seals-CartPole-v0-NPU
模型介绍
文件和版本
Pull Requests
讨论
分析

HumanCompatibleAI/ppo-seals-CartPole-v0 昇腾 NPU 部署

在昇腾 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

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 推理路径完全一致。

2. 验证环境

组件版本
操作系统Linux aarch64(HCE / openEuler,内核 5.10)
昇腾 NPUAscend 910B(Ascend910,单卡 64GB HBM,本机 2 卡 npu:0 / npu:1)
CANN8.5.1
Python3.11.14
PyTorch2.9.0+cpu
torch_npu2.9.0.post1+gitee7ba04
gymnasium0.29.1(与训练时版本一致)
seals0.2.1
stable-baselines32.9.0
numpy1.26.4
Pillow12.2.0

完整依赖见 requirements.txt。

3. 目录结构

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

4. 分步推理操作流程

4.1 创建虚拟环境(已含系统 torch_npu)

本项目 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

4.2 确认权重就位

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)), 全程离线、无需联网。

4.3 快速自检:模型与环境信息

./venv/bin/python inference.py --mode info

确认输出 [env] ... | torch_npu 2.9.0.post1+gitee7ba04 | ...、SUCCESS, 即表示 NPU 环境、权重加载、环境创建均正常。

4.4 执行 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

测试用例 1 — 模型与环境信息总览

命令:

./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%),昇腾推理链路完整 ✅

测试用例 2 — 单局推理(seed=0,随机采样)

命令:

./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 完全一致 ✅

测试用例 3 — 单局推理(seed=1)

命令:

./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,策略推理稳定 ✅

测试用例 4 — 单局推理(seed=2)

命令:

./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,策略推理稳定 ✅

测试用例 5 — 单局推理(seed=3)

命令:

./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 推理正常 ✅

测试用例 6 — 单局推理(seed=4)

命令:

./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 推理正常 ✅

测试用例 7 — 单局推理(seed=5)

命令:

./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 推理正常 ✅

测试用例 8 — 单局推理(seed=6)

命令:

./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 推理正常 ✅

测试用例 9 — 单局推理(seed=7)

命令:

./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 推理正常 ✅

测试用例 10 — 单局推理(seed=8)

命令:

./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 推理正常 ✅

测试用例 11 — 单局推理(seed=9)

命令:

./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 推理正常 ✅

测试用例 12 — 单局推理(seed=10)

命令:

./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 推理正常 ✅

测试用例 13 — 单局推理(seed=11)

命令:

./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 推理正常 ✅

测试用例 14 — 单局推理(seed=12)

命令:

./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 推理正常 ✅

测试用例 15 — 单局推理(seed=13)

命令:

./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 推理正常 ✅

测试用例 16 — 单局推理(seed=14)

命令:

./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 推理正常 ✅

测试用例 17 — 单局推理(seed=15)

命令:

./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 推理正常 ✅

测试用例 18 — 单局推理(seed=16)

命令:

./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 推理正常 ✅

测试用例 19 — 单局推理(seed=17)

命令:

./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 推理正常 ✅

测试用例 20 — 单局推理(seed=18)

命令:

./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 推理正常 ✅

测试用例 21 — 单局推理(seed=19)

命令:

./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 推理正常 ✅

测试用例 22 — 单局推理(seed=20)

命令:

./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 推理正常 ✅

测试用例 23 — 单局推理(seed=21)

命令:

./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 推理正常 ✅

测试用例 24 — 单局推理(seed=22)

命令:

./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 推理正常 ✅

测试用例 25 — 单局推理(seed=23)

命令:

./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 推理正常 ✅

测试用例 26 — 单局推理(seed=24)

命令:

./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 推理正常 ✅

测试用例 27 — 单局推理(seed=25)

命令:

./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 推理正常 ✅

测试用例 28 — 单局推理(seed=26)

命令:

./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 推理正常 ✅

测试用例 29 — 单局推理(seed=27)

命令:

./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 推理正常 ✅

测试用例 30 — 单局推理(seed=28)

命令:

./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 推理正常 ✅

测试用例 31 — 单局推理(seed=29)

命令:

./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 推理正常 ✅

测试用例 32 — 50 局批量统计

命令:

./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,与官方评估结果一致 ✅

测试用例 33 — 双卡切换(npu:1)

命令:

./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),支持双卡并行调度 ✅

测试用例 34 — float16 精度单局推理

命令:

./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 步,精度切换无异常 ✅

测试用例 35 — bfloat16 精度单局推理

命令:

./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 步,精度切换无异常 ✅

测试用例 36 — 确定性策略(argmax)单局推理

命令:

./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 步 ✅

测试用例 37 — 精度对照 NPU fp32 vs CPU fp32

命令:

./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%,满足要求 ✅

测试用例 38 — 精度对照 NPU fp16 vs CPU fp32

命令:

./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 全一致,满足要求 ✅

测试用例 39 — 精度对照 NPU bf16 vs CPU fp32

命令:

./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 全一致,满足要求 ✅

测试用例 40 — 动作概率分布分析

命令:

./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,分布合理 ✅

测试用例 41 — 状态价值函数 V(s)

命令:

./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 长程收益量级吻合 ✅

测试用例 42 — 批量推理(batch=16)

命令:

./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 一致,批量吞吐优于单步 ✅

测试用例 43 — 延迟基准(warmup 后 100 次)

命令:

./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 执行稳定 ✅

测试用例 44 — 动作序列指纹(确定性校验)

命令:

./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 推理可复现/确定性 ✅

测试用例 45 — 渲染轨迹帧(seed=0)

命令:

./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_reward500.0(成功率 100%)

适配要点与注意事项

  • 推理引擎选择:经典 RL 策略网络(MLP)不适用 vLLM-Ascend / SGLang(面向 LLM/VLM 生成),直接使用 torch_npu 昇腾后端 forward,与官方 SB3 推理路径 完全等价。2
  • 权重结构对齐: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 差异导致结果偏差。
  • 离散动作采样:非确定性推理时按 SB3 语义用 Categorical(logits).sample(), 确定性推理用 argmax;两者均已实测(见测试用例 2 与 36)。
  • NPU 日志: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/。
  • 多卡:本模型仅 9K 参数、显存占用 <100MB,单卡即可;如有多卡可 --device npu:1 分别调度,结果一致(见测试用例 33)。
  • 性能量级:策略网络极小,单步延迟主要由 CPU↔NPU 数据搬运与设备同步构成 (实测 ~0.5ms/步);属于小模型部署的典型现象,AICore 利用率非瓶颈。

参考资料

  • HuggingFace 模型主页:HumanCompatibleAI/ppo-seals-CartPole-v0
  • RL Zoo:rl-baselines3-zoo
  • Stable-Baselines3
  • seals 环境库:HumanCompatibleAI/seals
  • Gymnasium
  • 昇腾社区(CANN / torch_npu)

贡献者: z_studio | 赛道: 模型适配赛道


脚注

Footnotes

  1. 本部署使用昇腾官方 PyTorch 后端 torch_npu,策略权重由 inference.py 手动 重建 SB3 MlpPolicy 网络后严格加载,前向推理在 NPU 上完成,与官方 SB3 RL Zoo 评估路径(policy.predict())等价。 ↩

  2. 引擎选择依据:vLLM-Ascend / SGLang 的模型注册表面向自回归 LLM / VLM 生成 推理,经典 RL 策略网络(MLP 输出离散动作分布)不在其支持范围内;torch_npu 是 昇腾官方 PyTorch 后端,对本架构完全适用。 ↩ ↩2

  3. 权重位于 /data/models/HumanCompatibleAI/ppo-seals-CartPole-v0/,非本目录内。 ↩

  4. torch / torch_npu 为昇腾系统预置组件(依赖 CANN 8.5.1),通过 --system-site-packages venv 共享,无需重装;如需全新安装请参照昇腾社区文档。 ↩

  5. CANN 日志相关环境变量为 ASCEND_GLOBAL_LOG_LEVEL 与 ASCEND_PROCESS_LOG_PATH, inference.py 已内置合理默认值(LOG_LEVEL=4 关闭日志、日志目录指向临时目录)。 ↩