m0_63918125/Pi3
模型介绍
文件和版本
Pull Requests
讨论
分析

Pi3 on Ascend NPU (torch_npu 2.9.0.post1)

1. 简介

本文档记录 Pi3(yyfz233/Pi3,permutation-equivariant visual geometry / 多视角三维重建)在华为昇腾 NPU(Ascend910)上的适配与真机验证结果。

  • 结构:DINOv2-L 编码器 + 36 层 RoPE100 解码器(decoder_size='large'),外加 local-points / confidence / camera-pose 三个解码头;参数量约 0.959B(958,696,732)。
  • dtype:fp32(HF32 关闭),用于正确性对照。
  • 任务类型:image-to-3d(计算机视觉)。输入一组多视角图像 B×N×3×H×W(像素 [0,1]),模型内部做 ImageNet 归一化,输出每视角 local_points、conf、camera_poses(4×4,OpenCV 约定),并将局部点用相机位姿反投影得到全局 points。

适配要点:

  • 无需 trust_remote_code:Pi3 通过 PyTorchModelHubMixin.from_pretrained 加载,模型代码在 pi3 包(不在 PyPI)。本 inference.py 从 GitCode GitHub 镜像获取该包并挂到 sys.path,不需要 pip 构建后端。
  • 无硬 CUDA 依赖:cuRoPE2D 是可选 CUDA 扩展,Pi3 已自带纯 torch RoPE2D 回退;注意力用 torch.scaled_dot_product_attention(xformers/flash-attn 的 import 全部被 try/except 包裹并回退)。本文件设 XFORMERS_DISABLED=1 稳定走纯 torch 路径。
  • 直接 .to('npu:0') 即可:sdpa_kernel([MATH, EFFICIENT_ATTENTION]) 上下文与 torch.amp.autocast(device_type='cuda', enabled=False) 在 NPU 上均为可用/空操作,无需改模型源码;CameraHead 的 torch.svd/_linalg_det 会 CPU 回退(正确、仅少量开销)。
  • 本模型特有验证点:多视角几何一致性(各视角世界坐标点云是否落在同一场景)与置信度结构(训练后的 conf 头是否选择性),作为无 GT 场景的 Gate-3 三证。

相关获取地址:

  • 权重下载地址(HuggingFace):https://huggingface.co/yyfz233/Pi3
  • 权重下载地址(GitCode 镜像,本次实际使用):https://ai.gitcode.com/hf_mirrors/yyfz233/Pi3
  • 模型代码包(GitCode GitHub 镜像):https://gitcode.com/gh_mirrors/pi/Pi3
  • 论文:https://arxiv.org/abs/2507.13347

2. 验证环境

组件版本
CANN8.5.1
torch2.9.0+cpu
torch-npu2.9.0.post1
transformers4.57.6
Python3.11.14
  • NPU:Ascend910,1 逻辑卡(ASCEND_RT_VISIBLE_DEVICES=1 → 进程内 npu:0,65GB HBM)
  • 推理引擎:torch_npu
  • 权重路径:~/.cache/models/Pi3/model.safetensors(约 3.6 GB)
  • 任务类型:image-to-3d(多视角三维重建)

3. 环境准备与权重获取

export PATH=/usr/local/python3.11.14/bin:$PATH
pip install -r requirements.txt          # torch/torch-npu 已按 CANN 8.5.1 预装
python -c "import torch,torch_npu;assert torch.npu.is_available();print('npu OK')"
  • 模型代码包:inference.py 在缺包时自动执行(已代理旁路): git clone --depth 1 https://gitcode.com/gh_mirrors/pi/Pi3,无需 pip install。
  • 权重:inference.py 通过 huggingface_hub.snapshot_download 从 hf-mirror.com(Xet CDN 代理旁路)拉取 config.json + model.safetensors(3,834,909,248 字节,带字节数完整性校验,避免残缺缓存被误判为完整)。

