Ascend-SACT/Qwen-Image-series-v1.0
模型介绍文件和版本Pull Requests讨论分析
下载使用量0

Qwen-Image-series 模型 NPU 推理部署指南

一、模型介绍

1.1 概述

Qwen-Image-series 是通义千问团队推出的图像生成与编辑大模型系列,基于 DiT(Diffusion Transformer)架构,具备出色的文字渲染和多语言生成能力。

  • Qwen-Image:文生图模型,根据文本提示词生成高质量图像,在文字渲染(中英文、数学公式、表情符号等)方面表现突出,能够精确地将用户指定的文字内容呈现在生成的图像中。
  • Qwen-Image-2512:文生图增强版,在 Qwen-Image 基础上优化了生成质量和图文对齐能力。
  • Qwen-Image-Edit-2511:图生图模型,支持基于输入图像和文本提示词进行图像编辑与生成,可根据用户描述对原图进行风格转换、内容修改等操作。

1.2 模型系列与权重下载

根据所需任务下载对应模型权重到本地 model/ 目录:

模型功能HuggingFaceModelScope
Qwen-Image文生图HuggingFaceModelScope
Qwen-Image-2512文生图(增强版)HuggingFaceModelScope
Qwen-Image-Edit-2511图生图HuggingFaceModelScope

下载完成后,每个模型目录结构应包含:

model/Qwen-Image/
├── transformer/       # DiT 模型权重
├── text_encoder/      # 文本编码器
├── tokenizer/         # 分词器
├── scheduler/         # 调度器配置
└── vae/               # VAE 模型

1.3 技术架构

  • 基础架构:基于 DiT(Diffusion Transformer),使用 Flow Matching 调度策略
  • 文本编码器:支持中英文多语言提示词输入
  • VAE:自研 3D AE(AutoencoderKLQwenImage),支持 tiling 和 slicing 显存优化
  • 数据类型:默认使用 bfloat16 精度推理
  • 推理参数:默认 50 步去噪,1024×1024 分辨率

二、环境准备

2.1 硬件要求

  • 设备:Atlas 800T A2(8×64G)推理设备
  • 最低卡数:1 卡(单卡推理),推荐 2 卡及以上获取更优性能

2.2 软件版本配套

配套项版本
CANN8.5
Python3.11.10
PyTorch2.6.0
torch_npu2.6.0
torchvision0.21.0
diffusers0.36.0
transformers4.57.3
yunchang0.6.0

2.3 镜像获取

从华为昇腾镜像仓库获取 MindIE 推理镜像(镜像已包含 CANN、MindIE、torch_npu):

  • 镜像下载链接:Ascend Hub MindIE
  • 推荐镜像版本:2.3.0-800I-A2-py311-openeuler24.03-lts(ARM 架构)

三、安装依赖

3.1 系统依赖(OpenEuler)

yum install gcc gcc-c++ glibc-devel libstdc++-devel cmake make python3-devel libgcc

3.2 安装 mindiesd

mindiesd 是华为昇腾提供的 Stable Diffusion 推理加速库,集成了算子优化、缓存加速、量化、并行等高阶特性。

源码地址:GitCode MindIE-SD

# 1. 检查并卸载旧版本
pip list | grep mindiesd
# 如果存在则卸载
pip uninstall mindiesd

# 2. 再次确认卸载干净
pip list | grep mindiesd
# 如果仍然存在,可能是被其他包依赖安装的,需要先卸载再重装

# 3. 编译安装 mindiesd
cd MindIE-SD
rm -rf dist
python setup.py bdist_wheel
cd dist
pip install mindiesd-*.whl

3.3 安装 Qwen-Image-series 依赖

源码地址:Modelers Qwen-Image-series

cd Qwen-Image-series
pip3 install -r requirements.txt

依赖包含:

  • diffusers==0.36.0:HuggingFace 扩散模型框架
  • transformers==4.57.3:文本编码器加载
  • yunchang==0.6.0:分布式并行通信库

四、执行推理

5.1 Qwen-Image 文生图

5.1.1 单卡推理

使用 test-Qwen-Image-1.sh 脚本执行单卡推理:

bash test-Qwen-Image-1.sh

脚本内容解析:

#!/bin/bash
set -e

# ====================== 全局环境变量配置 ======================
export PYTORCH_NPU_ALLOC_CONF='expandable_segments:True'   # NPU显存动态分配
export ALGO=2               # 0:普通, 1:FA, 2:LA(高性能FA算子)
export OVERLAP=0            # 通信-计算重叠开关
export ROPE_FUSE=1          # RoPE算子融合
export ADALN_FUSE=1         # ADALN算子融合

export COND_CACHE=1          # 条件缓存
export UNCOND_CACHE=1        # 无条件缓存
export CACHE_STEP_START=10   # 缓存开始步骤
export CACHE_STEP_INTERVAL=3 # 缓存步骤间隔
export CACHE_STEP_END=35     # 缓存结束步骤
export CACHE_BLOCK_START=10  # 缓存开始块
export CACHE_BLOCK_END=50    # 缓存结束块

