- 人工智能
- 大模型
- 本地部署
- 推理引擎
- 媒体生成
【免费下载链接】stable-diffusion.cpp
Diffusion model(SD,Flux,Wan,Qwen Image,Z-Image,...) inference in pure C/C++
本篇技术指南聚焦 stable-diffusion.cpp 对MiniT2I(一种 Diffusion Transformer 架构的文生图模型)的完整支持链路:从权重下载、命令行推理参数,到源码中 MiniT2IConfig 自动检测、MMJiT 主干结构与 flan-t5-large 文本编码的实现细节。读完本文,你将掌握如何在本项目的 examples/cli 命令行工具中运行 MiniT2I,并能从源码层面理解其"双流 Transformer + flow matching"的推理机制。
MiniT2I 在 stable-diffusion.cpp 中的定位
MiniT2I 是 stable-diffusion.cpp 支持的众多纯 C/C++ 推理模型之一,官方用法文档 docs/minit2i.md 明确指出:
MiniT2I uses a MiniT2I diffusion transformer and
google/flan-t5-largeas the text encoder.
即整个生成管线由两个核心部分组成:
- 扩散主干(Diffusion Transformer):MiniT2I 官方发布的
minit2i-b-16检查点,负责图像 token 的逐步去噪; - 文本编码器(Text Encoder):
google/flan-t5-large,负责把自然语言提示词编码为条件向量,指导扩散过程。
从源码结构看,MiniT2I 被归入 DiT(Diffusion Transformer)模型家族。src/model.h 中的sd_version_is_minit2i()判断函数以及sd_version_is_dit()列表(src/model.h)均将VERSION_MINIT2I纳入 DiT 体系;在 src/stable-diffusion.cpp 的预测类型表中,MiniT2I 对应名为minit2i_flow的 flow matching 预测模式,与 SD3/Flux 的 flow 模式并列,说明其训练目标属于"流匹配(flow matching)"而非传统的 epsilon 预测。
权重下载:两个文件,缺一不可
按照 docs/minit2i.md 的"Download weights"一节,需要准备两部分权重:
| 组件 | 来源 | 需要的文件 |
|---|---|---|
| MiniT2I 扩散模型 | MiniT2I/MiniT2I仓库的minit2i-b-16/transformer目录 | diffusion_pytorch_model.safetensors |
| flan-t5-large 文本编码器 | google/flan-t5-large仓库 | model.safetensors |
下载后建议按如下目录组织,与下文命令行示例保持一致:
models/ ├── minit2i/ │ └── diffusion_pytorch_model.safetensors └── flan-t5-large/ └── model.safetensors需要特别说明的是:当前文档中的命令行示例直接以safetensors原始权重作为输入。stable-diffusion.cpp 的模型加载系统(src/model_loader.cpp、src/model_io/safetensors_io.cpp)支持直接读取这类权重;若你希望转成 GGUF 使用,可参考 docs/quantization_and_gguf.md 了解量化与格式转换流程,但 MiniT2I 直接加载 safetensors 即可运行。
另外,文本编码器是必需的。在 src/conditioning/conditioner.hpp 的MiniT2IConditioner构造函数中,源码会扫描权重中是否存在text_encoders.t5xxl前缀的张量;若找不到 T5 编码器,会打印"IMPORTANT NOTICE: No MiniT2I T5 text encoder provided, cannot process prompts!"并退化为零向量条件——此时生成的图片将完全失去语义控制。因此请务必同时下载 flan-t5-large。
命令行推理:Metal 与 CUDA 两套实战命令
Mac Metal 后端
原文档给出的 Metal 示例(适用于 Apple Silicon Mac):
./bin/sd-cli \ --backend metal \ --diffusion-model ../models/minit2i/diffusion_pytorch_model.safetensors \ --t5xxl ../models/flan-t5-large/model.safetensors \ --prompt "a cat" \ --steps 100 \ --cfg-scale 6 \ --width 512 \ --height 512 \ --seed 42 \ --sampling-method euler \ --rng cpu \ --output minit2i_metal.png \ --threads 8CUDA 后端 + 扩散闪存注意力
原文档给出的 CUDA 示例(NVIDIA GPU,开启--diffusion-fa以启用 diffusion flash attention):
./bin/sd-cli \ --diffusion-model ../models/minit2i/diffusion_pytorch_model.safetensors \ --t5xxl ../models/flan-t5-large/model.safetensors \ --prompt "a cat" \ --steps 100 \ --cfg-scale 6 \ --width 512 \ --height 512 \ --seed 42 \ --sampling-method euler \ --diffusion-fa \ --output minit2i_cuda.png命令中涉及的参数含义如下:
| 参数 | 作用 | 说明 |
|---|---|---|
--backend metal | 选择 Metal 后端 | 仅 macOS 可用;CUDA 示例不写该参数时默认使用 CUDA 后端 |
--diffusion-model | 指定 MiniT2I 扩散模型权重 | 指向diffusion_pytorch_model.safetensors |
--t5xxl | 指定 T5 文本编码器权重 | 指向 flan-t5-large 的model.safetensors,对应源码中的MiniT2IConditioner |
--prompt | 生成提示词 | 示例为"a cat" |
--steps | 采样步数 | 示例为 100,对应MiniT2IConfig::n_T = 100的训练默认步数 |
--cfg-scale | Classifier-Free Guidance 强度 | 示例为 6;CFG 区间由cfg_interval_start/cfg_interval_end(默认 0.0~1.0)控制 |
--width/--height | 输出图像尺寸 | 示例为 512×512,与MiniT2IConfig::image_size = 512一致 |
--seed | 随机种子 | 示例为 42,保证可复现 |
--sampling-method euler | 采样器 | 示例使用 Euler |
--rng cpu | 随机数发生器 | Metal 示例指定为 CPU 端 RNG |
--diffusion-fa | 开启 diffusion 阶段的 flash attention | CUDA 示例用于加速注意力计算 |
--output | 输出图片路径 | 示例分别为minit2i_metal.png/minit2i_cuda.png |
--threads 8 | CPU 线程数 | Metal 示例设置为 8 |
--t5xxl参数名虽然带着 "xxl" 字样,但在 MiniT2I 场景中它实际加载的是 flan-t5-large 权重——源码MiniT2IConditioner内部使用T5Runner并以text_encoders.t5xxl.transformer为前缀加载张量(src/conditioning/conditioner.hpp),说明该参数是项目中面向 T5 家族文本编码器的通用入口,不限定模型尺寸。
源码级原理:从配置自动检测到 MMJiT 主干
配置自动检测:无需手动指定超参
stable-diffusion.cpp 为 MiniT2I 实现了从权重自动推断模型配置的能力。src/model/diffusion/minit2i.hpp 中的MiniT2IConfig::detect_from_weights()会扫描权重张量名来还原网络结构:
- 由
img_embedder.proj1.weight/proj2.weight推断patch_size、in_channels、pca_channels、hidden_size; - 由
txt_embedder.weight推断txt_input_size(1024)与txt_hidden_size(768); - 由
double_blocks.N.img_qkv.weight推断num_heads(768 维时 12 头、1248 维时 24 头)与head_dim(64 或 52); - 通过遍历
double_blocks./txt_preamble_blocks.编号统计depth_double(默认 17)与txt_preamble_depth(默认 2)的层数。
该结构体的默认值完整对应minit2i-b-16检查点:image_size=512、patch_size=16、in_channels=3、txt_input_size=1024、hidden_size=768、txt_hidden_size=768、cond_vec_size=768、depth_double=17、txt_preamble_depth=2、num_heads=12、head_dim=64、mlp_ratio≈2.6667、pca_channels=128、prompt_length=256、n_T=100(src/model/diffusion/minit2i.hpp)。从这些默认值可以确认:MiniT2I 是一个 patch 化(16×16)的 DiT,文本侧与图像侧共享 768 维隐藏空间,属于中小规模的轻量文生图模型。
MMJiT 主干:双流 Transformer + 联合注意力
模型主干类名为MMJiT(src/model/diffusion/minit2i.hpp),其结构自上而下包括:
BottleneckPatchEmbed图像嵌入器:先用patch_size步长的卷积把图像切成 patch 并降维到pca_channels=128,再用 1×1 卷积投影到hidden_size(src/model/diffusion/minit2i.hpp);txt_embedder文本嵌入器:将 T5 输出(1024 维)线性投影到 768 维;t_embedder/pooled_embedder时间步与全局条件:TimestepEmbedder用正弦时间步嵌入 + SiLU MLP 生成条件向量(src/model/diffusion/minit2i.hpp);txt_preamble_blocks(2 层纯文本 Transformer):在图文融合前对文本 token 进行预编码,内部采用 RMSNorm + Q/K 归一化 + RoPE 的注意力结构(PlainTextTransformerBlock,src/model/diffusion/minit2i.hpp);double_blocks(17 层双流 DiT 块):图像流与文本流分别过 QKV 投影后,将 Q/K/V 拼接成联合序列执行联合注意力(joint attention),再把输出切回两流分别过残差 + SwiGLU MLP(DoubleStreamDiTBlock,src/model/diffusion/minit2i.hpp)。这种"双流输入、联合注意力、输出分流"的设计与 SD3/Flux 等 MMDiT 思路同源;FinalLayer+DiT::unpatchify:将最后的联合表示切片出图像部分,线性投影后重新拼回像素空间(src/model/diffusion/minit2i.hpp)。
值得注意的是,MMJiT::forward中每个 preamble 块和 double 块都调用了sd::ggml_graph_cut::mark_graph_cut做图切分标记(src/model/diffusion/minit2i.hpp),这意味着 MiniT2I 的深层网络可以借助 layer split 机制在多层设备/多后端间切分执行,属于项目图优化能力的直接受益者。
三种位置编码与缓存机制
MiniT2I 在推理时需要三种位置编码(src/model/diffusion/minit2i.hpp):
pos_embed:图像侧 2D sincos 位置嵌入,按网格坐标生成(make_2d_sincos_pos_embed);txt_pe:文本侧 RoPE 编码(make_text_rope);joint_pe:联合注意力用,由文本 RoPE 与图像 2D 轴频率 RoPE(make_vision_rope)拼接而成。
MiniT2IRunner::ensure_position_cache()以img_side × txt_len为 key 缓存这组嵌入:只要图像尺寸与文本长度不变化,位置编码只计算一次并常驻显存/内存(标记为GGML_BACKEND_BUFFER_USAGE_WEIGHTS),显著减少重复计算。
条件编码与掩码机制
文本条件由 src/conditioning/conditioner.hpp 的MiniT2IConditioner负责:
- 使用
T5UniGramTokenizer对提示词分词,再交给前缀为text_encoders.t5xxl.transformer的T5Runner前向计算得到 1024 维 hidden states; - 所有序列统一 pad 到
prompt_length = 256:真实 token 的掩码为 1.0,padding 位置为 0.0(src/conditioning/conditioner.hpp); - 掩码同时作为
c_vector传入扩散模型:在MMJiT::apply_text_mask()中,padding 位置会被替换为可学习的mask_token(src/model/diffusion/minit2i.hpp),并在 T5 侧将 padding 位置的注意力分数置为-HUGE_VALF,确保编码器只关注真实文本。
构建与调度
在 src/pipeline/model_builders.cpp 中,MiniT2I 版本被组装为MiniT2IConditioner(文本编码)与MiniT2IRunner(扩散主干,权重前缀model.diffusion_model.model.net)的组合;MiniT2IRunner::build_graph以MINIT2I_GRAPH_SIZE = 196608的图容量构建前向计算图(src/model/diffusion/minit2i.hpp)。去噪循环使用minit2i_flow预测模式,配合--sampling-method euler等采样器完成从随机噪声到图像的生成。
快速上手建议
- 按上文目录下载两个 safetensors 权重文件;
- 从源码构建
sd-cli(构建方式参考 examples/cli/README.md 与根目录 README.md); - 在 Apple Silicon Mac 上使用 Metal 示例,在 NVIDIA GPU 上使用 CUDA 示例(可加
--diffusion-fa加速); - 验证输出
minit2i_metal.png/minit2i_cuda.png是否与提示词语义一致——若图像完全随机,优先检查--t5xxl权重是否正确加载。
深入阅读
- 官方用法文档:docs/minit2i.md
- 扩散主干实现:src/model/diffusion/minit2i.hpp
- 文本编码器实现:src/conditioning/conditioner.hpp
- 模型装配逻辑:src/pipeline/model_builders.cpp
- 模型版本与预测模式定义:src/model.h、src/stable-diffusion.cpp
- 命令行工具:examples/cli/README.md
- 相关后端与加速说明:docs/backend.md、docs/sd3.md(同属 flow matching DiT 家族)
- 人工智能
- 大模型
- 本地部署
- 推理引擎
- 媒体生成
【免费下载链接】stable-diffusion.cpp
Diffusion model(SD,Flux,Wan,Qwen Image,Z-Image,...) inference in pure C/C++
相关推荐
在 stable-diffusion.cpp 中部署 Stable Diffusion 3.5 Large:权重下载、CLI 推理与 MMDiT 架构解析
在 stable diffusion.cpp 中部署 Stable Diffusion 3.5 Large:权重下载、CLI 推理与 MMDiT 架构解析 st
人工智能大模型本地部署推理引擎媒体生成stable-diffusion.cpp 运行 ERNIE-Image:Turbo/标准版权重获取、CLI 推理参数与 4GB 显存实战指南
stable diffusion.cpp 运行 ERNIE Image:Turbo/标准版权重获取、CLI 推理参数与 4GB 显存实战指南 本篇技术指南聚焦于
人工智能大模型本地部署推理引擎媒体生成computer 项目性能基准解读:computerd FUSE 挂载在元数据密集与大规模 I/O 场景下的实测数据
computer 项目性能基准解读:computerd FUSE 挂载在元数据密集与大规模 I/O 场景下的实测数据 导读 本篇文章围绕 docs/19_per
人工智能大模型本地部署推理引擎媒体生成
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考