图像生成与编辑

Qwen-Image-2.1 可以把提示词变成图像,也可以把提示词加一张或多张参考图变成编辑后的图像。本页包含下载、运行示例、默认值,以及决定出图耗时的设置。

💡

这些命令遵循与文本模型示例相同的约定:Hugging Face CLI、从仓库根目录源码构建,并把 --backend 换成与你硬件匹配的值。参见按家族下载与运行。

Qwen-Image-2.1(提示词 → 图像,提示词 + 图像 → 编辑后的图像)

最短路径是现成的 config/qwen-image-2.1.json。它固定仓库修订版本与 SHA-256 校验,缺什么下什么(共四个文件,约 10.29 GiB),存放到 $TENSORSHARP_MODELS/qwen-image-2.1/;未设置 TENSORSHARP_MODELS 时为仓库内的 models/qwen-image-2.1/。该配置选择 ggml_metal;在已构建 CUDA 后端的 NVIDIA 机器上追加 --backend ggml_cuda;原生 CPU 后端为 ggml_cpu,--backend cpu 则全部用纯 C# 运行(见在 CPU 上运行)。

dotnet build TensorSharp.Cli/TensorSharp.Cli.csproj -c Release
dotnet build TensorSharp.Server.Host/TensorSharp.Server.Host.csproj -c Release

# 文生图
dotnet run --project TensorSharp.Cli -c Release --no-build -- \
  --config config/qwen-image-2.1.json \
  --prompt 'A small orange cat beside a blue ceramic vase, soft daylight, detailed photograph' \
  --width 2048 --height 2048 --diffusion-steps 40 --cfg 1 \
  --diffusion-seed 42 --output generated.png

# 图像编辑
dotnet run --project TensorSharp.Cli -c Release --no-build -- \
  --config config/qwen-image-2.1.json \
  --image generated.png \
  --prompt 'Change the blue vase to a red vase. Preserve the cat, lighting and composition.' \
  --width 2048 --height 2048 --diffusion-steps 40 --cfg 1 \
  --diffusion-seed 42 --output edited.png

# 服务端 + Web UI
dotnet run --project TensorSharp.Server.Host -c Release --no-build -- \
  --config config/qwen-image-2.1.json --host 127.0.0.1 --port 5000

如需自己下载这四个文件,请显式传入伴随文件:

hf download Abiray/Qwen-Image-2.1-GGUF qwen_image_2.1_Q4_K_M.gguf --local-dir models
hf download Comfy-Org/Qwen-Image-2.1 vae/qwen_image_2.1_vae_bf16.safetensors --local-dir models
hf download Qwen/Qwen3-VL-8B-Instruct-GGUF Qwen3VL-8B-Instruct-Q4_K_M.gguf mmproj-Qwen3VL-8B-Instruct-F16.gguf --local-dir models

dotnet TensorSharp.Server.Host/bin/TensorSharp.Server.Host.dll --model models/qwen_image_2.1_Q4_K_M.gguf \
    --qwen-image-vae models/vae/qwen_image_2.1_vae_bf16.safetensors \
    --qwen-image-vl models/Qwen3VL-8B-Instruct-Q4_K_M.gguf \
    --qwen-image-mmproj models/mmproj-Qwen3VL-8B-Instruct-F16.gguf \
    --backend ggml_cuda
组件文件来源
扩散 Transformerqwen_image_2.1_Q4_K_M.ggufAbiray/Qwen-Image-2.1-GGUF
专用 VAEqwen_image_2.1_vae_bf16.safetensorsComfy-Org/Qwen-Image-2.1
文本编码器Qwen3VL-8B-Instruct-Q4_K_M.ggufQwen/Qwen3-VL-8B-Instruct-GGUF
编辑用视觉编码器mmproj-Qwen3VL-8B-Instruct-F16.gguf同一个 Qwen3-VL 仓库

下载大小并不等于推理峰值内存:运行时内存还包括激活值、解码缓冲区和工作权重,更大的图像和多张参考图都会提高内存需求。