# ====================== 任务配置 ======================
TASK="Qwen-Image"
MODEL_PATH="../../model/Qwen-Image"
DEVICE_IDS="6"                                    # 单卡设备ID
NPROC_PER_NODE=$(echo $DEVICE_IDS | tr ',' '\n' | wc -l)
MASTER_PORT=29508

# ====================== 设备配置 ======================
export ASCEND_RT_VISIBLE_DEVICES=${DEVICE_IDS}

TIME_STR=`date +"%Y%m%d%H%M%S"`

# ====================== 执行推理 ======================
torchrun --nproc_per_node=${NPROC_PER_NODE} --master-port ${MASTER_PORT} generate.py \
    --task ${TASK} \
    --ckpt_dir ${MODEL_PATH} \
    --prompt '''A coffee shop entrance features a chalkboard sign reading "Qwen Coffee 😊 $2 per cup," with a neon light beside it displaying "通义千问". Next to it hangs a poster showing a beautiful Chinese woman, and beneath the poster is written "π≈3.1415926-53589793-23846264-33832795-02384197". Ultra HD, 4K, cinematic composition''' \
    --negative_prompt " " \
    --width 1024 \
    --height 1024 \
    --num_inference_steps 50 \
    --seed 42 \
    --output_file "./output/text_to_image-1-${TIME_STR}.png" \
    --vae_tiling \
    --vae_slicing \

推理结果:50步推理端到端耗时约 25.57秒。

验证日志(Qwen-Image单卡日志(COND_CACHE).txt):

[Rank 0][2026-03-17 11:36:18][INFO] 开始初始化推理环境,Rank:0/0,本地Rank:0
[Rank 0][2026-03-17 11:36:18][INFO] 初始化NPU设备成功,设备ID:0
[Rank 0][2026-03-17 11:36:18][INFO] 模型数据类型:torch.bfloat16,运行设备:npu:0
Loading checkpoint shards: 100%|██████████| 9/9 [00:00<00:00, 23.83it/s]
[Rank 0][2026-03-17 11:36:19][INFO] 开始初始化Qwen-Image任务Pipeline
Loading pipeline components...: 100%|██████████| 5/5 [00:00<00:00,  5.90it/s]
[Rank 0][2026-03-17 11:36:23][INFO] 启用VAE分块推理(vae_tiling)
[Rank 0][2026-03-17 11:36:23][INFO] 启用VAE切片推理(vae_slicing)
[Rank 0][2026-03-17 11:36:23][INFO] 启用缓存配置,COND_CACHE=True, UNCOND_CACHE=True,配置:{'method': 'dit_block_cache', 'blocks_count': 60, 'steps_count': 50, 'step_start': 10, 'step_interval': 3, 'step_end': 35, 'block_start': 10, 'block_end': 50}
[Rank 0][2026-03-17 11:36:23][INFO] 开始模型预热(3步推理),解决首次算子编译耗时
100%|██████████| 3/3 [00:03<00:00,  1.32s/it]
100%|██████████| 50/50 [00:24<00:00,  2.05it/s]
[Rank 0][2026-03-17 11:36:56][INFO] 正式推理完成,端到端耗时:25.5781秒
[Rank 0][2026-03-17 11:36:56][INFO] 生成图片保存成功:/data01/xxx/Qwen-Image-series/output/text_to_image-1-20260317113557_0.png
[Rank 0][2026-03-17 11:36:56][INFO] 开始释放推理资源,清理显存/内存
[Rank 0][2026-03-17 11:37:00][INFO] 资源释放完成
[Rank 0][2026-03-17 11:37:00][INFO] Rank 0 推理任务全部完成

5.1.2 双卡推理

使用 test-Qwen-Image-2.sh 脚本执行双卡推理:

bash test-Qwen-Image-2.sh

脚本内容解析:

#!/bin/bash
set -e

# ====================== 全局环境变量配置 ======================
export PYTORCH_NPU_ALLOC_CONF='expandable_segments:True'
export ALGO=2               # 使用高性能FA算子(LA)
export OVERLAP=0            # 通信-计算重叠开关
export ROPE_FUSE=1          # RoPE算子融合
export ADALN_FUSE=1         # ADALN算子融合

export COND_CACHE=1          # 条件缓存
export UNCOND_CACHE=1        # 无条件缓存
export CACHE_STEP_START=10
export CACHE_STEP_INTERVAL=3
export CACHE_STEP_END=35
export CACHE_BLOCK_START=10
export CACHE_BLOCK_END=50

# ====================== 任务配置 ======================
TASK="Qwen-Image"
MODEL_PATH="../../model/Qwen-Image"
DEVICE_IDS="6,7"                                   # 双卡设备ID
NPROC_PER_NODE=$(echo $DEVICE_IDS | tr ',' '\n' | wc -l)
MASTER_PORT=29508

# ====================== 设备配置 ======================
export ASCEND_RT_VISIBLE_DEVICES=${DEVICE_IDS}

TIME_STR=`date +"%Y%m%d%H%M%S"`