4. 推理运行

已验证通过的命令(npu:0 only):

export PATH=/usr/local/python3.11.14/bin:$PATH
# 基本推理(加载三门禁 + 多视角前向 + 确定性)
ASCEND_RT_VISIBLE_DEVICES=1 ASCEND_CACHE_PATH=/tmp/ascend_cache_Pi3 \
  python inference.py --device npu

# 附加 Gate-3 随机初始化对照 + 性能基准
ASCEND_RT_VISIBLE_DEVICES=1 ASCEND_CACHE_PATH=/tmp/ascend_cache_Pi3 \
  python inference.py --device npu --gate3 --benchmark

Demo 输入为 Pi3 仓库自带的多视角场景 examples/man_walking_long 的 4 帧(4×3×350×714)。

5. Smoke 验证

python inference.py --device npu --gate3 --benchmark 在昇腾 NPU 上的真实输出:

==========================================================================
Model     : yyfz233/Pi3  (Pi3 — permutation-equivariant visual geometry)
Arch      : Pi3  |  params = 958,696,732 (0.959B)
Config    : {'decoder_size': 'large', 'pos_type': 'rope100'}
GATE-1 (strict state_dict) : missing=0 unexpected=0  -> OK (0/0)
GATE-2 (config landed)     : pos_type=rope100 decoder_size='large'->dec_embed_dim=1024 dec_depth=36 patch=14  -> OK
--------------------------------------------------------------------------
Demo views: 4 x 3 x 350 x 714  (scene: man_walking_long)
points       : shape=[1, 4, 350, 714, 3]  (world point cloud)
local_points : shape=[1, 4, 350, 714, 3]  z(depth) min/med/max = 0.074/0.464/195.454
conf         : shape=[1, 4, 350, 714, 1]  sigmoid range [0.000, 0.876]  mean=0.261
camera_poses : shape=[1, 4, 4, 4]  rot-ortho err(max)=9.60e-07  transl-spread=0.640
View-consistency: inter-view centroid spread / scene extent = 0.0287  (<<1 => coherent single scene)
Determinism : max|pts1-pts2| = 0.000e+00  (bit-exact)
--------------------------------------------------------------------------
GATE-3 (random-init control — structured geometry vs degenerate noise):
  [证1] view-consistency ratio : pretrained 0.0287  vs random 0.1811   (6.3x tighter, lower=coherent)
  [证2] confidence std (structure): pretrained 0.2451  vs random 0.0848   (2.9x more selective)
  [证3] determinism (x2 forwards): max|pts1-pts2| = 0.000e+00  (bit-exact)
  -> DECISIVE WIN (pretrained >> random on both证)
--------------------------------------------------------------------------
PERF (B=1, N=4, 714x350, fp32, HF32 off): avg=361.6 min=358.8 max=367.6 p50=360.3 p90=367.3 p95=367.6 ms  | 11.10 views/s | peak HBM 4149 MB
--------------------------------------------------------------------------
[OK] results written to /tmp/Pi3_npu_results.json
==========================================================================

验证结果:

  • Gate-1:strict 加载 missing=0 unexpected=0(权重与结构完全吻合)。
  • Gate-2:config.json 的 pos_type=rope100、decoder_size='large'(dec_embed_dim=1024、dec_depth=36)、patch=14 全部在实例上生效。
  • 四路输出形状合理:全局/局部点图 [1,4,350,714,3],置信度 [1,4,350,714,1],相机位姿 [1,4,4,4](旋转正交误差 9.60e-07,即有效旋转矩阵)。
  • 多视角一致性 0.0287(<<1),四个视角的世界坐标点云汇聚于同一场景。
  • 两次前向 max|pts1-pts2| = 0,逐元素比特一致(确定性)。

6. 性能参考

测试条件:B=1、N=4 视角、714×350、fp32、HF32 关闭、6 次预热、20 次正式,每次计时前后 torch.npu.synchronize()。

