Bug_Factory_w/DreamZero-DROID
模型介绍
文件和版本
Pull Requests
讨论
分析

DreamZero-DROID 昇腾 NPU 迁移与服务化推理指南

DreamZero-DROID — NVIDIA GEAR Lab 的 14B 世界动作模型(World Action Model, WAM), 基于 Wan2.1-I2V-14B-480P 视频扩散骨干从头训练(仅用 DROID 数据集), 联合预测未来视频帧与机器人动作。本项目将其从 CUDA 环境迁移到 华为昇腾 Ascend910 NPU,并基于 FastAPI 提供服务化推理(HTTP 接口)。

项目内容
模型DreamZero-DROID(GRoot VLA 自定义架构,22.92B 参数,61GB 权重)
任务视频+动作联合预测(世界动作模型):观测帧+语言指令+本体状态 → 24 步动作
输入4 帧 480×640 观测(单帧自动复制)+ 英文指令 + 本体状态(≤64 维)
输出action_pred (1,24,32) 动作序列 + video_pred 预测视频 latent
硬件Ascend910(本环境 16 卡,部署使用物理 NPU1,bf16 占 47.5GB)
软件CANN 8.5.1 / Python 3.11 / PyTorch 2.9.0 / torch_npu 2.9.0.post1
推理服务FastAPI + uvicorn(HTTP 服务化推理)
测试结果5/5 用例通过,单次推理约 9s

1. 目录结构

DreamZero-DROID-npu/
├── inference.py              # 服务化推理脚本(FastAPI HTTP 服务)★ 核心交付
├── test_inference.py         # 测试用例(5 项,HTTP 模式)
├── requirements.txt          # 运行环境依赖清单
├── README.md                 # 本文档
├── repo/                     # GRoot 推理框架源码(已含全部 NPU 适配补丁)
│   ├── groot/                #   VLA 模型实现(dreamzero 模块)
│   ├── eval_utils/           #   策略服务器接口
│   ├── socket_test_optimized_AR.py  #   官方 WebSocket 服务器(多卡 DDP)
│   └── ...
├── test_results/
│   └── test_result.txt       # 测试结果记录
└── assets/
    ├── umt5-xxl/             # umt5 分词器(sentencepiece,离线可用)
    ├── npu_device_call.png   # 截图1:NPU 设备调用
    ├── model_result.png      # 截图2:模型测试结果(动作热力图)
    ├── agent_workflow.png    # 截图3:适配过程工作流
    └── _make_screenshots.py  # 截图生成脚本(可复现)

2. 环境要求

依赖版本说明
操作系统openEuler / Ubuntu(aarch64)本机 openEuler 2203 SP4
昇腾硬件Ascend910(≥1 卡,≥64GB HBM)bf16 权重 28GB + 激活 19GB ≈ 47.5GB
CANN≥ 8.0(本机 8.5.1)/usr/local/Ascend/ascend-toolkit/set_env.sh
Python3.11—
PyTorch2.9.0与 torch_npu 版本配套
torch_npu2.9.0.post1昇腾 NPU 运行时插件
GRoot 框架本目录 repo/(已打 NPU 补丁)通过 PYTHONPATH 引用,无需 pip 安装

模型权重:/mnt/old_data/whl/models/6/GEAR-Dreams/DreamZero-DROID(61GB,10 分片)。 若分片缺失(如 model-00008),从 hf-mirror 补下: curl -L -o model-00008-of-00010.safetensors "https://hf-mirror.com/GEAR-Dreams/DreamZero-DROID/resolve/main/model-00008-of-00010.safetensors"

3. 环境准备

# 1) 加载 CANN 环境
source /usr/local/Ascend/ascend-toolkit/set_env.sh

# 2) 安装依赖(华为镜像源)
export PIP_INDEX_URL=https://repo.huaweicloud.com/repository/pypi/simple/
pip install -r requirements.txt

# 3) 校验 NPU 环境
npu-smi info
python -c "import torch, torch_npu; a=torch.randn(3,4).npu(); print(a+a)"

4. 模型迁移适配说明(本次迁移 10 个关键适配点)

DreamZero 为 NVIDIA GRoot 自定义 VLA 架构(非 transformers 标准模型),官方代码 为 CUDA/TensorRT 环境编写。迁移到昇腾 NPU 的适配点如下:

#适配点说明
1权重分片补齐原始下载缺 model-00008-of-00010.safetensors(4.9GB),从 hf-mirror 补下
2CUDA 硬编码8 处 device='cuda'(VAE mean/std、DiT freqs、scheduler、噪声生成),transfer_to_npu 不覆盖 tensor 构造参数,全部改为 device='npu'
3flash-attn → SDPA两个 attention 模块在无 flash-attn 时崩溃;wan2_1_attention.py 有现成 sdpa fallback(_gpu_supports_flash_attention 自动触发),attention.py 需设 ENABLE_TENSORRT=true 走 sdpa 分支;另修 2 处 assert q.device.type == 'cuda' → ('cuda','npu')
4HF 组件下载绕过VAE/文本/图像编码器权重尝试从 HF 下载(ensure_file),离线环境崩溃;patch ensure_file 返回 None(三组件权重已含在主 checkpoint:vae 194 键 / model 1317 键 / text_encoder 242 键 / image_encoder 393 键),并在 config.json 设 skip_component_loading: true
5tokenizer 兼容transformers T5Tokenizer(Fast) 与 umt5-xxl 的 spiece.model 不兼容(Cannot parse precompiled_charsmap,tokenizers 0.22 bug);改用 sentencepiece 直连编码
6文本长度DiT text_len=512 固定,文本 token ids 需 pad/截断到 512(含 <|eos|>)
7输入维度state 需 64 维(state_encoder input_dim=max_state_dim=64);action 需 (1,24,32)(validate_inputs 校验)
8torch.compile 移除scheduler 两个 @torch.compile 装饰器在 NPU 触发 dynamo 崩溃(get_device_capability() >= (9,0)),移除(NPU 无 Triton)
9TensorRT 属性推理路径检查 self.trt_engine,属性不存在崩溃;__init__ 补 self.trt_engine = None
10状态重置lazy_joint_video_action 跨调用保留 KV cache/语言状态,二次调用 500;每次推理前重置 kv_cache/clip_feas/ys/language/current_start_frame