# ====================== 执行推理 ======================
# 2卡并行:cfg_size=2 ulysses_size=1(推荐配置)
torchrun --nproc_per_node=${NPROC_PER_NODE} --master-port ${MASTER_PORT} generate.py \
    --task ${TASK} \
    --ckpt_dir ${MODEL_PATH} \
    --prompt '''A coffee shop entrance features a chalkboard sign reading "Qwen Coffee 😊 $2 per cup," with a neon light beside it displaying "通义千问". Next to it hangs a poster showing a beautiful Chinese woman, and beneath the poster is written "π≈3.1415926-53589793-23846264-33832795-02384197". Ultra HD, 4K, cinematic composition''' \
    --negative_prompt " " \
    --width 1024 \
    --height 1024 \
    --num_inference_steps 50 \
    --seed 42 \
    --output_file "./output/text_to_image-2-${TIME_STR}.png" \
    --vae_tiling \
    --vae_slicing \
    --cfg_size 2 \
    --ulysses_size 1

推理结果:50步推理端到端耗时约 13.41秒,相比单卡加速约 1.91倍。

验证日志(Qwen-Image双卡日志(COND_CACHE).txt):

[Rank 0][2026-03-17 11:39:39][INFO] 开始初始化推理环境,Rank:0/1,本地Rank:0
[Rank 0][2026-03-17 11:39:39][INFO] 初始化NPU设备成功,设备ID:0
[Rank 0][2026-03-17 11:39:39][INFO] 分布式进程组初始化成功,后端:hccl
[Rank 0][2026-03-17 11:39:39][INFO] 并行环境初始化成功,配置:{'tp_degree': 1, 'sp_degree': 1, 'ulysses_degree': 1, 'ring_degree': 1, 'use_cfg_parallel': True, 'world_size': 2, 'cfg_degree': 2}
[Rank 0][2026-03-17 11:39:39][INFO] 模型数据类型:torch.bfloat16,运行设备:npu:0
Loading checkpoint shards: 100%|██████████| 9/9 [00:00<00:00, 24.08it/s]
[Rank 0][2026-03-17 11:39:40][INFO] 开始初始化Qwen-Image任务Pipeline
Loading pipeline components...: 100%|██████████| 5/5 [00:00<00:00,  5.94it/s]
[Rank 0][2026-03-17 11:39:44][INFO] 启用VAE分块推理(vae_tiling)
[Rank 0][2026-03-17 11:39:44][INFO] 启用VAE切片推理(vae_slicing)
[Rank 0][2026-03-17 11:39:44][INFO] 启用缓存配置,COND_CACHE=True, UNCOND_CACHE=True,配置:{'method': 'dit_block_cache', 'blocks_count': 60, 'steps_count': 50, 'step_start': 10, 'step_interval': 3, 'step_end': 35, 'block_start': 10, 'block_end': 50}
[Rank 0][2026-03-17 11:39:44][INFO] 开始模型预热(3步推理),解决首次算子编译耗时
100%|██████████| 3/3 [00:03<00:00,  1.24s/it]
100%|██████████| 50/50 [00:12<00:00,  4.09it/s]
[Rank 0][2026-03-17 11:40:05][INFO] 正式推理完成,端到端耗时:13.4181秒
[Rank 0][2026-03-17 11:40:06][INFO] 生成图片保存成功:/data01/xxx/Qwen-Image-series/output/text_to_image-2-20260317113918_0.png
[Rank 0][2026-03-17 11:40:06][INFO] 开始释放推理资源,清理显存/内存
[Rank 0][2026-03-17 11:40:10][INFO] 资源释放完成
[Rank 0][2026-03-17 11:40:10][INFO] 分布式进程组销毁成功
[Rank 0][2026-03-17 11:40:10][INFO] Rank 0 推理任务全部完成

5.2 Qwen-Image-2512 文生图(增强版)

5.2.1 单卡推理

使用 test-Qwen-Image-2512-1.sh 脚本执行单卡推理:

bash test-Qwen-Image-2512-1.sh

脚本内容解析:

#!/bin/bash
set -e

# ====================== 全局环境变量配置 ======================
export PYTORCH_NPU_ALLOC_CONF='expandable_segments:True'
export ALGO=2               # 0:普通, 1:FA, 2:LA
export OVERLAP=0            # 通信-计算重叠开关
export ROPE_FUSE=1          # RoPE算子融合
export ADALN_FUSE=1         # ADALN算子融合

export COND_CACHE=1          # 条件缓存
export UNCOND_CACHE=1        # 无条件缓存
export CACHE_STEP_START=10
export CACHE_STEP_INTERVAL=3
export CACHE_STEP_END=35
export CACHE_BLOCK_START=10
export CACHE_BLOCK_END=50

# ====================== 任务配置 ======================
TASK="Qwen-Image-2512"
MODEL_PATH="../../model/Qwen-Image-2512"
DEVICE_IDS="6"
NPROC_PER_NODE=$(echo $DEVICE_IDS | tr ',' '\n' | wc -l)
MASTER_PORT=29508

