MNN 扩散模型(Diffusion)文生图推理指南:从 Stable Diffusion 模型转换到端侧部署
MNN 扩散模型Diffusion文生图推理指南从 Stable Diffusion 模型转换到端侧部署【免费下载链接】MNNMNN: A blazing-fast, lightweight inference engine battle-tested by Alibaba, powering high-performance on-device LLMs and Edge AI.项目地址: https://gitcode.com/GitHub_Trending/mn/MNN导读本文围绕 MNN 仓库中 docs/transformers/diffusion.md 的技术内容展开系统讲解如何在 MNN 推理引擎上落地 Stable Diffusion 系列文生图text-to-image模型包括模型选型与下载、HuggingFace 模型到 ONNX 再到 MNN 的两段式转换、Demo 编译、运行参数调优与 FAQ 排障。读者完成后将掌握一条完整的端侧文生图流水线从权重导出到量化压缩再到 OpenCL / Metal 后端加速推理并能理解 MNN Diffusion 引擎内部 text encoder、UNet、VAE decoder 三个子模型的协作关系。一、模型支持与下载MNN Diffusion 引擎在transformers/diffusion目录下提供了基于 ONNX→MNN 转换的端侧文生图能力当前官方文档明确支持以下三类 Stable Diffusion 系权重模型说明获取地址原文stable-diffusion-v1-5通用英文文生图模型社区生态最成熟HuggingFacestable-diffusion-v1-5/stable-diffusion-v1-5chilloutmix基于 SD1.5 的微调模型ModelScopewyj123456/chilloutmixIDEA-CCNL/Taiyi-Stable-Diffusion-1B-Chinese-v0.1太乙中文版 SD适合中文 promptHuggingFaceIDEA-CCNL/Taiyi-Stable-Diffusion-1B-Chinese-v0.1从源码看engine/include/diffusion/diffusion.hpp 中的DiffusionModelType枚举对模型类型做了统一抽象typedef enum { STABLE_DIFFUSION_1_5 0, // stable-diffusion-v1-5 / chilloutmix STABLE_DIFFUSION_TAIYI_CHINESE 1, // 太乙中文版 SANA_DIFFUSION 2, // Sana仓库已扩展支持 WAN2_1_T2V 3, // Wan2.1 文生视频仓库已扩展支持 DIFFUSION_MODEL_USER } DiffusionModelType;也就是说Demo 命令行中的model_type参数0与1正是上述枚举的前两项而仓库在文档之外还进一步扩展了 SanaDiT 架构文生图与 Wan2.1文生视频支持详见 transformers/diffusion/README.md。二、模型转换HuggingFace → ONNX → MNNMNN 无法直接消费 PyTorch 权重转换链路分两步先用 PyTorch 生态把权重导出为 ONNX再用 MNNConvert 把 ONNX 转成 MNN 模型。转换脚本集中在 transformers/diffusion/export。2.1 环境准备conda官方转换脚本依赖torch、onnx、diffusers等库仓库在 transformers/diffusion/env.yaml 中提供了现成的 conda 环境定义name: ldm channels: - pytorch - defaults dependencies: - pytorch - numpy - diffusers - onnx - transformers - sentencepiece - pip: - optimum[exporters] - onnxruntime-gpu创建并激活环境conda env create -f env.yaml conda activate ldm2.2 第一步HuggingFace Stable Diffusion → ONNX进入导出目录并执行官方脚本cd mnn_path/transformers/diffusion/export python onnx_export.py \ --model_path hf_sd_load_path \ --output_path onnx_save_path \ --opset 18关键参数说明--model_path本地 diffusers checkpoint 目录或 HuggingFace Hub 上的模型路径--output_pathONNX 输出目录脚本会在其下生成text_encoder/、unet/、vae_encoder/、vae_decoder/四个子目录及tokenizer/--opsetONNX 算子集版本文档示例使用 18脚本默认值为 14--fp16可选开关将权重以 fp16 导出注意脚本要求 fp16 导出需 CUDA 环境。阅读 export/onnx_export.py 可以看到每个子模型导出时的输入输出契约这些形状信息决定了后续 MNN 端推理时的张量布局子模型输入输出备注text_encoderinput_ids(int32)last_hidden_state,pooler_output固定model_max_lengthCLIP 为 77 tokenunetsample,timestep,encoder_hidden_statesout_sample权重超 2GB使用外部数据格式拆分vae_encodersample,return_dictlatent_sampleimg2img 等场景需要vae_decoderlatent_samplesample将 latent 解码为像素图其中 UNet 导出时使用了save_as_external_dataTrue并把外部权重合并为单个weights.pb见脚本中onnx.save_model(..., all_tensors_to_one_fileTrue, locationweights.pb)这与后续 MNN 转换时的--saveExternalData1参数一一对应。2.3 第二步ONNX → MNN新建 diffusion 的 MNN 模型文件夹mnn_save_path将转好的 MNN 文件放入其中然后执行python3 convert_mnn.py ../onnx ~/alicnn/AliNNPrivate/build/diffusion --weightQuantBits8若希望在 OpenCL / Metal 后端进一步加速可追加--transformerFuse# 适用 OpenCL / Metal 后端推理 python3 convert_mnn.py onnx_path mnn_save_path --weightQuantBits8 --transformerFuse从源码看export/convert_mnn.py 的核心逻辑是依次对text_encoder、unet、vae_decoder三个模型调用 MNNConvert-f ONNX --modelFile onnx/model/model.onnx --MNNModel mnn/model.mnn --saveExternalData1其中--weightQuantBits8和--transformerFuse均通过命令行第三个参数透传给 MNNConvert转换完成后脚本会调用export_diffusion_mtok借助 transformers/llm/export 下的 tokenizer 工具链把 HuggingFace tokenizer 统一导出为 MNN 端的tokenizer.mtok文件并自动复制到 mnn 目录下。因此最终mnn_save_path目录的标准结构为mnn_save_path/ ├── text_encoder.mnn # CLIP 文本编码器 ├── unet.mnn # UNet 去噪模型 ├── vae_decoder.mnn # VAE 解码器 └── tokenizer.mtok # 统一格式的 tokenizer关于参数的两个重要事实--weightQuantBits8对权重做 8bit 量化显著降低模型体积与内存占用是端侧部署的关键手段--transformerFuse开启 transformer 算子融合插件只有 OpenCL / Metal 后端支持CPU 等其他后端会在运行时报错详见本文 FAQ。三、编译 Diffusion Demo3.1 Linux / macOS / Windowscd mnn_path mkdir build cd build cmake .. -DMNN_LOW_MEMORYON -DMNN_BUILD_DIFFUSIONON -DMNN_BUILD_OPENCVON -DMNN_IMGCODECSON -DMNN_OPENCLON -DMNN_SEP_BUILDOFF -DMNN_SUPPORT_TRANSFORMER_FUSEON make -j32各 CMake 开关的作用开关作用MNN_LOW_MEMORYON低内存模式减少模型驻留内存MNN_BUILD_DIFFUSIONON编译 diffusion 引擎与diffusion_demo可执行文件MNN_BUILD_OPENCVON编译 MNN 内置 OpenCV 图像处理模块图像读写与预处理依赖MNN_IMGCODECSON启用图片编解码支持MNN_OPENCLON启用 OpenCL 后端GPU 加速Android/Linux 常用MNN_SEP_BUILDOFF关闭独立模块编译将所有模块编入同一目标MNN_SUPPORT_TRANSFORMER_FUSEON编译 transformer 融合算子插件配合--transformerFuse使用补充说明运行 diffusion demo 需要 tokenizer而 tokenizer 已统一为 mtok-only因此编译时必须开启-DMNN_BUILD_LLMON参见 transformers/diffusion/README.md。从 engine/CMakeLists.txt 可以看到开启MNN_BUILD_LLM后会给 diffusion 目标追加MNN_DIFFUSION_WITH_LLM_TOKENIZER编译宏并同时生成sana_diffusion_demo、wan_diffusion_demo等扩展 demo。3.2 Androidcd mnn_path/project/android/build ../build_64.sh -DMNN_LOW_MEMORYON -DMNN_BUILD_DIFFUSIONON -DMNN_BUILD_OPENCVON -DMNN_IMGCODECSON -DMNN_OPENCLON -DMNN_SEP_BUILDOFF -DMNN_SUPPORT_TRANSFORMER_FUSEON ../updateTest.shAndroid 构建脚本位于 project/android/build_64.shupdateTest.sh负责把编译产物与测试资源同步到设备侧之后即可在 Android 设备OpenCL 后端上运行 demo。四、运行 Diffusion Demo4.1 命令格式与资源准备./diffusion_demo resource_path model_type memory_mode backend_type iteration_num random_seed output_image_name prompt_text其中resource_path即上一节生成的 mnn 模型文件夹路径包含text_encoder.mnn、unet.mnn、vae_decoder.mnn、tokenizer.mtok。注意三点diffusion tokenizer 已统一为 mtok-only编译时需要开启-DMNN_BUILD_LLMONconvert_mnn.py会把 HuggingFace tokenizer 导出为tokenizer.mtok运行时需要将tokenizer.mtok放到resource_path文件夹中。对应 demo 源码 engine/diffusion_demo.cpp 中主流程依次为Diffusion::createDiffusion(...)创建引擎、diffusion-load()加载模型、diffusion-run(...)执行采样并通过进度回调打印Progress: xx%。4.2 参数详解model_type模型类型目前支持两类 diffusion 模型0表示 stable-diffusion-v1-5 / chilloutmix1表示 Taiyi-Stable-Diffusion太乙中文版。对应源码中的STABLE_DIFFUSION_1_5与STABLE_DIFFUSION_TAIYI_CHINESE枚举。memory_mode内存模式取值模式行为0内存节约模式demo 中每个模型使用前才初始化用完即释放首次运行每个子模型有初始化等待1内存足够模式启动时全量初始化所有模型运行时无需等待初始化出图性能最好2内存 性能折中模式启动时初始化部分模型对应 engine/include/diffusion/diffusion.hpp 中的注释定义0 - memory saving mode1 - memory enough mode2 - balance mode。需要连续生成多张图时内存节约模式下每次run前需重新load()而内存足够模式只需首次加载源码中while(0)示例块即为多轮生成的注释示范。backend_type运行后端指定推理后端如 OpenCL / Metal / CPU 等。OpenCL 对应3Metal 对应6CPU 对应0可参考 transformers/diffusion/README.md 的参数表。Android 侧可用 OpenCLiOS 侧可用 Metal。iteration_num采样迭代次数文生图去噪迭代步数官方建议设置在 10 到 20 之间。步数越多细节越充分但耗时线性增长SD1.5 这类模型一般 20 步即可获得良好效果。random_seed随机种子固定输入噪声种子数设置为负数表示随机生成噪声种子。当随机种子生成的图片质量不佳时可以固定某个正整数种子复现/微调结果。output_image_name输出图片名生成图片的名字默认保存到当前运行目录下。prompt_text提示词文生图 prompt。stable-diffusion-v1-5 / chilloutmix 建议使用英文 promptTaiyi-Stable-Diffusion 建议使用中文 prompt。从 engine/diffusion_demo.cpp 可见demo 会把第 9 个参数之后的所有参数拼接为完整 prompt支持带空格的多词提示。4.3 运行命令示例./diffusion_demo mnn_sd1.5_path 0 1 3 20 -1 demo.jpg a cute cat ./diffusion_demo mnn_chilloutmix_path 0 0 3 10 42 demo.jpg a pure girl ./diffusion_demo mnn_taiyi_path 1 0 3 10 -1 demo.jpg 一只可爱的猫三个示例分别对应SD1.5 全内存模式 20 步随机种子、chilloutmix 省内存模式 10 步固定种子、太乙中文版省内存模式 10 步随机种子。五、引擎内部原理三子模型流水线结合 engine/include/diffusion/stable_diffusion.hpp 与 engine/include/diffusion/diffusion.hppSD 推理由三个 MNNModule协同完成与转换阶段的三个 ONNX 子模型一一对应text_encoderCLIP 文本编码器将 prompt 分词mMaxTextLen 77即 CLIP 的最大 token 长度后编码为文本 embeddingunet去噪网络以文本 embedding 为条件在 latent 空间迭代去噪。StableDiffusion类中step_plms、forwardWithResizeCache、mTimeSteps、mAlphas、mEts等成员实现了 PLMS 采样器的时间步调度与去噪递推vae_decoderVAE 解码器把去噪后的 latent 解码为最终像素图像。工厂方法Diffusion::createDiffusion依据DiffusionModelType分发到StableDiffusion/SanaDiffusion/WanDiffusion具体实现见 engine/src/diffusion.cpp上层diffusion_demo无需关心模型差异。统一生成接口还支持text2img从随机噪声开始与img2img从输入图像 latent 开始两种模式以及use_cfgClassifier-Free Guidance需 batch2 的正负样本 embedding与cfg_scale典型值 4.5–7.5等高级参数见 diffusion.hpp 的参数注释。六、FAQ常见问题排查1. Demo 运行报错、段错误怎么解决最常见的原因是设备内存不足。经验值如下支持 OpenCL fp16 的设备需要保证 2GB 以上内存不支持 fp16 的设备则需要 4GB 以上显存。内存不足时建议优先使用memory_mode0省内存模式按需加载释放子模型并配合转换阶段的--weightQuantBits8量化压缩权重体积。2. 使用其他后端出现报错什么原因目前其他后端暂不支持 transformer 插件算子。若切换后端后报错需要在 onnx→mnn 转换阶段去掉--transformerFuse重新转换模型。即--transformerFuse是 OpenCL / Metal 专属的加速选项CPU 等后端必须关闭。结语MNN 的 Diffusion 支持为端侧文生图提供了一条从权重导出、模型量化、后端加速到 Demo 验证的完整工程链路HuggingFace → ONNXonnx_export.py→ MNNconvert_mnn.py→ diffusion_demo。结合--weightQuantBits8量化、memory_mode内存策略与 OpenCL / Metal 的--transformerFuse融合优化开发者可以把 Stable Diffusion 1.5、chilloutmix 乃至太乙中文版等模型部署到移动端与边缘设备上仓库还在此基础上扩展了 Sana 与 Wan2.1 等新架构入口均位于 transformers/diffusion。【免费下载链接】MNNMNN: A blazing-fast, lightweight inference engine battle-tested by Alibaba, powering high-performance on-device LLMs and Edge AI.项目地址: https://gitcode.com/GitHub_Trending/mn/MNN创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考