字节笔记本
2026年8月29日
本机跑 Qwen Z-Image:DiT 架构和显存实测
通义的 Z-Image-Turbo(造相)官方说消费级 16GB 显存就能跑。这句话在 30/40 系卡上大体成立,换到 RTX 20 系就容易翻车:卡不支持 BF16,只能上 FP32,显存立刻翻倍;再叠一层 DiT 的 Attention,分辨率一拉高就会爆仓。下面按架构、实测和一套本机 Web 生成器,把这条路跑通。
先分清两个模型
Z-Image 不是那个 20B 的 Qwen-Image。它是阿里通义 MAI 团队的 6B 图像生成家族,架构叫 S3-DiT(Scalable Single-Stream Diffusion Transformer):文本 token、视觉语义 token 和图像 VAE token 拼成一条序列,走单流 Transformer,而不是 Stable Diffusion 那套 U-Net。家族里常用的是蒸馏版 Z-Image-Turbo:8 步就能出图,官方给的消费级目标是 16GB 显存。
权重和文档:
Turbo 的推理参数也和普通扩散模型不一样:guidance_scale 必须是 0.0(没有 CFG),步数官方示例写 num_inference_steps=9(实际是 8 次 DiT 前向)。
为什么 1024 方图会爆显存
U-Net 时代,分辨率涨一档,卷积显存大致按像素数线性涨。DiT 的核心是 Attention,序列长度跟 token 数走,计算量和激活显存大致按序列长度的平方涨。1024×1024 相对 1024×768,token 数大约多三分之一,Attention 开销不是多三分之一那么简单。
所以本机调参时,先降分辨率,比先上量化更直接。一张 2080 Ti(22GB)在 FP32 下扛不住 1024×1024,换成 1024×768 就能稳定出图。这不是模型“写坏了”,是单流 DiT 在全精度下的正常代价。
官方那句「16GB 消费级」默认的是 BF16。BF16 支持从 Ampere(30 系)开始才比较齐,Turing(20 系)没有这条路径。
20 系卡:别用 FP16,用 FP32
实测下来,精度选择可以记三条:
| 显卡世代 | 建议精度 | 原因 |
|---|---|---|
| 30 / 40 / 50 系 | BF16 | 官方推荐,16GB 级别能跑 1024 方图 |
| 20 系(2080 Ti 等) | FP32 | 没有 BF16;FP16 容易出全黑图 |
| 更老的卡 | FP32 + CPU offload,并降分辨率 | 不要硬上 1024 方图 |
FP16 在这套模型上是黑图的常见源头,VAE 解码再溢一次就更黑。社区里比较稳的补丁是:主干用 BF16 或 FP32,VAE 强制锁 FP32,调度器 shift 设成 3.0。缺任何一条,Turbo 都可能吐出噪点或纯黑。
官方 diffusers 路径
需要比较新的 diffusers(Z-Image 的两个 PR 已经合进主干):
pip install git+https://github.com/huggingface/diffusers
pip install transformers accelerate torch有 BF16 的卡,直接按官方示例:
import torch
from diffusers import ZImagePipeline
pipe = ZImagePipeline.from_pretrained(
"Tongyi-MAI/Z-Image-Turbo",
torch_dtype=torch.bfloat16,
low_cpu_mem_usage=False,
)
pipe.to("cuda")
image = pipe(
prompt="红衣汉服少女,室外夜景,大雁塔剪影",
height=1024,
width=1024,
num_inference_steps=9,
guidance_scale=0.0,
generator=torch.Generator("cuda").manual_seed(42),
).images[0]
image.save("example.png")显存紧张时打开 offload,不要硬 to("cuda"):
pipe.enable_model_cpu_offload()20 系卡把 torch_dtype 改成 torch.float32,分辨率先用 1024, 768。第一次编译会慢,官方也提到可以对 transformer 做 compile(),首张图要等,后面会快。
权重也可以从 ModelScope 拉,国内机器通常比 Hugging Face 稳。文件不要塞进 Git:text encoder、transformer、VAE 都是分片 safetensors,仓库里只留代码和 model_index.json。
一套带 Web 界面的本机生成器
如果只想在浏览器里填提示词、看历史图,不必每次写脚本,可以用 Maxwell_Peng_pengjin/Qwen。它是一个本地 HTTP 服务:后端 zimage_web_generator.py 加载当前目录的 Z-Image-Turbo,前端 zimage_generator.html 提供中文界面。针对 2080 Ti 做了精度切换、VAE 锁定和 CPU offload,1024×768 大约 20 秒一张。
目录怎么摆
git clone https://gitee.com/Maxwell_Peng_pengjin/Qwen.git
cd Qwen
pip install diffusers transformers accelerate torch模型文件从 Tongyi-MAI/Z-Image-Turbo 单独下载,放到仓库根目录,结构大致是:
Qwen/
├── zimage_web_generator.py
├── zimage_generator.html
├── model_index.json
├── text_encoder/
├── transformer/
├── vae/
├── scheduler/
└── tokenizer/不要指望 clone 下来就能生成。那几个 safetensors 分片体积很大,README 写得很清楚:从 Hugging Face 拉,不要从 Git 拉。
启动
Windows 可以用仓库里的 start_web_generator_improved.bat。手动启动:
python zimage_web_generator.py浏览器打开 http://localhost:8080。界面里选尺寸时,20 系卡优先 1024×768 或 768×768,不要一上来就 1024 方图。
生成器里几处值得看的实现:
- 用
torch.cuda.is_bf16_supported()决定 BF16 / FP32,明确避开 FP16 enable_model_cpu_offload(),22GB 环境下给激活值留空间- VAE 锁 FP32,减少解码溢出
- 调度器改成
FlowMatchEulerDiscreteScheduler,shift=3.0 - Turbo 固定 8 步、
guidance_scale=0.0
这些和官方文档是对齐的,只是把 20 系卡的坑写进了启动逻辑。
出图仍是黑的怎么办
按这个顺序查:
diffusers是不是够新,老版本没有ZImagePipeline,用错 pipeline 会直接废- Turbo 的
guidance_scale必须是 0,套 SD 的 CFG 会把图搞花 - 20 系不要 BF16,也不要 FP16
- 把分辨率降到 1024×768 再试,OOM 和黑图经常一起出现
- 确认 VAE 在 FP32,调度器
shift是 3.0
首张图慢是正常的,CUDA 内核和可能的 compile() 都在这次发生。同一进程里后面的图会快很多。
小结
本机跑 Z-Image-Turbo,真正要记住的不是又一个 WebUI,而是两件事:它是 6B 的单流 DiT,分辨率对显存不线性;20 系卡没有 BF16,FP32 下 1024 方图在 22GB 上也不划算。把精度、offload 和分辨率这三件事设对,官方 pipeline 和上面那套本地生成器都能稳定出图。