# ====================== 设备配置 ======================
export ASCEND_RT_VISIBLE_DEVICES=${DEVICE_IDS}

TIME_STR=`date +"%Y%m%d%H%M%S"`

# ====================== 执行推理 ======================
torchrun --nproc_per_node=${NPROC_PER_NODE} --master-port ${MASTER_PORT} generate.py \
    --task ${TASK} \
    --ckpt_dir ${MODEL_PATH} \
    --prompt '''A coffee shop entrance features a chalkboard sign reading "Qwen Coffee 😊 $2 per cup," with a neon light beside it displaying "通义千问". Next to it hangs a poster showing a beautiful Chinese woman, and beneath the poster is written "π≈3.1415926-53589793-23846264-33832795-02384197". Ultra HD, 4K, cinematic composition''' \
    --negative_prompt " " \
    --width 1024 \
    --height 1024 \
    --num_inference_steps 50 \
    --seed 42 \
    --output_file "./output/text_to_image_2512-1-${TIME_STR}.png" \
    --vae_tiling \
    --vae_slicing \

推理结果:50步推理端到端耗时约 25.58秒。

验证日志(Qwen-Image-2512单卡日志(COND_CACHE).txt):

[Rank 0][2026-03-14 13:24:56][INFO] 开始初始化推理环境,Rank:0/0,本地Rank:0
[Rank 0][2026-03-14 13:24:56][INFO] 初始化NPU设备成功,设备ID:0
[Rank 0][2026-03-14 13:24:56][INFO] 模型数据类型:torch.bfloat16,运行设备:npu:0
Loading checkpoint shards: 100%|██████████| 9/9 [00:00<00:00, 23.52it/s]
[Rank 0][2026-03-14 13:24:56][INFO] 开始初始化Qwen-Image-2512任务Pipeline
Loading pipeline components...: 100%|██████████| 5/5 [00:00<00:00,  5.89it/s]
[Rank 0][2026-03-14 13:25:01][INFO] 启用VAE分块推理(vae_tiling)
[Rank 0][2026-03-14 13:25:01][INFO] 启用VAE切片推理(vae_slicing)
[Rank 0][2026-03-14 13:25:01][INFO] 启用缓存配置,COND_CACHE=True, UNCOND_CACHE=True,配置:{'method': 'dit_block_cache', 'blocks_count': 60, 'steps_count': 50, 'step_start': 10, 'step_interval': 3, 'step_end': 35, 'block_start': 10, 'block_end': 50}
[Rank 0][2026-03-14 13:25:01][INFO] 开始模型预热(3步推理),解决首次算子编译耗时
[Rank 0][2026-03-14 13:25:34][INFO] 正式推理完成,端到端耗时:25.5883秒
[Rank 0][2026-03-14 13:25:34][INFO] 生成图片保存成功:/data01/xxx/Qwen-Image-series/output/text_to_image_2512-1-20260314132435_0.png
[Rank 0][2026-03-14 13:25:34][INFO] 开始释放推理资源,清理显存/内存
[Rank 0][2026-03-14 13:25:38][INFO] 资源释放完成
[Rank 0][2026-03-14 13:25:38][INFO] Rank 0 推理任务全部完成

5.2.2 双卡推理

使用 test-Qwen-Image-2512-2.sh 脚本执行双卡推理:

bash test-Qwen-Image-2512-2.sh

脚本内容解析:

#!/bin/bash
set -e

# ====================== 全局环境变量配置 ======================
export PYTORCH_NPU_ALLOC_CONF='expandable_segments:True'
export ALGO=2               # 0:普通, 1:FA, 2:LA
export OVERLAP=0            # 通信-计算重叠开关
export ROPE_FUSE=1          # RoPE算子融合
export ADALN_FUSE=1         # ADALN算子融合

export COND_CACHE=1          # 条件缓存
export UNCOND_CACHE=1        # 无条件缓存
export CACHE_STEP_START=10
export CACHE_STEP_INTERVAL=3
export CACHE_STEP_END=35
export CACHE_BLOCK_START=10
export CACHE_BLOCK_END=50

# ====================== 任务配置 ======================
TASK="Qwen-Image-2512"
MODEL_PATH="../../model/Qwen-Image-2512"
DEVICE_IDS="6,7"
NPROC_PER_NODE=$(echo $DEVICE_IDS | tr ',' '\n' | wc -l)
MASTER_PORT=29508

# ====================== 设备配置 ======================
export ASCEND_RT_VISIBLE_DEVICES=${DEVICE_IDS}

TIME_STR=`date +"%Y%m%d%H%M%S"`