其他:官方推理服务器(socket_test_optimized_AR.py)依赖多卡 DDP + roboarena 协议 + flash-attn,本次交付改为单卡 NPU 直接调用 lazy_joint_video_action + FastAPI 包装。

5. 服务化推理(inference.py)

5.1 启动服务(模型加载约 4-5 分钟)

source /usr/local/Ascend/ascend-toolkit/set_env.sh
python inference.py \
  --model-path /mnt/old_data/whl/models/6/GEAR-Dreams/DreamZero-DROID \
  --host 0.0.0.0 --port 8008

启动日志:

[inference] Loading model (61GB, bf16) -> npu:0 ...
[inference] Model loaded in 265.1s, device=npu:0, HBM used=47.5GB
INFO:     Uvicorn running on http://0.0.0.0:8008

5.2 接口文档

方法路径说明
GET/health健康检查,返回设备/参数/显存信息
POST/infer动作/视频预测(image + instruction + state)
POST/v1/predictOpenAI 风格预测接口

5.3 调用示例

健康检查:

curl -s http://127.0.0.1:8008/health
# {"status":"ok","model":"DreamZero-DROID","architecture":"WAM (Wan2.1-I2V-14B backbone)","device":"npu:0","dtype":"torch.bfloat16","params_b":22.92}

动作预测(Python 客户端):

import base64, requests
from PIL import Image

# 观测帧(服务自动复制为 4 帧)
img = Image.new("RGB", (640, 480), (200, 200, 200))
buf = ...
r = requests.post("http://127.0.0.1:8008/infer", json={
    "image": "data:image/jpeg;base64,...",
    "instruction": "pick up the red mug and place it on the table",
    "state": [0.0] * 64,
}, timeout=1200)
print(r.json())

返回示例:

{
  "action_pred": [[0.02, -0.13, ...], ...],   // 24×32 动作序列
  "action_stats": {"shape": [1, 24, 32], "mean": 0.1091, "std": 1.1379},
  "video_pred_shape": [1, 16, 3, 60, 80],     // 预测视频 latent
  "latency_ms": 9000.0
}

6. 测试用例

python test_inference.py --url http://127.0.0.1:8008          # 完整模式(5 次推理)
python test_inference.py --url http://127.0.0.1:8008 --skip-range   # 快速模式

用例覆盖:

用例内容结果
T1健康检查 /health,device=npu、22.92B 参数✅ PASS
T2动作预测:action_pred (1,24,32) 且数值有限✅ PASS
T3输出统计:mean/std 合理范围✅ PASS
T4OpenAI 风格接口:/v1/predict✅ PASS
T5稳定性:连续两次调用均 200✅ PASS

完整测试结果见 test_results/test_result.txt,汇总:5 通过 / 0 失败。

7. 交付截图

截图文件说明
NPU 设备调用assets/npu_device_call.pngnpu-smi info + torch_npu 探针 + 部署摘要
测试结果assets/model_result.png动作序列热力图(24×32)+ 逐步范数 + 延迟指标 + 测试日志
适配过程assets/agent_workflow.png迁移适配工作流(10 步,含 7 个修复点)

截图可通过 python assets/_make_screenshots.py 重新生成(需服务运行中,约 10s 一次推理)。

8. 常见问题(FAQ)

问题原因解决方案
加载报 LocalEntryNotFoundError组件尝试从 HF 下载已 patch ensure_file 离线返回 None;确认 HF_HUB_OFFLINE=1
Torch not compiled with CUDA enableddevice='cuda' 硬编码已全局替换为 device='npu'
flash_attn 相关错误NPU 无 flash-attnENABLE_TENSORRT=true 走 sdpa;assert q.device.type 已放宽
Cannot parse precompiled_charsmaptokenizers 0.22 与 umt5 spiece 不兼容用 sentencepiece 直连编码
context.shape[1] == self.text_len 断言文本未 padpad/截断到 512(服务已处理)
bmm 维度不匹配(32 vs 64)state 维度错误state 需 64 维(服务已处理)
dynamo/Triton 相关崩溃@torch.compile 装饰器已移除(scheduler 两处)
has no attribute 'trt_engine'TensorRT 分支检查已补默认属性
第二次调用 500KV cache 跨调用残留服务已内置状态重置
显存不足(OOM)与其他服务争卡部署独立 NPU(本交付用物理 NPU1),单卡 ≥64GB

9. 参考

  • 模型主页:https://huggingface.co/GEAR-Dreams/DreamZero-DROID
  • 推理代码:https://github.com/dreamzero0/dreamzero(本交付 repo/ 已含 NPU 补丁)
  • 论文:DreamZero: World Action Models are Zero-shot Policies(arXiv:2602.15922)
  • 迁移 Skill:ai4s-basic(ascend-model-agent-plugin)