指标数值
avg_ms361.6 ms
min_ms / max_ms358.8 / 367.6 ms
p50_ms / p90_ms / p95_ms360.3 / 367.3 / 367.6 ms
throughput11.10 views/s
峰值 HBM4149 MB

稳态看 p50/p90。CameraHead 内的 torch.svd/_linalg_det 会 CPU 回退,属正确路径的少量 host 开销;对 points/local_points/conf 主干无影响。

7. 精度评测

Pi3 为无 GT 的几何重建任务(本机无对应带标注三维基准),采用随机初始化同架构对照 + 结构性/确定性三证证明预训练权重的有效性(Gate-3):

指标数值
数据集examples/man_walking_long(仓库自带,4 视角)
评测方式预训练 vs 同架构随机初始化(3 seed 平均),无 GT 三证
证1 · 多视角一致性比pretrained 0.0287 vs random 0.1811(6.3x 更紧凑,越低越一致)
证2 · 置信度结构(std)pretrained 0.2451 vs random 0.0848(2.9x 更具选择性)
证3 · 确定性(两次前向)`max
结论DECISIVE WIN:预训练在几何一致性与置信度结构上均决定性胜出
  • HF32:torch.npu.conv/matmul.allow_hf32=False(关闭)。fp32 下两次前向比特一致,未观测到 HF32 相关偏差。

8. 适配截图

  • agent workflow
  • npu device call
  • model result

9. 注意事项

Pi3 无需任何 CUDA 自定义算子即可上昇腾——cuRoPE2D 是可选扩展,仓库已内置纯 torch 回退;真正易踩的坑是把 pi3 包 pip install 会拖入一堆图形依赖并可能覆盖 torch_npu。

实际失败特征如下:

  • 现象:pip install(或 pip install git+...)pi3 时试图解析/编译 cuRoPE2D 或代理下拉超时;即便成功,也可能带入与 torch_npu 冲突的 CUDA torch。
  • 关键报错:Warning, cannot find cuda-compiled version of RoPE2D, using a slow pytorch version instead(这是正常回退提示,非错误);直连 GitHub 时另见代理 gnutls handshake 失败。
  • 位置:pi3/models/layers/pos_embed.py(try: from models.curope import cuRoPE2D)。

原因不是"缺少 CUDA RoPE 内核导致模型不可用",而是该内核本就可选:纯 torch RoPE2D 数值等价,只是稍慢。因此不要 pip 安装该包,只需把源码放到 sys.path。

当前环境的可用处理方式:

env -u https_proxy -u http_proxy -u HTTPS_PROXY -u HTTP_PROXY \
  git clone --depth 1 https://gitcode.com/gh_mirrors/pi/Pi3   # 代理旁路
# 然后 sys.path.insert(0, <clone_dir>);inference.py 已自动完成
export XFORMERS_DISABLED=1                                    # 稳定走纯 torch 注意力

其余注意事项:

  1. 权重完整性:hf-mirror 个别节点会回稳残缺快照。inference.py 以精确字节数 3,834,909,248 校验 model.safetensors,不符则重下——避免"目录非空即跳过下载"的弱守卫导致 safetensors 加载崩溃。
  2. ASCEND_CACHE_PATH 必须在 import 前预建:缺该目录会让 GE/AOE 初始化失败并伪装成 HF32/ACL error 500001。inference.py 顶部已 os.makedirs(...)。
  3. CameraHead 的 torch.svd/aten::_linalg_det CPU 回退:日志会出现 not currently supported on the NPU backend and will fall back to run on the CPU——这是正确路径(4×4 小矩阵,开销可忽略),非精度问题。
  4. fp32 强制:config 未声明 dtype,为正确性对照全程 fp32 且 HF32 关闭;bf16/fp16 autocast(原例给 CUDA 用)在此不启用。

10. 标签

#NPU #Ascend