# ====================== 执行推理 ======================
# 2卡并行:cfg_size=2 ulysses_size=1(推荐配置)
torchrun --nproc_per_node=${NPROC_PER_NODE} --master-port ${MASTER_PORT} generate.py \
    --task ${TASK} \
    --ckpt_dir ${MODEL_PATH} \
    --prompt '''A coffee shop entrance features a chalkboard sign reading "Qwen Coffee 😊 $2 per cup," with a neon light beside it displaying "通义千问". Next to it hangs a poster showing a beautiful Chinese woman, and beneath the poster is written "π≈3.1415926-53589793-23846264-33832795-02384197". Ultra HD, 4K, cinematic composition''' \
    --negative_prompt " " \
    --width 1024 \
    --height 1024 \
    --num_inference_steps 50 \
    --seed 42 \
    --output_file "./output/text_to_image_2512-2-${TIME_STR}.png" \
    --vae_tiling \
    --vae_slicing \
    --cfg_size 2 \
    --ulysses_size 1

推理结果:50步推理端到端耗时约 13.35秒,相比单卡加速约 1.92倍。

验证日志(Qwen-Image-2512双卡日志(COND_CACHE).txt):

[Rank 0][2026-03-14 17:36:31][INFO] 开始初始化推理环境,Rank:0/1,本地Rank:0
[Rank 0][2026-03-14 17:36:31][INFO] 初始化NPU设备成功,设备ID:0
[Rank 0][2026-03-14 17:36:31][INFO] 分布式进程组初始化成功,后端:hccl
[Rank 0][2026-03-14 17:36:31][INFO] 并行环境初始化成功,配置:{'tp_degree': 1, 'sp_degree': 1, 'ulysses_degree': 1, 'ring_degree': 1, 'use_cfg_parallel': True, 'world_size': 2, 'cfg_degree': 2}
[Rank 0][2026-03-14 17:36:31][INFO] 模型数据类型:torch.bfloat16,运行设备:npu:0
Loading checkpoint shards: 100%|██████████| 9/9 [00:00<00:00, 23.56it/s]
[Rank 0][2026-03-14 17:36:32][INFO] 开始初始化Qwen-Image-2512任务Pipeline
Loading pipeline components...: 100%|██████████| 5/5 [00:00<00:00,  5.90it/s]
[Rank 0][2026-03-14 17:36:36][INFO] 启用VAE分块推理(vae_tiling)
[Rank 0][2026-03-14 17:36:36][INFO] 启用VAE切片推理(vae_slicing)
[Rank 0][2026-03-14 17:36:36][INFO] 启用缓存配置,COND_CACHE=True, UNCOND_CACHE=True,配置:{'method': 'dit_block_cache', 'blocks_count': 60, 'steps_count': 50, 'step_start': 10, 'step_interval': 3, 'step_end': 35, 'block_start': 10, 'block_end': 50}
[Rank 0][2026-03-14 17:36:36][INFO] 开始模型预热(3步推理),解决首次算子编译耗时
[Rank 0][2026-03-14 17:36:57][INFO] 正式推理完成,端到端耗时:13.3536秒
[Rank 0][2026-03-14 17:36:58][INFO] 生成图片保存成功:/data01/xxx/Qwen-Image-series/output/text_to_image_2512-2-20260314173610_0.png
[Rank 0][2026-03-14 17:36:58][INFO] 开始释放推理资源,清理显存/内存
[Rank 0][2026-03-14 17:37:01][INFO] 资源释放完成
[Rank 0][2026-03-14 17:37:01][INFO] 分布式进程组销毁成功
[Rank 0][2026-03-14 17:37:01][INFO] Rank 0 推理任务全部完成

5.3 Qwen-Image-Edit-2511 图生图

5.3.1 单卡推理

使用 test-Qwen-Image-Edit-2511-1.sh 脚本执行单卡推理:

bash test-Qwen-Image-Edit-2511-1.sh

脚本内容解析:

#!/bin/bash
set -e

# ====================== 全局环境变量配置 ======================
export PYTORCH_NPU_ALLOC_CONF='expandable_segments:True'
export ALGO=2               # 0:普通, 1:FA, 2:LA
export OVERLAP=0            # 通信-计算重叠开关
export ROPE_FUSE=1          # RoPE算子融合
export ADALN_FUSE=1         # ADALN算子融合

export COND_CACHE=1          # 条件缓存
export UNCOND_CACHE=1        # 无条件缓存
export CACHE_STEP_START=10
export CACHE_STEP_INTERVAL=3
export CACHE_STEP_END=35
export CACHE_BLOCK_START=10
export CACHE_BLOCK_END=50

# ====================== 任务配置 ======================
TASK="Qwen-Image-Edit-2511"
MODEL_PATH="../../model/Qwen-Image-Edit-2511"
DEVICE_IDS="6"
NPROC_PER_NODE=$(echo $DEVICE_IDS | tr ',' '\n' | wc -l)
MASTER_PORT=29508

# ====================== 设备配置 ======================
export ASCEND_RT_VISIBLE_DEVICES=${DEVICE_IDS}

TIME_STR=`date +"%Y%m%d%H%M%S"`

# ====================== 执行推理 ======================
torchrun --nproc_per_node=${NPROC_PER_NODE} --master-port ${MASTER_PORT} generate.py \
    --task ${TASK} \
    --ckpt_dir ${MODEL_PATH} \
    --image "./examples/yarn-art-pikachu.png" \
    --prompt "Make Pikachu hold a sign that says 'Qwen Edit is awesome', yarn art style, detailed, vibrant color" \
    --negative_prompt " " \
    --width 1024 \
    --height 1024 \
    --num_inference_steps 40 \
    --seed 42 \
    --output_file "./output/image_edit_2511-1-${TIME_STR}.png" \
    --vae_tiling \
    --vae_slicing \

