作者​:昇腾实战派​知识地图​:【昇腾实战派】综合指导知识地图_昇腾大模型地图-CSDN博客

背景概述

在 Ascend NPU 上使用 torch.compile + Inductor + DVM 进行 FLUX 模型训练时,开发者可能会遇到编译链路和分布式通信方面的基础设施问题。本文基于实际训练场景,系统梳理了从环境搭建、DVM 后端验证到常见报错修复的完整流程,旨在帮助开发者快速定位并解决类似问题。

环境信息:

  • torch=2.14.0.dev20260719+cpu
  • torch_npu=2.14.0.dev20260719+gitfe48c44
  • python=3.12.13
  • 基于 torchtitan main 分支修改

一、TorchNPU Master + DVM 环境搭建

1.1 下载 Master 源码

为避免覆盖现有环境,建议单独建立源码目录:

cd /path/to/workspace
git clone -b master --depth 1 https://gitcode.com/Ascend/pytorch.git torch_npu_master
cd torch_npu_master

确认分支与最新提交:

git branch --show-current
git log -1 --oneline

预期输出:master

1.2 确认 DVM 后端存在

编译前务必先检查源码中是否包含 DVM 相关实现:

cd /path/to/torch_npu_master

# 检查 DVM 目录
find torch_npu/_inductor -type d -name '*dvm*'

# 检查 DVM 后端加载逻辑
grep -R "_load_dvm_backend" torch_npu/_inductor
grep -R "NpuDvmKernel" torch_npu/_inductor
grep -R "DvmCodegenInterpreter" torch_npu/_inductor

关键确认点:存在 torch_npu/_inductor/dvm/ 目录,且源码中包含 DVM Backend、DVM Kernel、DVM Codegen 等相关实现。若没有 DVM 路径,则无需继续编译。

1.3 检查 PyTorch 版本兼容性

查看 version.txt 确认 TorchNPU master 支持的 PyTorch 版本:

cat /path/to/torch_npu_master/version.txt

示例输出:

2.15.0
2.14.0
2.13.0

选择兼容版本安装 PyTorch(以 2.13.0 为例):

pip install torch==2.13.0 --index-url https://download.pytorch.org/whl/cpu
python -c "import torch; print(torch.__version__)"  # 预期: 2.13.0

1.4 编译与安装 TorchNPU

cd /path/to/torch_npu_master

# 安装编译依赖
pip install -r requirements.txt
pip install pyyaml setuptools auditwheel

# 加载 CANN 环境
source /usr/local/Ascend/cann/set_env.sh

# 编译(指定 Python 版本)
bash ci/build.sh --python=3.12

# 安装编译产物
pip install --force-reinstall --no-deps dist/torch_npu*.whl

使用 --no-deps 避免 pip 修改已准备好的 PyTorch 环境。

1.5 验证安装

import os
import torch
import torch_npu

print("torch      =", torch.__version__)
print("torch_npu  =", torch_npu.__version__)
print("npu path   =", torch_npu.__file__)

root = os.path.dirname(torch_npu.__file__)
print("dvm dir exists:", os.path.exists(os.path.join(root, "_inductor", "dvm")))

预期输出:dvm dir exists: True


二、DVM 后端验证与图融合测试

2.1 开启 DVM Backend

运行 Python 程序前设置环境变量:

export TORCHINDUCTOR_NPU_BACKEND=dvm
export TORCH_COMPILE_DEBUG=1
export TORCHINDUCTOR_CACHE_DIR=/tmp/torchinductor_dvm

环境变量说明:

  • TORCHINDUCTOR_NPU_BACKEND=dvm:指定 NPU Inductor Codegen 使用 DVM Backend
  • TORCH_COMPILE_DEBUG=1:生成调试目录,用于检查 Inductor 最终生成的代码
  • TORCHINDUCTOR_CACHE_DIR:单独指定 DVM 编译缓存,避免复用其他 Backend 的历史缓存

2.2 静态 Shape 最小示例

import torch
import torch_npu

class DvmDemo(torch.nn.Module):
    def forward(self, x, y):
        value = x * y
        value = value + x
        return torch.relu(value)

x = torch.randn((128, 128), device="npu", dtype=torch.float32)
y = torch.randn((128, 128), device="npu", dtype=torch.float32)

model = DvmDemo().npu()
compiled_model = torch.compile(model, backend="inductor", dynamic=False)

out = compiled_model(x, y)
torch.npu.synchronize()
print(out.shape, out.device, out.dtype)