其他 Qwen-Image-2.1 GGUF 也能加载。完全不带元数据的文件,例如 Unsloth 的 qwen-image-2.1-Q8_0.gguf(包括张量带 model.diffusion_model. 前缀的情形),会依据张量布局识别——从不依据文件名。伴随文件扫描只匹配 qwen_image_2.1_vae 的 safetensors 文件,以及名字里含 qwen3vl-8b 或 qwen3-vl-8b 的文件,因此名为 mmproj-BF16.gguf 的投影器需要用 --qwen-image-mmproj 指定。在 M5 Pro 上,这个 Unsloth Q8_0 文件生成 1024×1024、40 步用时 337.7 秒,同一次单次对比中 stable-diffusion.cpp 为 383.1 秒。只有 2.1 能加载:更早的 Qwen-Image 或 Qwen-Image-Edit-2511 Transformer 会在加载时被拒绝(退出码 2)。

Qwen-Image-2.1-Turbo(8 步)

Qwen-Image-2.1-Turbo 是同一个 7B Transformer 蒸馏为 8 步 Euler、CFG 1、使用一个固定调度的版本;它的 VAE、文本编码器与视觉投影器就是上面的 2.1 文件。config/qwen-image-2.1-turbo.json 把 AtomicChat 的 Qwen-Image-2.1-Turbo-AD-Q4_K.gguf(4.20 GB)下载到模型根目录下的 qwen-image-2.1/,与上面那些按发布名称存放的 2.1 文件放在一起,因此已存有这些文件的目录只需下载 Transformer。Qwen-Image-2.1-Turbo-Q8_0.gguf(7.59 GB)的 Transformer 最接近全精度检查点(模型卡中相对 BF16 的 LPIPS:0.037,AD-Q4_K 为 0.147);两者使用同一个 Q4_K_M 文本编码器,按模型卡的测量,它让图片偏离的程度与 AD-Q4_K 相当。

dotnet run --project TensorSharp.Cli -c Release --no-build -- \
  --config config/qwen-image-2.1-turbo.json \
  --prompt 'a neon sign that reads "OPEN LATE", rainy night' \
  --width 1024 --height 1024 --diffusion-seed 42 --output turbo.png

图像生成与编辑(Qwen-Image-2.1)

所加载的 qwen_image GGUF 是 Qwen-Image-2.1 扩散 Transformer。TensorSharp 在其旁解析伴随文件——专用 2.1 VAE、Qwen3-VL-8B 文本编码器,以及编辑时使用的 Qwen3-VL mmproj 视觉编码器——也可以用 --qwen-image-vae / --qwen-image-vl / --qwen-image-mmproj 指定(环境变量:TS_QWEN_IMAGE_VAE / TS_QWEN_IMAGE_TE / TS_QWEN_IMAGE_MMPROJ)。原生 RGBA 输入与 PNG 输出保留透明度:Qwen3-VL 条件分支把参考图合成到白色背景上,而 VAE 保留 alpha 通道。

提速的关键是分辨率和步数。削减步数最多的是步数蒸馏 LoRA 插件,它把默认的 40 步换成 4–8 次 Transformer 前向:在 M5 Pro 上,1024×1024、Viggle Turbo 的 6 步整体用时 54.5 秒(见 LoRA 插件)。2K 正方形的潜在图像 token 数是 1K 正方形的四倍,注意力计算也更多,因此 --width 1024 --height 1024 是草图设置。--diffusion-steps 25 --cfg 1 是官方 ComfyUI 生成与编辑工作流使用的更快配置;默认仍为 40 步,更少的步数是质量与速度之间的权衡,并不代表质量相当。CFG 1 本身就意味着每步只做一次 Transformer 前向。快速冒烟测试可用 256×256、一步,它只验证加载和端到端数据通路,不说明图像质量。图像编辑还会从默认开启的前缀 KV 缓存中获益。

可从 CLI(--prompt,编辑时再加 --image)、Web UI(不带附件的提示词会生成图像;附加一张或多张图像即可编辑,并有实时去噪预览)、HTTP API(/api/image-generate 与 /api/image-edit,各有 /stream 变体),或在进程内从 C# 通过 QwenImageModel.GenerateImage() / EditImage() 运行。由于扩散流水线共享可变的工作状态,图像操作会串行执行。完整细节见仓库的 Qwen-Image-2.1 卡片(验证记录见英文版)。

编辑选定区域