推理结果:40步推理端到端耗时约 50.64秒。

验证日志(Qwen-Image-Edit-2511单卡日志(COND_CACHE).txt):

[Rank 0][2026-03-14 13:10:20][INFO] 开始初始化推理环境,Rank:0/0,本地Rank:0
[Rank 0][2026-03-14 13:10:20][INFO] 初始化NPU设备成功,设备ID:0
[Rank 0][2026-03-14 13:10:20][INFO] 模型数据类型:torch.bfloat16,运行设备:npu:0
Loading checkpoint shards: 100%|██████████| 5/5 [00:02<00:00,  2.47it/s]
[Rank 0][2026-03-14 13:10:23][INFO] 开始初始化Qwen-Image-Edit-2511任务Pipeline
Loading pipeline components...: 100%|██████████| 6/6 [00:02<00:00,  2.13it/s]
[Rank 0][2026-03-14 13:10:54][INFO] 启用VAE分块推理(vae_tiling)
[Rank 0][2026-03-14 13:10:54][INFO] 启用VAE切片推理(vae_slicing)
[Rank 0][2026-03-14 13:10:54][INFO] 启用缓存配置,COND_CACHE=True, UNCOND_CACHE=True,配置:{'method': 'dit_block_cache', 'blocks_count': 60, 'steps_count': 40, 'step_start': 10, 'step_interval': 3, 'step_end': 35, 'block_start': 10, 'block_end': 50}
[Rank 0][2026-03-14 13:10:54][INFO] 成功加载图片[1/1]:./examples/yarn-art-pikachu.png
[Rank 0][2026-03-14 13:10:54][INFO] 开始模型预热(3步推理),解决首次算子编译耗时
[Rank 0][2026-03-14 13:11:57][INFO] 正式推理完成,端到端耗时:50.6452秒
[Rank 0][2026-03-14 13:11:58][INFO] 生成图片保存成功:/data01/xxx/Qwen-Image-series/output/image_edit_2511-1-20260314131000_0.png
[Rank 0][2026-03-14 13:11:58][INFO] 开始释放推理资源,清理显存/内存
[Rank 0][2026-03-14 13:12:02][INFO] 资源释放完成
[Rank 0][2026-03-14 13:12:02][INFO] Rank 0 推理任务全部完成

5.3.2 双卡推理

使用 test-Qwen-Image-Edit-2511-2.sh 脚本执行双卡推理:

bash test-Qwen-Image-Edit-2511-2.sh

脚本内容解析:

#!/bin/bash
set -e

# ====================== 全局环境变量配置 ======================
export PYTORCH_NPU_ALLOC_CONF='expandable_segments:True'
export ALGO=2               # 0:普通, 1:FA, 2:LA
export OVERLAP=0            # 通信-计算重叠开关
export ROPE_FUSE=1          # RoPE算子融合
export ADALN_FUSE=1         # ADALN算子融合

export COND_CACHE=1          # 条件缓存
export UNCOND_CACHE=1        # 无条件缓存
export CACHE_STEP_START=10
export CACHE_STEP_INTERVAL=3
export CACHE_STEP_END=35
export CACHE_BLOCK_START=10
export CACHE_BLOCK_END=50

# ====================== 任务配置 ======================
TASK="Qwen-Image-Edit-2511"
MODEL_PATH="../../model/Qwen-Image-Edit-2511"
DEVICE_IDS="6,7"
NPROC_PER_NODE=$(echo $DEVICE_IDS | tr ',' '\n' | wc -l)
MASTER_PORT=29508

# ====================== 设备配置 ======================
export ASCEND_RT_VISIBLE_DEVICES=${DEVICE_IDS}

TIME_STR=`date +"%Y%m%d%H%M%S"`

# ====================== 执行推理 ======================
# 2卡并行:cfg_size=2 ulysses_size=1(推荐配置)
torchrun --nproc_per_node=${NPROC_PER_NODE} --master-port ${MASTER_PORT} generate.py \
    --task ${TASK} \
    --ckpt_dir ${MODEL_PATH} \
    --image "./examples/yarn-art-pikachu.png" \
    --prompt "Make Pikachu hold a sign that says 'Qwen Edit is awesome', yarn art style, detailed, vibrant color" \
    --negative_prompt " " \
    --width 1024 \
    --height 1024 \
    --num_inference_steps 40 \
    --seed 42 \
    --output_file "./output/image_edit_2511-2-${TIME_STR}.png" \
    --vae_tiling \
    --vae_slicing \
    --cfg_size 2 \
    --ulysses_size 1

推理结果:40步推理端到端耗时约 26.23秒,相比单卡加速约 1.93倍。

验证日志(Qwen-Image-Edit-2511双卡日志(COND_CACHE).txt):