编译链路说明:

torch.compile → Dynamo → Inductor → NPU Backend → TORCHINDUCTOR_NPU_BACKEND=dvm → DVM Codegen

2.3 动态 Shape 示例

import torch
import torch_npu

class DynamicDvmDemo(torch.nn.Module):
    def forward(self, x, y):
        rows = x.shape[0]
        return torch.relu(x + y) / rows

def make_inputs(rows):
    x = torch.randn((rows, 128), device="npu", dtype=torch.float32)
    y = torch.randn((rows, 128), device="npu", dtype=torch.float32)
    torch._dynamo.mark_dynamic(x, 0)
    torch._dynamo.mark_dynamic(y, 0)
    return x, y

model = DynamicDvmDemo().npu()
compiled_model = torch.compile(model, backend="inductor", dynamic=True)

for rows in (32, 48):
    x, y = make_inputs(rows)
    out = compiled_model(x, y)
    expected = model(x, y)
    torch.npu.synchronize()
    torch.testing.assert_close(out, expected, atol=1e-4, rtol=1e-4)
    print(rows, out.shape)

2.4 确认 DVM 代码生成

开启 TORCH_COMPILE_DEBUG=1 后,运行测试程序,然后检查生成的代码:

find torch_compile_debug -name output_code.py -print
grep -R "@dvm.kernel" torch_compile_debug
grep -R "torch_npu._inductor.*dvm" torch_compile_debug

如果 DVM Codegen 生效,output_code.py 中应出现类似结构:

from torch_npu._inductor import dvm

@dvm.kernel(ktype='vector', dyn_shape=False)
def dvm_fused_add_mul_relu_0_build(k):
    arg0_1 = k.load([128, 128], dvm.float32)
    arg1_1 = k.load([128, 128], dvm.float32)
    mul = k.mul(arg0_1, arg1_1)
    add = k.add(mul, arg0_1)
    relu = k.maximum(add, 0)
    k.store(relu, dvm.float32)

dvm_fused_add_mul_relu_0 = dvm_fused_add_mul_relu_0_build

关键判断标准:仅设置环境变量 dvm 不能证明 DVM 已参与 Codegen,最终必须以生成代码中出现 from torch_npu._inductor import dvm 和 @dvm.kernel 为准。


三、常见报错修复

3.1 报错一:FallbackKernel 没有 data 属性

报错现象

模型 checkpoint 正常加载,进入第一个训练 step 后,torch.compile 在 Inductor 图处理阶段报错:

torch._inductor.exc.InductorError:
AttributeError: 'FallbackKernel' object has no attribute 'data'

调用位置:

torch_npu/_inductor/ascend_npu_ir/ascend_npu_ir/npu/inductor_patch/ir.py
_patch_baseview_realize_hint()
    ↓
traced_graph = buffer.data.get_traced_graph()
    ↓
AttributeError: 'FallbackKernel' object has no attribute 'data'

问题本质

TorchNPU 对 Inductor IR 的 Patch 原本只针对以下类型进行了提前返回:

ir.MultiOutput
ir.InputBuffer
ir.ConcatKernel

但计算图中可能出现 ir.FallbackKernel,该对象与普通 Buffer 结构不同,不能访问 .data 属性。

解决方案

修改文件:

/usr/local/python3.12.13/lib/python3.12/site-packages/
torch_npu/_inductor/ascend_npu_ir/ascend_npu_ir/npu/inductor_patch/ir.py

文件中相同判断出现 3 次(约在 230、257、284 行),建议全部修改。

原代码:

if isinstance(buffer, (ir.MultiOutput, ir.InputBuffer, ir.ConcatKernel)):
    return r

修改后:

if isinstance(
    buffer,
    (
        ir.MultiOutput,
        ir.InputBuffer,
        ir.ConcatKernel,
        ir.FallbackKernel,
    ),
):
    return r

修改效果

修改后的逻辑为:

realize_hint()
      ↓
检查 buffer 类型
      ↓
FallbackKernel?
      │
      ├─ Yes → 直接 return r
      │
      └─ No  → 继续访问 buffer.data.get_traced_graph()

该修改修正的是 TorchNPU Inductor IR 对不同 Buffer 类型的兼容处理,而非 FLUX 模型的计算逻辑。

3.2 报错二:HCCL 通信端口冲突

问题现象

8 卡训练启动时,HCCL 默认使用的 16666 端口被其他任务占用,导致建链失败。

解决方案