在 TensorAgent 或服务端 Web UI 中附加照片,选择缩略图旁的选择区域,涂选或擦除区域,再选择使用选区。该照片成为编辑目标,其余照片保留为参考图。加载 Qwen-Image 2.1,描述修改并发送。编辑器支持鼠标、触摸、触控笔、缩放/平移、撤销/重做、反选和边缘柔化。比较原图用于检查结果;再次编辑恢复照片、选区与提示词。

保存的选区保留目标的原始尺寸,以及选区外精确的解码 RGB/alpha 像素。灰度蒙版中白色编辑、黑色保护;alpha 蒙版中透明像素编辑。蒙版必须与第一张图的尺寸相同。边缘柔化向内渐变。可选裁剪模式仅处理带上下文的选区,再放回原始画布,可减少工作量,但会减少周围上下文。选区内是否按指令修改仍取决于模型。

dotnet run --project TensorSharp.Cli -c Release --no-build -- \
  --config config/qwen-image-2.1.json \
  --image photo.png --mask selection.png --mask-mode grayscale \
  --prompt 'Change the selected vase to red ceramic' \
  --mask-feather 8 --mask-crop --mask-crop-padding 96 \
  --width 1024 --height 1024 --diffusion-seed 42 --output edited.png

--mask-invert 反转选区。柔化范围为 0–1024 个源图像素;裁剪留边为 0–16384(默认 64)。编辑器支持最多 1600 万像素、每边最多 8192 像素,并使用单独的全分辨率 PNG 编辑 HEIC/HEIF 选区。同一套蒙版字段支持 JSON、multipart 与 SSE 图像编辑 API 及 C# 的 QwenImageParams。详细语义与验证边界见模型卡。

在 CPU 上运行(--backend cpu)

--backend cpu 用托管 C# 运行整条流水线,不调用任何 GGML:Transformer(像 ggml-cpu 那样使用 8 位激活、在多行整数 GEMM 上计算;分块 flash attention;不合并的 LoRA)、位于主机内存的前缀 KV 缓存、同样基于整数 GEMM 的 Qwen3-VL 文本编码器与基于 packed F32 GEMM 的视觉编码器,以及以隐式 im2col packed 卷积实现、在每个逻辑 CPU 一个线程的线程池上运行的 VAE。在这个后端上,未指定尺寸的请求输出 1024×1024(1 百万像素);ggml_cpu 与 GPU 后端保持 2048×2048。这个后端会拒绝 --tp。在 i7-11800H(8 核 16 线程、AVX-512、32 GB)上实测,文生图,种子 42:

运行cpuggml_cpu与 ggml_cpu 图像对比
256×256、2 步16.9–17.1 s(VAE 解码 2.8–2.9 s)36.1–36.4 s(VAE 解码 10.8–11.2 s)PSNR 37.7 dB,SSIM 0.984
512×512、Pruna 5 步 LoRA118 s(每步 17.6–21.7 s)295.7 s(VAE 解码 50.3 s)PSNR 32.9 dB,SSIM 0.972

两者图像不同,是因为托管 Transformer 的求和顺序与 ggml-cpu 不同,并且在 ggml-cpu 使用 F16 GELU 表的地方保持 F32。TS_QWEN21_CPU_MATMUL=f32(F32 激活乘以反量化的权重分块,之前的默认值)更慢(上面两次运行分别为 20.4 s 与 169.6 s),数值更稳定。另有两次更大的运行是用这个 F32 Transformer 测的:1024×1024、Pruna LoRA 用时 756 s,ggml_cpu 为 1101 s;512×512 编辑为 224 s 对 353 s。在 CPU 上,内存是限制所在:估计峰值放不下的尺寸会在开始任何工作之前被拒绝(TS_QWEN_IMAGE_CPU_MEMORY_CHECK=0 可跳过);1024×1024 的 Pruna 生成提交内存峰值为 3.7 GiB,2048×2048 的 VAE 编码加解码为 10.5 GiB。内核开关(TS_QWEN21_CPU_*、TS_QWEN_TE_CPU_MATMUL、TS_CPU_GEMM_THREADS)见模型卡。

前缀 KV 缓存