[Rank 0][2026-03-14 13:19:19][INFO] 开始初始化推理环境,Rank:0/1,本地Rank:0
[Rank 0][2026-03-14 13:19:19][INFO] 初始化NPU设备成功,设备ID:0
[Rank 0][2026-03-14 13:19:19][INFO] 分布式进程组初始化成功,后端:hccl
[Rank 0][2026-03-14 13:19:19][INFO] 并行环境初始化成功,配置:{'tp_degree': 1, 'sp_degree': 1, 'ulysses_degree': 1, 'ring_degree': 1, 'use_cfg_parallel': True, 'world_size': 2, 'cfg_degree': 2}
[Rank 0][2026-03-14 13:19:19][INFO] 模型数据类型:torch.bfloat16,运行设备:npu:0
Loading checkpoint shards: 100%|██████████| 5/5 [00:00<00:00, 16.20it/s]
[Rank 0][2026-03-14 13:19:19][INFO] 开始初始化Qwen-Image-Edit-2511任务Pipeline
Loading pipeline components...: 100%|██████████| 6/6 [00:02<00:00,  2.92it/s]
[Rank 0][2026-03-14 13:19:26][INFO] 启用VAE分块推理(vae_tiling)
[Rank 0][2026-03-14 13:19:26][INFO] 启用VAE切片推理(vae_slicing)
[Rank 0][2026-03-14 13:19:26][INFO] 启用缓存配置,COND_CACHE=True, UNCOND_CACHE=True,配置:{'method': 'dit_block_cache', 'blocks_count': 60, 'steps_count': 40, 'step_start': 10, 'step_interval': 3, 'step_end': 35, 'block_start': 10, 'block_end': 50}
[Rank 0][2026-03-14 13:19:26][INFO] 成功加载图片[1/1]:./examples/yarn-art-pikachu.png
[Rank 0][2026-03-14 13:19:26][INFO] 开始模型预热(3步推理),解决首次算子编译耗时
[Rank 0][2026-03-14 13:20:02][INFO] 正式推理完成,端到端耗时:26.2365秒
[Rank 0][2026-03-14 13:20:02][INFO] 生成图片保存成功:/data01/xxx/Qwen-Image-series/output/image_edit_2511-2-20260314131858_0.png
[Rank 0][2026-03-14 13:20:06][INFO] 开始释放推理资源,清理显存/内存
[Rank 0][2026-03-14 13:20:06][INFO] 资源释放完成
[Rank 0][2026-03-14 13:20:06][INFO] 分布式进程组销毁成功
[Rank 0][2026-03-14 13:20:06][INFO] Rank 0 推理任务全部完成

五、优化手段总结

本推理方案从算子级优化、算法级优化、显存优化、并行加速和推理流程优化五个维度进行了全面优化,充分发挥昇腾 NPU 硬件性能。

6.1 算子级优化(等价优化,不影响生成质量)

优化项环境变量说明
高性能 Attention 算子(LA)ALGO=2替换默认 SDPA 算子为昇腾自研 Laser Attention(LA)算子。ALGO=0 为默认 SDPA,ALGO=1 为 FA 算子,ALGO=2 为高性能 FA 算子(推荐)
RoPE 算子融合ROPE_FUSE=1将 Rotary Position Embedding 的多个小算子融合为一个大算子,减少 kernel launch 开销
ADALN 算子融合ADALN_FUSE=1将 Adaptive Layer Normalization 相关算子融合,减少显存访问次数

6.2 算法级优化(缓存加速,可能轻微影响生成质量)

优化项环境变量说明
条件输入缓存(COND_CACHE)COND_CACHE=1在扩散去噪过程中,条件分支的 DiT Block 输出在特定步骤间变化较小,可缓存复用,跳过冗余计算
无条件输入缓存(UNCOND_CACHE)UNCOND_CACHE=1同理,无条件分支的 DiT Block 输出也可缓存复用

缓存参数精细控制:

参数默认值说明
CACHE_STEP_START10缓存开始的去噪步骤(前几步变化剧烈,不宜缓存)
CACHE_STEP_INTERVAL3缓存间隔步数(每隔几步复用一次缓存)
CACHE_STEP_END35缓存结束的去噪步骤(后续步骤需精确计算)
CACHE_BLOCK_START10缓存起始 Block 编号
CACHE_BLOCK_END50缓存结束 Block 编号
CACHE_BLOCKS_COUNT60DiT 总 Block 数量

原理:扩散模型在去噪过程中,中间步骤的 DiT Block 输出变化较小(尤其是无条件分支),通过 dit_block_cache 方法在指定步骤范围内对特定 Block 的输出进行缓存和复用,避免重复计算,从而实现约 1.3~1.6 倍的加速。

6.3 显存优化

