本项目基于QAI_AppBuilder
https://github.com/qualcomm/qai-appbuilder
模型下载地址 (包含对应的上下文二进制文件)
https://www.aidevhome.com/?id=51
第一部分:Windows PC 平台使用
本部分介绍如何在搭载Snapdragon X Elite 的AI PC 上,通过 qai_appbuilder 的 全流程 in-process HTP 方案 运行 SD3.5 Medium 图像生成
1.1 压缩包内容
sd3.5_qnn_for_windows-8380/
├── sd3.5_medium_pc.py # PC 推理入口脚本
├── time_text_embed.pt # timestep 嵌入权重 (~32 MB)
├── requirements.txt # Python 依赖
├── README.md / README_PC.md
├── libs/ # QNN 运行时库(已包含,无需额外下载)
│ ├── QnnHtp.dll HTP 后端
│ ├── QnnHtpPrepare.dll HTP 预处理
│ ├── QnnHtpV73Stub.dll v73 DSP stub
│ ├── QnnHtpNetRunExtensions.dll 运行扩展
│ ├── QnnSystem.dll 系统库
│ ├── Genie.dll
│ └── ... 其他运行时文件
├── serialized_binaries/ # QNN 模型文件
│ ├── text_encoder.serialized.bin (~238 MB) CLIP-L 文本编码器
│ ├── text_encoder_2.serialized.bin (~1.4 GB) CLIP-G 文本编码器
│ ├── transformer.serialized.bin (~2.3 GB) MMDiT 去噪网络
│ └── vae_decoder.serialized.bin (~102 MB) VAE 解码器
├── tokenizer/ # CLIP-L tokenizer
│ ├── vocab.json
│ ├── merges.txt
│ ├── special_tokens_map.json
│ └── tokenizer_config.json
└── tokenizer_2/ # CLIP-G tokenizer
├── vocab.json
├── merges.txt
├── special_tokens_map.json
└── tokenizer_config.json
💡 路径自动适配: sd3.5_medium_pc.py 同时兼容两种目录结构:
扁平结构 (新版默认):serialized_binaries/、tokenizer/、libs/ 等直接位于脚本同级目录。
注意: 总大小约 4.6 GB (含模型权重文件和 QNN 运行时库)。
1.2 环境准备
**硬件:**Snapdragon X Elite(HTP v73)或更高
**内存:**建议 32GB RAM(transformer 模型约 2.3GB,加载到 HTP 上下文中)
**Python:**3.12 (x86_64 emulated on ARM64)
QNN Libs: 已包含在压缩包中,脚本会自动定位无需手动配置
1.3 资源下载与准备
下载模型文件:
将下载的压缩包解压到工作目录下。压缩包已包含所需的 QNN 运行时库(libs/ 目录),无需额外下载。
1.4 安装依赖
① 创建虚拟环境(推荐):
python -m venv venv
venv\Scripts\activate
② 安装 Python 依赖: 使用压缩包中的 requirements.txt:
pip install -i https://mirrors.aliyun.com/pypi/simple/ -r requirements.txt
requirements.txt 内容:
torch>=2.4.1
transformers>=4.44.0
diffusers==0.34.0
Pillow>=9.0.0
numpy>=1.24.0
qai_appbuilder==2.46.0.1
1.5 QNN Libs 说明
QNN运行时库已包含在压缩包的libs/目录中,脚本会自动检测使用,无需手动配置路径。脚本的查找顺序为:
优先尝试 <脚本目录>/models/libs(带 models/ 子目录的旧版结构)
未找到则使用 <脚本目录>/libs(扁平结构 / 新版默认)
libs/ 目录包含以下关键文件:
QnnHtp.dll --- HTP 后端库(推理核心)
QnnHtpPrepare.dll --- HTP 预处理
QnnHtpV73Stub.dll --- v73 DSP stub
QnnHtpNetRunExtensions.dll --- 运行时扩展
QnnSystem.dll --- 系统库
Genie.dll --- Genie 框架库
1.6 运行推理
基本用法:
python sd3.5_medium_pc.py --prompt "A cat holding a sign that says hello world"
完整参数示例:
python sd3.5_medium_pc.py ^
--prompt "A beautiful sunset over the ocean" ^
--negative_prompt "blurry, low quality" ^
--steps 20 ^
--cfg 3.5 ^
--seed 42 ^
参数说明:
| 参数 | 默认值 | 说明 |
|---|---|---|
| --prompt | "A cat..." | 正向提示词 |
| --negative_prompt | "" | 负向提示词 |
| --steps | 20 | 去噪步数(5 步快速测试,20 步高质量) |
| --cfg | 3.5 | CFG 引导强度 |
| --seed | 42 | 随机种子(相同种子 = 可复现结果) |
| --output | output.png | 输出图片路径 |
1.7 推理流程如下:
1. [CPU] 加载 tokenizer + time_text_embed 权重 + scheduler
2. [一次性] 通过 qai_appbuilder 加载 4 个 QNN 模型到 HTP 上下文
(text_encoder / text_encoder_2 / vae_decoder / transformer)
3. [NPU] CLIP-L + CLIP-G 文本编码(正向 + 负向 prompt)
4. [CPU] 初始化随机 latent 噪声
5. [循环 N 步去噪]:
a. [CPU] 计算时间步嵌入 (temb)
b. [NPU] transformer 条件推理 → 噪声预测
c. [NPU] transformer 无条件推理 → 噪声预测
d. [CPU] CFG 合并 + 调度器更新 latent
6. [NPU] VAE 解码 → 像素图像
7. [CPU] 后处理 → 保存 PNG (1024×1024)
第二部分:Android 平台使用
本部分介绍如何通过 Host PC + Android 设备 协作完成 SD3.5 Medium 图像生成:
- Host PC(Linux/Windows):负责 tokenizer 编解码、调度器计算、前后处理
- Android 设备 NPU :通过 ADB 调用
qnn-net-run``简单推理,执行 4 个 QNN 模型推理
支持两个平台版本:
| 版本 | DSP 架构 | SOC ID | 芯片平台 |
|---|---|---|---|
| GEN4 | V79 | 69 | Snapdragon (Sun) |
| GEN5 | V81 | 87 | Snapdragon 8 Elite |
2.1 压缩包内容
++SD3.5 Medium 骁龙 8 至尊版平台 (8750) 模型下载++
++SD3.5 Medium 第五代骁龙 8 至尊版平台 (8850) 模型下载++
sd3.5/
├── sd3.5_medium_inference_android.py # 推理入口脚本
├── qnn-net-run # QNN CLI 推理工具 (aarch64-android)
├── time_text_embed.pt # 时间嵌入权重 (~32MB)
├── htp_config.json # HTP 配置参考
├── htp_backend.json # HTP 后端配置参考
├── libs/ # QNN 运行时库 (~300MB, 约71个 .so)
│ ├── libQnnHtp.so
│ ├── libQnnHtpV79Stub.so # GEN4: V79 / GEN5: V81
│ ├── libQnnHtpV79CalculatorStub.so
│ ├── libQnnHtpV79Skel.so
│ ├── libQnnSystem.so
│ └── ... (其他 QNN .so 库)
├── serialized_binaries/ # GEN4 用 "serialized_binaries/"
│ │ # GEN5 用 "serialized_binaries_gen5/"
│ ├── text_encoder.serialized.bin ~238MB
│ ├── text_encoder_2.serialized.bin ~1.4GB
│ ├── transformer.serialized.bin ~2.3GB
│ └── vae_decoder.serialized.bin ~105MB
├── tokenizer/ # CLIP tokenizer 文件
└── tokenizer_2/ # CLIP tokenizer_2 文件
注意: 总大小约 4.3GB(主要是模型权重文件)。
2.2 环境准备
安装 ADB:
# Ubuntu / Debian
sudo apt install android-tools-adb
# 验证安装
adb version
创建 Python 虚拟环境并安装依赖:
# 创建虚拟环境
python3 -m venv sd35_env
source sd35_env/bin/activate # Linux / macOS
# sd35_env\Scripts\activate # Windows
# 安装依赖
pip install -i https://mirrors.aliyun.com/pypi/simple/ torch transformers diffusers Pillow numpy
2.3 连接设备
# 连接设备后验证
adb devices
# 输出示例:
# List of devices attached
# 24e74add device ← 设备已连接
# 多设备场景:指定目标设备
export ANDROID_SERIAL=24e74add
确保设备状态显示为 device(不是 unauthorized 或 offline)。
2.4 首次运行(含设备初始化)
首次运行需要加 --setup 参数,脚本会自动将库和模型推送到设备 /data/local/tmp/sd35/。
# 激活虚拟环境
source sd35_env/bin/activate
# 进入工作目录
cd sd3.5_qnn_for_android_gen4/sd3.5/ # GEN4
# cd sd3.5_qnn_for_android_gen5/sd3.5/ # GEN5
# 首次运行(推送文件 + 推理)
python sd3.5_medium_inference_android.py \
--setup \
--prompt "A cat holding a sign that says hello world"
⚠ 首次推送耗时: 约 5-10 分钟(需推送约 4GB 文件到设备)。推送完成后,脚本会自动开始推理流程。
2.5 日常使用(后续推理)
首次设置完成后,无需再加 --setup:
# 基本用法
python sd3.5_medium_inference_android.py --prompt "A beautiful sunset over the ocean"
# 指定步数和种子
python sd3.5_medium_inference_android.py \
--prompt "A futuristic city at night" \
--steps 30 \
--seed 123 \
--output future_city.png
# 使用负向提示词
python sd3.5_medium_inference_android.py \
--prompt "Portrait of a woman, oil painting style" \
--negative_prompt "blurry, low quality, distorted" \
--guidance_scale 5.0
# 强制重新推送文件到设备
python sd3.5_medium_inference_android.py \
--force_setup \
--prompt "测试提示词"
完整参数列表:
| 参数 | 默认值 | 说明 |
|---|---|---|
| --prompt | "A cat..." | 正向提示词 |
| --negative_prompt | "" | 负向提示词 |
| --steps | 20 | 去噪步数 |
| --guidance_scale | 3.5 | CFG 引导强度 |
| --seed | 42 | 随机种子 |
| --output | "output.png" | 输出图片路径 |
| --setup | False | 首次运行,推送文件到设备 |
| --force_setup | False | 强制重新推送所有文件 |
| --model_dir | "." | tokenizer 所在目录 |
| --bins_dir | "serialized_binaries" | 模型 bin 文件目录 |
| --device_base | "/data/local/tmp/sd35" | 设备端工作目录 |
2.6 集成Apk说明
整体的编译后端库流程请查看项目代码qai-appbuilder/samples/android/
模型调用推理
ava_com_example_DDColor_MainActivity_DDColor(...) {
float* inputBuffer = (float*)env->GetDirectBufferAddress(j_inputBuffer);
float* outputBuffer = (float*)env->GetDirectBufferAddress(j_outputBuffer);
// 1. 指定后端 (例如:libQnnHtp.so 表示在DSP上运行)
std::string backend_lib_path = libs_dir + "/libQnnHtp.so";
std::string system_lib_path = libs_dir + "/libQnnSystem.so";
// 2. 初始化模型
libAppBuilder.ModelInitialize(MODEL_NAME, model_path, backend_lib_path, ...);
// 3. 执行推理
libAppBuilder.ModelInference(MODEL_NAME, ...);
// 4. 拷贝结果
memcpy(outputBuffer, outputBuffers.at(0), outputSize[0]);
// ... 释放资源 ...
return 0;