本文档记录 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)。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 构建后端。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 回退(正确、仅少量开销)。相关获取地址:
| 组件 | 版本 |
|---|---|
CANN | 8.5.1 |
torch | 2.9.0+cpu |
torch-npu | 2.9.0.post1 |
transformers | 4.57.6 |
Python | 3.11.14 |
Ascend910,1 逻辑卡(ASCEND_RT_VISIBLE_DEVICES=1 → 进程内 npu:0,65GB HBM)torch_npu~/.cache/models/Pi3/model.safetensors(约 3.6 GB)image-to-3d(多视角三维重建)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 字节,带字节数完整性校验,避免残缺缓存被误判为完整)。已验证通过的命令(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 --benchmarkDemo 输入为 Pi3 仓库自带的多视角场景 examples/man_walking_long 的 4 帧(4×3×350×714)。
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
==========================================================================验证结果:
strict 加载 missing=0 unexpected=0(权重与结构完全吻合)。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,逐元素比特一致(确定性)。测试条件:B=1、N=4 视角、714×350、fp32、HF32 关闭、6 次预热、20 次正式,每次计时前后 torch.npu.synchronize()。
| 指标 | 数值 |
|---|---|
avg_ms | 361.6 ms |
min_ms / max_ms | 358.8 / 367.6 ms |
p50_ms / p90_ms / p95_ms | 360.3 / 367.3 / 367.6 ms |
throughput | 11.10 views/s |
| 峰值 HBM | 4149 MB |
稳态看
p50/p90。CameraHead内的torch.svd/_linalg_det会 CPU 回退,属正确路径的少量 host 开销;对points/local_points/conf主干无影响。
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:预训练在几何一致性与置信度结构上均决定性胜出 |
torch.npu.conv/matmul.allow_hf32=False(关闭)。fp32 下两次前向比特一致,未观测到 HF32 相关偏差。


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 注意力其余注意事项:
hf-mirror 个别节点会回稳残缺快照。inference.py 以精确字节数 3,834,909,248 校验 model.safetensors,不符则重下——避免"目录非空即跳过下载"的弱守卫导致 safetensors 加载崩溃。ASCEND_CACHE_PATH 必须在 import 前预建:缺该目录会让 GE/AOE 初始化失败并伪装成 HF32/ACL error 500001。inference.py 顶部已 os.makedirs(...)。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 小矩阵,开销可忽略),非精度问题。fp32 强制:config 未声明 dtype,为正确性对照全程 fp32 且 HF32 关闭;bf16/fp16 autocast(原例给 CUDA 用)在此不启用。#NPU #Ascend