优化项启动参数说明
VAE Tiling--vae_tiling将 VAE 解码过程分块处理,每次只处理图像的一个 tile,大幅降低 VAE 解码的峰值显存占用
VAE Slicing--vae_slicing将 VAE 解码的 batch 维度切片处理,逐 batch 推理,降低显存峰值
低 CPU 内存加载low_cpu_mem_usage=True模型加载时使用低内存模式,避免加载过程中 CPU 内存溢出
NPU 显存动态分配PYTORCH_NPU_ALLOC_CONF='expandable_segments:True'启用 NPU 显存段的动态扩展,减少显存碎片,提高显存利用率
模型量化--quant_dit_path支持 w8a8(8bit权重+8bit激活)和 w8a16(8bit权重+16bit激活)量化,降低 DiT 模型显存占用

6.4 并行加速

优化项启动参数说明
CFG 并行--cfg_size 2Classifier-Free Guidance 的条件/无条件分支分别在两张卡上并行计算,避免串行执行,是最有效的双卡并行策略
Ulysses 序列并行--ulysses_size N将 Transformer 的序列维度切分到多张卡上并行计算,ulysses_size 需为 24 的因数
通信-计算重叠OVERLAP=1在开启 Ulysses 并行时,将通信操作与计算操作重叠执行,隐藏通信延迟(仅在 Ulysses + 多卡环境下生效)

并行策略推荐(卡数与并行度对应关系):

卡数推荐 cfg_size推荐 ulysses_size说明
111单卡无并行
221CFG 并行优于 Ulysses
422CFG + Ulysses 组合
824CFG + Ulysses 组合
1628CFG + Ulysses 组合

约束:cfg_size × ulysses_size 必须等于分布式进程数(即使用的 NPU 卡数),且 cfg_size 只能取值 1 或 2。

6.5 推理流程优化

优化项实现方式说明
模型预热先运行 3 步推理首次推理会触发算子编译(JIT),预热 3 步后再进行正式推理,排除编译耗时
分布式屏障同步dist.barrier()预热完成后等待所有进程同步,确保正式推理前各进程状态一致
设备同步计时torch.npu.synchronize()在计时前后进行设备同步,确保耗时统计准确
资源及时释放显式 del + gc + empty_cache推理完成后显式释放模型、pipeline,执行垃圾回收和 NPU 显存清空,避免显存泄漏和碎片

6.6 优化效果汇总

以下为 1024×1024 分辨率、开启全部优化(等价优化 + 缓存加速)的端到端推理耗时:

模型推理步数单卡耗时双卡耗时双卡加速比
Qwen-Image50步~25.57秒~13.41秒~1.91x
Qwen-Image-251250步~25.58秒~13.35秒~1.92x
Qwen-Image-Edit-251140步~50.64秒~26.23秒~1.93x

六、参数说明

7.1 环境变量参数

参数可选值默认值说明
ALGO0/1/20Attention 算子选择:0=SDPA,1=FA,2=LA(推荐)
OVERLAP0/10通信-计算重叠开关,需配合 Ulysses 并行使用
ROPE_FUSE0/10RoPE 算子融合开关
ADALN_FUSE0/10ADALN 算子融合开关
COND_CACHE0/10条件输入缓存开关
UNCOND_CACHE0/10无条件输入缓存开关
CACHE_STEP_START整数10缓存开始步骤
CACHE_STEP_INTERVAL整数3缓存步骤间隔
CACHE_STEP_END整数35缓存结束步骤
CACHE_BLOCK_START整数10缓存开始块
CACHE_BLOCK_END整数50缓存结束块
PYTORCH_NPU_ALLOC_CONF--NPU 显存分配策略

7.2 命令行参数

参数类型默认值说明
--taskstrQwen-Image推理任务类型
--ckpt_dirstrQwen/Qwen-Image模型权重路径
--promptstr示例提示词正面提示词
--negative_promptstr" "负面提示词
--widthint1024生成图片宽度
--heightint1024生成图片高度
--num_inference_stepsint50去噪步数
--seedint42随机种子
--output_filestrtext_to_image.png输出图片路径
--vae_tilingflagFalse启用 VAE 分块推理
--vae_slicingflagFalse启用 VAE 切片推理
--cfg_sizeint1CFG 并行度(1或2)
--ulysses_sizeint1Ulysses 并行度
--cfg_scalefloat4.0True CFG 缩放系数
--guidance_scalefloat1.0引导系数
--quant_dit_pathstrNone量化模型路径(启用则加载量化权重)
--lora_pathstrNoneLoRA 权重路径
--torch_dtypestrbfloat16数据类型

七、常见问题

Q1:显存不足怎么办?

开启 --vae_tiling --vae_slicing 降低 VAE 显存占用;降低 --width / --height 分辨率;使用量化模型(--quant_dit_path)。

Q2:多卡通信失败怎么办?

检查 ASCEND_RT_VISIBLE_DEVICES 是否正确设置,检查 --master-port 端口是否被占用,确保 cfg_size × ulysses_size 等于使用的卡数。

Q3:推理结果不一致怎么办?

固定 --seed 参数;注意缓存优化(COND_CACHE/UNCOND_CACHE)可能轻微影响生成质量,可按需调整缓存参数或关闭缓存。

Q4:如何调整模型权重路径?

修改脚本中的 MODEL_PATH 变量,指向模型权重的实际本地路径。