显式指定新的 HCCL 端口范围:

export HCCL_NPU_SOCKET_PORT_RANGE="16700-16799"
export HCCL_CONNECT_TIMEOUT=7200
export HCCL_EXEC_TIMEOUT=7200

与 DVM 配置组合

HCCL 配置与 DVM 是相互独立的层次:

  • HCCL:多卡通信
  • DVM:torch.compile / Inductor 的 NPU Codegen Backend

因此原有 DVM 环境变量继续保留:

export TORCHINDUCTOR_NPU_BACKEND=dvm
export TORCHINDUCTOR_CACHE_DIR=/path/to/cache/torchinductor_dvm
export TORCHINDUCTOR_COMPILE_THREADS=2
export TORCHINDUCTOR_DEBUG=0


四、最终推荐启动配置

4.1 环境变量统一配置

source /usr/local/Ascend/ascend-toolkit/set_env.sh

# 8 卡 NPU
export ASCEND_RT_VISIBLE_DEVICES=0,1,2,3,4,5,6,7

# HCCL:避免默认端口冲突
export HCCL_NPU_SOCKET_PORT_RANGE="16700-16799"
export HCCL_CONNECT_TIMEOUT=7200
export HCCL_EXEC_TIMEOUT=7200

# DVM / Inductor
export TORCHINDUCTOR_NPU_BACKEND=dvm
export TORCHINDUCTOR_CACHE_DIR=/path/to/cache/torchinductor_dvm
export TORCHINDUCTOR_COMPILE_THREADS=2
export TORCHINDUCTOR_DEBUG=0

# 其他
export TOKENIZERS_PARALLELISM=false
export OMP_NUM_THREADS=8

4.2 启动命令

推荐使用一次性环境变量方式,避免污染当前 Shell:

TORCHINDUCTOR_NPU_BACKEND=dvm \
TORCHINDUCTOR_CACHE_DIR=/path/to/cache/torchinductor_dvm \
NGPU=8 \
MODULE=flux \
CONFIG=flux_dev_compile_baseline_8gpu \
./run_train.sh

如需开启 Compile Debug:

TORCHINDUCTOR_NPU_BACKEND=dvm \
TORCH_COMPILE_DEBUG=1 \
TORCHINDUCTOR_CACHE_DIR=/path/to/cache/torchinductor_dvm \
NGPU=8 \
MODULE=flux \
CONFIG=flux_dev_compile_baseline_8gpu \
./run_train.sh


五、问题快速定位表

问题所属层根因解决方案
'FallbackKernel' object has no attribute 'data'TorchNPU / Inductor IRTorchNPU Patch 将 FallbackKernel 按普通 Buffer 访问 .data在 ir.py 3 处类型判断中加入 ir.FallbackKernel
HCCL 16666 端口冲突NPU 多卡通信默认 HCCL Socket 端口被其他任务占用设置 HCCL_NPU_SOCKET_PORT_RANGE="16700-16799"

一句话总结

  • 报错一:编译器 IR 类型兼容问题,让 FallbackKernel 提前返回即可解决。
  • 报错二:分布式通信端口问题,为当前任务分配独立的 HCCL 端口范围。

这两个问题均属于运行/编译基础设施层,前者发生在 TorchNPU Inductor Codegen 链路,后者发生在 HCCL 通信链路,并非 FLUX 模型本身的逻辑问题。


六、最终检查清单

正式运行训练前,请依次确认:

  1. ✅ version.txt 与 PyTorch 版本匹配
  2. ✅ TorchNPU master 源码存在 _inductor/dvm
  3. ✅ 实际 import 的 torch_npu.__file__ 指向新安装版本
  4. ✅ 安装目录存在 _inductor/dvm
  5. ✅ TORCHINDUCTOR_NPU_BACKEND=dvm 已设置
  6. ✅ 最小静态 Shape 示例能够运行
  7. ✅ 动态 Shape 示例能够运行
  8. ✅ output_code.py 中真正出现 DVM import 和 @dvm.kernel

第 8 点最为关键:仅设置环境变量为 dvm 不能证明 DVM 已参与 Codegen,最终必须以生成代码为准。

Logo

鲲鹏昇腾开发者社区是面向全社会开放的“联接全球计算开发者,聚合华为+生态”的社区,内容涵盖鲲鹏、昇腾资源,帮助开发者快速获取所需的知识、经验、软件、工具、算力,支撑开发者易学、好用、成功,成为核心开发者。

更多推荐