FloodDiffusionTiny — 基于 Latent Diffusion Forcing(LDF) 的文本→运动生成 模型(text-to-motion),输出 263 维 HumanML3D 运动特征或 22 关节 3D 骨骼坐标。 本项目将其从通用 PyTorch 环境迁移到华为昇腾 Ascend910 NPU,并基于 FastAPI 提供服务化推理(HTTP 接口)。
| 项目 | 内容 |
|---|---|
| 模型 | FloodDiffusionTiny(LDFModel,扩散强制+VAE+umt5 文本编码,104MB+VAE) |
| 任务 | 文本描述 → 人体运动序列(263 维特征 / 22 关节坐标) |
| 输入 | 英文运动描述(如 "a person walking forward")+ 长度/输出格式参数 |
| 输出 | motion (~4×length, 263) 特征或 (N, 22, 3) 关节坐标 |
| 硬件 | Ascend910(本环境 16 卡,部署使用 npu:0) |
| 软件 | CANN 8.5.1 / Python 3.11 / PyTorch 2.9.0 / torch_npu 2.9.0.post1 |
| 推理服务 | FastAPI + uvicorn(HTTP 服务化推理) |
| 测试结果 | 5/5 用例通过,单次生成约 5s |
FloodDiffusionTiny-npu/
├── inference.py # 服务化推理脚本(FastAPI HTTP 服务)★ 核心交付
├── test_inference.py # 测试用例(5 项,HTTP 模式)
├── requirements.txt # 运行环境依赖清单
├── README.md # 本文档
├── test_results/
│ └── test_result.txt # 测试结果记录
└── assets/
├── npu_device_call.png # 截图1:NPU 设备调用
├── model_result.png # 截图2:模型测试结果(骨骼轨迹+特征图)
├── agent_workflow.png # 截图3:适配过程工作流
└── _make_screenshots.py # 截图生成脚本(可复现)模型目录:
/mnt/old_data/whl/models/8/AlayaLab/FloodDiffusionTiny/(含模型代码 hf_pipeline.py / ldf_models / ldf_utils,trust_remote_code 加载, 已打 NPU 适配补丁)
| 依赖 | 版本 | 说明 |
|---|---|---|
| 操作系统 | openEuler / Ubuntu(aarch64) | 本机 openEuler 2203 SP4 |
| 昇腾硬件 | Ascend910(≥1 卡) | 模型极小,显存占用 < 2GB |
| CANN | ≥ 8.0(本机 8.5.1) | /usr/local/Ascend/ascend-toolkit/set_env.sh |
| Python | 3.11 | — |
| PyTorch | 2.9.0 | 与 torch_npu 版本配套 |
| torch_npu | 2.9.0.post1 | 昇腾 NPU 运行时插件 |
| umt5-base | 自动下载 | 文本编码器(HF_ENDPOINT=https://hf-mirror.com,约 1.6GB 缓存) |
# 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)"FloodDiffusionTiny 为自定义 LDF 架构(trust_remote_code),官方依赖 flash-attn (CUDA)。迁移到昇腾 NPU 的适配点:
| # | 适配点 | 说明 |
|---|---|---|
| 1 | flash-attn → SDPA fallback | ldf_models/tools/attention.py 在无 flash-attn 时 assert FLASH_ATTN_2_AVAILABLE 崩溃;注入 PyTorch scaled_dot_product_attention fallback(NPU 原生支持),并放宽 assert q.device.type == "cuda" → ('cuda','npu') |
| 2 | RoPE 复数 dtype | wan_model.py 的 RoPE 用 float64 构造复数(torch.polar)→ complex128,NPU 的 cat 算子不支持;改为 float32 → complex64(2 处:rope_params、rope_apply) |
| 3 | umt5-base 离线加载 | 文本编码器 from_pretrained("google/umt5-base"):a) HF 直连不通 → HF_ENDPOINT=https://hf-mirror.com;b) 仓库 config.json 缺 model_type 键(HF 仓库缺陷)→ AutoConfig 报 "Unrecognized model",补丁缓存 config 加 "model_type": "umt5" |
| 4 | 设备映射 | transfer_to_npu 自动处理 torch.cuda.is_available() / device 映射(模型加载逻辑中的 'cuda' if torch.cuda.is_available() 自动落到 NPU) |
本项目不涉及 DP/DDP 分布式改造;flash-attn 无需安装(SDPA fallback 覆盖)。
source /usr/local/Ascend/ascend-toolkit/set_env.sh
python inference.py \
--model-path /mnt/old_data/whl/models/8/AlayaLab/FloodDiffusionTiny \
--host 0.0.0.0 --port 8009启动日志:
[inference] Loading LDFModel from /mnt/old_data/whl/models/8/AlayaLab/FloodDiffusionTiny ...
[inference] Model loaded in 10.6s, device=npu:0
INFO: Uvicorn running on http://0.0.0.0:8009| 方法 | 路径 | 说明 |
|---|---|---|
| GET | /health | 健康检查,返回设备/模型信息 |
| POST | /infer | 运动生成(text + length + output_joints + smoothing_alpha) |
| POST | /v1/motions | OpenAI 风格接口 |
健康检查:
curl -s http://127.0.0.1:8009/health
# {"status":"ok","model":"FloodDiffusionTiny","architecture":"LDF (Diffusion Forcing, tiny)","device":"npu:0","dtype":"torch.float32"}运动生成:
curl -s http://127.0.0.1:8009/infer -H "Content-Type: application/json" -d '{
"text": "a person walking forward", "length": 60
}'返回示例:
{
"motion": [[...], ...], // (237, 263) 运动特征
"shape": [237, 263],
"stats": {"mean": 0.1628, "std": 1.09, "min": -6.2, "max": 6.0},
"latency_ms": 5555.33
}关节坐标输出:
curl -s http://127.0.0.1:8009/infer -H "Content-Type: application/json" -d '{
"text": "a person jumping", "length": 40, "output_joints": true
}'
# shape: [157, 22, 3]python test_inference.py --url http://127.0.0.1:8009用例覆盖:
| 用例 | 内容 | 结果 |
|---|---|---|
| T1 | 健康检查 /health,确认 device=npu:0 | ✅ PASS |
| T2 | 运动生成:walking forward → (237, 263) 特征 | ✅ PASS |
| T3 | 长度参数:length=30 → 117 帧 | ✅ PASS |
| T4 | 关节坐标:output_joints=true → (157, 22, 3) | ✅ PASS |
| T5 | OpenAI 风格接口:/v1/motions | ✅ PASS |
完整测试结果见 test_results/test_result.txt,汇总:5 通过 / 0 失败。
| 截图 | 文件 | 说明 |
|---|---|---|
| NPU 设备调用 | assets/npu_device_call.png | npu-smi info + torch_npu 探针 + 部署摘要 |
| 测试结果 | assets/model_result.png | 3D 骨骼轨迹 + 263 维特征图 + 延迟指标 + 测试日志 |
| 适配过程 | assets/agent_workflow.png | 迁移适配工作流(10 步,含 3 个修复点) |
截图可通过 python assets/_make_screenshots.py 重新生成(需服务运行中)。
| 问题 | 原因 | 解决方案 |
|---|---|---|
aclnnCat ... DT_COMPLEX128 | RoPE 复数运算 complex128(NPU 不支持) | 已 patch wan_model.py float64→float32(complex64) |
assert FLASH_ATTN_2_AVAILABLE | 无 flash-attn | 已注入 SDPA fallback(attention.py) |
Unrecognized model in google/umt5-base | HF 仓库 config 缺 model_type 键 | 已补丁缓存 config("model_type": "umt5") |
| umt5 下载失败 | HF 直连不通 | HF_ENDPOINT=https://hf-mirror.com(服务已配置) |
No module named 'decorator' | torch_npu 运行时依赖缺失 | pip install decorator |
| 端口被占用 | 环境预装服务占用端口 | 换用空闲端口(如 8009) |