文本与参考图 token 用 t = 0 调制,并且从不关注正在生成的图像,因此它们的 K 和 V 在每个去噪步都相同。TensorSharp 实现了官方的前缀 KV 缓存:第一步运行整个序列,把每个块前缀部分的 K 和 V 存到设备上;之后每一步只计算目标图像的 token。它默认开启(TS_QWEN21_PREFIX_CACHE=0 关闭),存的正是注意力读取的类型——Metal 与 CUDA flash attention 为 F16,其他为 F32——因此在默认存储下输出 PNG 与不用缓存时逐字节相同。CFG 运行为每个分支各保留一份缓存,所有缓存都在 VAE 解码前释放。代价是内存:F16 下每个前缀 token、每个分支 512 KiB,每张约 1 百万像素的参考图约 2 GiB。一份缓存最多使用设备报告的空闲内存的一半(TS_QWEN21_PREFIX_CACHE_MAX_MIB 可进一步限制),放不下时会被拒绝并给出警告;TS_QWEN21_PREFIX_CACHE_TYPE=q8_0 或 q8_0_v 以 8 位存储,节省内存,但每步慢 5–13%,输出也会有少量舍入。

收益与前缀在序列中所占的比例成正比。M5 Pro 上 1024² 编辑,单参考图每步从 17.97 秒降至 9.65–10.38 秒,双参考图从 33.32 秒降至 11.46 秒(2.91×);A40(ggml_cuda)上单参考图编辑从 2.547 秒降至 1.328 秒。文生图的前缀只有提示词,只快 1–3%;2048² 时目标 token 占主导,编辑的收益也更小。细节见 Qwen-Image-2.1 卡片,Vulkan 数据见英文版卡片。

多 GPU

在 ggml_cuda 或 ggml_vulkan 上,--tp N 按 Megatron 方式切分扩散 Transformer:每张卡持有 32/N 个完整注意力头与 12,288/N 个 MLP 列,每个块的两个行并行乘积在 GPU 之间求和,每张卡只缓存自己那些头的前缀。N 必须整除 32 个注意力头——单机上为 2、4、8 或 16——且切分每个权重时都不能拆开它的量化块,加载时会按权重类型逐一检查;实测只覆盖 2 卡。文本编码器、视觉编码器与 VAE 留在第一张卡上;不支持多节点组。在两张 A40 上,1024² 文生图每步快 1.34×,1024² 单参考图编辑快 1.42×,2048² 快 1.54–1.57×;ggml_vulkan 经主机内存归约,为 0.86×——比单卡还慢。部分和的相加顺序不同,因此输出与单卡不逐位相同:构图与质量一致,细节可能不同。每张卡的内存与数值检查见卡片。

LoRA 插件

CLI 与服务端都可以用 --lora 给扩散 Transformer 加上一个 LoRA:一种风格、一项编辑能力,或者把默认 40 步换成 4–8 次 Transformer 前向的步数蒸馏适配器。重复该参数可叠加插件;--lora-scale 设置前一个 --lora 的强度,--lora-config 指定它的伴随配置(TensorSharp LoRA 配置、PEFT adapter_config.json 或 VideoX-Fun pdd_config.json)。config/lora/ 中的十四个现成 Qwen-Image-2.1 插件(qwen-image-2.1-*.json)会在首次使用时下载并校验权重哈希,并带有适配器的强度与采样配方。该目录还有两个 MiniMax-H3 Turbo 插件,Qwen-Image-2.1 不接受它们。

# Viggle Turbo:插件配方给出 6 步、CFG 1(支持 4–8 步)
dotnet run --project TensorSharp.Cli -c Release --no-build -- \
  --config config/qwen-image-2.1.json \
  --lora config/lora/qwen-image-2.1-viggle-turbo.json \
  --prompt 'A small orange cat beside a blue ceramic vase, soft daylight, detailed photograph' \
  --width 1024 --height 1024 --diffusion-seed 42 --output turbo.png

# 服务端把启动时的这组插件应用到每个图像请求
dotnet run --project TensorSharp.Server.Host -c Release --no-build -- \
  --config config/qwen-image-2.1.json --lora config/lora/qwen-image-2.1-pruna-8step.json

参数说明与插件配置格式见仓库的 USAGE_zh-cn.md,打包与张量并行细节见 Qwen-Image-2.1 卡片。