为什么不用 vLLM-Ascend?ppo-Huggy-NPU 推理引擎选型决策复盘
【免费下载链接】ppo-Huggy-NPU项目地址: https://ai.gitcode.com/z_studio/ppo-Huggy-NPU
在昇腾 NPU 上部署模型,很多人的第一反应就是「上 vLLM-Ascend」。但 ppo-Huggy-NPU 这个开源项目偏偏反其道而行:它把 Hugging Face Deep RL 课程经典示例 Huggy the Dog(拥抱机器人 🐶)完整部署到了昇腾 910B NPU 上,推理引擎选的却是torch_npu。这篇文章将完整复盘这次昇腾 NPU 推理引擎选型决策:vLLM-Ascend 到底卡在哪、torch_npu 凭什么胜出、以及你下次遇到类似模型该怎么选。
一、先认识这只小狗:Huggy 到底是什么模型
Huggy 是 Hugging Face Deep RL 课程的经典入门示例:一只由 Unity ML-Agents 训练的小狗,学会「扑向并拥抱」投出的棍子。它由PPO 算法训练(max_steps: 2,000,000),权重发布在 Hugging Face Hub,参数量仅566,805(fp32 权重约 2.3 MB)。
关键的一点是:Huggy 的网络结构是MLP 策略网络(59 维观测 → 3 层 512 隐藏层 → 21 维连续动作),不是 Transformer,不是 LLM,也不是 VLM。整个网络的计算图非常简单:
- 观测归一化:
clamp((obs − running_mean) / sqrt(running_variance / steps), −5, 5) - 主干:
Linear(59→512) → SiLU → Linear(512→512) → SiLU → Linear(512→512) → SiLU - 动作头:
mu = Linear(512→21),确定性动作 =clip(mu, −3, 3) / 3
这段网络结构在 inference.py 的脚本注释里有完整描述,也在 README.md 中配了计算图说明。先看清模型类型,是后面所有选型判断的起点。
二、核心问题:为什么 vLLM-Ascend 跑不了 Huggy?
这是整个项目最容易被问到的问题。答案其实很直接:
vLLM-Ascend 的定位是 LLM/VLM 的自回归 token 生成推理引擎。它的模型注册表(vllm/model_executor/models/registry.py)只包含文本和视觉生成架构——比如 Qwen、Llama、DeepSeek 这类大语言模型。它的工作方式是:把 prompt 编码 → 逐 token 自回归生成 → 流式输出。这一整套链路是为生成式大模型量身定制的。
而 Huggy 是强化学习的策略网络,输入是 59 维的连续向量观测,输出是 21 维的连续动作,属于判别式的前向计算,完全不涉及 token 生成。也就是说:
- vLLM-Ascend 的模型注册表里根本没有 MLP 策略网络这类架构,加载都加载不进去;
- 就算强行套用,自回归的 KV Cache、采样器、tokenizer 等组件对 Huggy 来说毫无意义。
打个比方:vLLM-Ascend 是一台专门运集装箱的重型卡车,而 Huggy 只是一件小快递。卡车装不下,也不该用它来送。
三、torch_npu 胜出的三个关键理由
排除 vLLM-Ascend 后,项目最终选择了torch_npu(昇腾官方 PyTorch 后端)。胜出理由有三点:
1. 原生 PyTorch 生态,直接 forward 策略网络。torch_npu 让torch代码几乎零改动地在 NPU 上运行,只需把设备指定为npu:0,模型就能直接在昇腾 910B 上完成前向推理,不需要任何转换。
2. 算子全部原生兼容。逐算子核对后确认,Huggy 计算图用到的Sub / Div / Clip / Gemm / Sigmoid / Mul / Add / Exp全部是 PyTorch 原生算子,昇腾 ACL 直接支持,没有 CUDA 独有算子、没有 Triton 依赖、没有阻塞项。这一条在 AGENT_WORKFLOW.md 的 Step 4 有详细记录。
3. 与官方 ONNX 交叉验证,数值完全对得上。项目以官方Huggy.onnx作为 CPU 参考实现(onnxruntime),与 torch 重建的网络做逐算子对比,最大偏差仅6.6e-7(float32 舍入级别),余弦相似度 1.0,确认模型结构与数值还原完全正确。
四、选型决策复盘:一张表看懂该选哪个引擎
这次踩坑的经验完全可以沉淀成一张选型速查表:
| 模型类型 | 典型特征 | 推荐推理引擎 |
|---|---|---|
| LLM / VLM | Transformer、自回归 token 生成 | vLLM-Ascend / SGLang |
| 经典 RL 策略网络 | MLP、向量观测 → 连续动作 | torch_npu |
| 其他 PyTorch 模型 | CNN 等非生成式架构 | torch_npu |
判断三步法,以后遇到新模型可以照着走:
- 看架构:是 Transformer 且需要逐 token 生成?→ 考虑 vLLM-Ascend;是 MLP/CNN 这种判别式结构?→ 直接走 torch_npu;
- 看算子:计算图里有没有 CUDA 独有或 Triton 依赖的算子?没有就基本畅通;
- 看验证:用官方权重(如 ONNX)做参考实现交叉验证,数值对齐才算真正适配成功。
五、实战验证:50 组测试用例给出答案
选型正确与否,最终要靠数据说话。项目在inference.py中实现了11 种推理模式(info / action / sample / batch / precision / onnx-compare / fingerprint / stats / benchmark / export-onnx 等),并跑完了50 组测试用例,可用 run_tests.sh 一键重跑:
- 性能:单步推理平均延迟0.37 ms(p95 0.40 ms),权重加载仅 0.03 秒,峰值显存不到 100 MB;
- 精度:float32 下 NPU 与 CPU 参考的余弦相似度1.0,最大绝对误差仅1.1e-6,与官方 ONNX 一致;
- 确定性:同 seed 两次运行的输出逐位一致(sha256 指纹校验通过),双卡
npu:0/npu:1输出也逐位一致; - 发现:fp16 精度可接受,但bf16 在 910B 上相对误差略超阈值,因此生产推荐 float32。
另外值得一提的细节:ML-Agents 的running_variance是累计和(可达 1e5),强转 float16 会溢出成 inf 导致归一化 NaN,所以脚本强制将归一化统计量保留 float32——这类坑在 AGENT_WORKFLOW.md 的 Step 7 有完整记录。
六、快速上手:三步在昇腾 NPU 上跑通推理
如果你想亲自验证这套选型,环境要求是CANN 8.5.1 + Ascend 910B + Python 3.11,然后按下面三步走:
第 1 步:克隆仓库并创建虚拟环境
git clone https://gitcode.com/z_studio/ppo-Huggy-NPU cd ppo-Huggy-NPU python3 -m venv --system-site-packages venv第 2 步:安装依赖(torch / torch-npu 为昇腾系统预置,仅需按需安装交叉验证包)
./venv/bin/pip install -r requirements.txt第 3 步:运行推理
./venv/bin/python inference.py --mode info ./venv/bin/python inference.py --mode action --obs random --seed 0 ./venv/bin/python inference.py --mode benchmark --runs 200如果看到npu_available = True且用例全部SUCCESS,说明选型和部署都成功了。
结语:选型没有最好,只有最合适
vLLM-Ascend 是优秀的 LLM 推理引擎,但它不是万能的。ppo-Huggy-NPU 的这次推理引擎选型决策复盘告诉我们:先看清模型类型,再选推理引擎。对于强化学习策略网络这类非生成式模型,torch_npu 反而是更轻、更快、更正确的选择——单步 0.37 ms 的延迟和 1e-6 级别的精度误差,就是最好的证明。希望这份复盘能帮你在下次选型时少走弯路。
【免费下载链接】ppo-Huggy-NPU项目地址: https://ai.gitcode.com/z_studio/ppo-Huggy-NPU
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考