高通 AI Stack 稳定扩散Demo指南(3)

150 篇文章 7 订阅
50 篇文章 0 订阅

高通 AI Stack 稳定扩散Demo指南(3)


1.2.2 Linux 上的 Qualcomm AI Engine 直接模型准备

Qualcomm AI Engine Direct SDK 允许客户在 HTP 硬件上运行机器学习模型。以下步骤描述了如何在具有 HTP 功能的 Linux 平台上准备和执行稳定扩散模型。

本文档交替使用术语 Qualcomm 神经网络 (QNN) 和 Qualcomm AI Engine Direct SDK。

先决条件

  1. Qualcomm AI Engine Direct SDK(支持 Ubuntu Linux)
  2. Ubuntu 20.04 安装以及 QNN 工具所需的软件包
  3. Android 平台工具版本 31 或更高版本
  4. 该笔记本可以使用 Anaconda(使用提供的environment.yaml)或虚拟环境(venv)执行
  5. 稳定的扩散.onnx文件及其相应的 AIMET 编码(通过 AIMET 工作流程生成)

此工作流程假设您已按照 AIMET 稳定扩散工作流程生成了稳定扩散模型工件:

  • 稳定扩散文本编码器模型及其 AIMET 编码
  • 稳定扩散 U-Net 模型及其 AIMET 编码
  • 稳定扩散变分自动编码器 (VAE) 模型及其 AIMET 编码
  • fp32.npyfile - 保存为 Python pickle 的 numpy 对象数组,其中包含模型转换步骤所需的数据。

测试环境
Linux x86 电脑

  • 发行商 ID:Ubuntu
  • 说明:Ubuntu 20.04.5 LTS
  • 发布时间:20.04
  • 平台:x86_64 AMD

工作流程
这三个模型和编码通过 Qualcomm AI Engine Direct SDK 中提供的不同可执行 QNN 实用程序独立处理。

要准备用于推理的稳定扩散模型,QNN 可执行实用程序需要 Ubuntu 20.04 环境

  • 将文件转换.onnx为等效的 QNN 表示形式A16W8(16 位激活和 8 位权重)
  • 生成 QNN 模型库
  • 为 QNN HTP 后端生成 QNN 上下文二进制文件

准备好用于推理的稳定扩散模型后,下一步是在 Snapdragon Android 设备上执行 QNN 上下文二进制文件以进行推理。请参阅 qnn_model_execution_on_android.ipynb。

在这里插入图片描述
可以使用 Anaconda 或 Python 虚拟环境 (venv) 设置 Python 环境。

注意:在执行笔记本之前,必须执行以下两个设置 Python 环境的步骤之一。

如果您已经启动了 jupyer 笔记本,请先配置 Python 环境,然后再继续。配置Python环境后,重新启动笔记本服务器并选择正确的内核。

设置
在 Ubuntu 20.04 终端中设置 Anaconda

  1. 从以下位置安装 Anaconda:https://repo.anaconda.com/archive/Anaconda3-2023.03-1-Linux-x86_64.sh。

  2. 使用以下命令执行安装脚本。

    chmod a+x Anaconda3-2023.03-1-Linux-x86_64.sh && bash Anaconda3-2023.03-1-Linux-x86_64.sh

  3. 在 Ubuntu 20.04 终端中使用以下命令配置 Anaconda 环境。

    conda create --name stable_diffusion_env python=3.8

    conda activate stable_diffusion_env

    conda install ipykernel

    ipython kernel install --user --name=stable_diffusion_env

在 Ubuntu 20.04 终端中设置 venv(非 Anaconda)
以下步骤安装在 Ubuntu 20.04 环境(Ubuntu 终端窗口)中使用 QNN 工具所需的软件包。

  1. 更新包索引文件。

    sudo apt-get update

  2. 安装Python3.8和必要的包。

    默认情况下,Ubuntu 20.04 应该附带 Python 3.8,您无需再次安装。但是要重新安装它,请运行以下命令。

    sudo bash -c ‘apt-get update && apt-get install software-properties-common && add-apt-repository ppa:deadsnakes/ppa && apt-get install python3.8 python3.8-distutils libpython3.8’

  3. 安装 python3-pip。

    sudo apt-get install python3-pip

  4. 安装python3虚拟环境支持。

    sudo apt install python3-virtualenv

  5. 通过执行以下命令创建并激活Python 3.8虚拟环境。

     virtualenv -p /usr/bin/python3.8 venv_stable_diffusion
     source venv_stable_diffusion/bin/activate
    

安装所需的Python包

pip install --quiet -r requirements.txt

设置 Qualcomm AI Engine Direct SDK

以下步骤配置 Qualcomm AI Engine Direct SDK,以便在设备上运行 Stable Diffusion。在 Ubuntu 20.04 终端上执行以下命令。

注意:这些步骤需要 sudo 或 root 权限。

  1. 在Ubuntu中设置Python和pip后,检查QNN工具依赖关系;看/docs/QNN/general/setup.html 了解有关 QNN 设置和 ML 框架依赖项的更多信息。
  2. 将QNN_SDK_ROOT环境变量设置为 Qualcomm AI Engine 目录的位置。对于Linux,export QNN_SDK_ROOT=“./assets/qnn_assets/unzipped_qnn_sdk_linux/”
  3. 检查并安装 Linux 依赖项。
 source $QNN_SDK_ROOT/bin/check-linux-dependency.sh
 sudo apt-get install -y libtinfo5

为 Qualcomm AI Engine 设置 Python 依赖项

import os
#Check and install Python dependencies
QNN_SDK_ROOT=os.getcwd() + "/assets/qnn_assets/unzipped_qnn_sdk_linux/"
!python $QNN_SDK_ROOT/bin/check-python-dependency

准备用于推理的稳定扩散模型
以下部分使用 Qualcomm AI Engine Direct SDK 为目标推理准备稳定的扩散模型。

# Set up environment variable to reference STABLE_DIFFUSION_MODELS
STABLE_DIFFUSION_MODELS = os.getcwd() + "/assets/stable_diffusion/"

将模型从 ONNX 表示转换为 QNN 表示

Qualcomm AI Engine Direct SDKqnn-onnx-conerter工具可将模型从 ONNX 表示精确转换为等效的 QNN 表示A16W8。从 AIMET 工作流程生成的编码文件通过选项提供作为此步骤的输入–quantization_overrides model.encodings。

此步骤生成一个.cpp文件,该文件将模型表示为一系列 QNN API 调用,以及一个.bin包含静态数据的文件,静态数据通常是模型权重并由.cpp文件引用。

对于所有三个模型,此步骤必须独立完成。

生成模型输入列表/数据

inputs_pickle_path=STABLE_DIFFUSION_MODELS + '/fp32.npy'
!python3 generate_inputs.py --pickle_path $inputs_pickle_path --working_dir $STABLE_DIFFUSION_MODELS

为 Qualcomm AI Direct SDK 工具设置环境变量

env = os.environ.copy()
env["QNN_SDK_ROOT"] = QNN_SDK_ROOT
env["PYTHONPATH"] = QNN_SDK_ROOT + "/benchmarks/QNN/:" + QNN_SDK_ROOT + "/lib/python"
env["PATH"] = QNN_SDK_ROOT + "/bin/x86_64-linux-clang:" + env["PATH"]
env["LD_LIBRARY_PATH"] = QNN_SDK_ROOT + "/lib/x86_64-linux-clang"
env["HEXAGON_TOOLS_DIR"] = QNN_SDK_ROOT + "/bin/x86_64-linux-clang"

转换文本编码器

mport subprocess

!mkdir $STABLE_DIFFUSION_MODELS/converted_text_encoder
proc = subprocess.Popen([QNN_SDK_ROOT + "/bin/x86_64-linux-clang/qnn-onnx-converter",
                  "-o", STABLE_DIFFUSION_MODELS + "/converted_text_encoder/qnn_model.cpp",
                   "-i",STABLE_DIFFUSION_MODELS + "/text_encoder_onnx/text_encoder.onnx",
                   "--input_list", STABLE_DIFFUSION_MODELS + "/text_encoder_onnx/text_encoder_input_list.txt",
                   "--act_bw", "16",
                   "--bias_bw", "32",
                   "--quantization_overrides", STABLE_DIFFUSION_MODELS + "/text_encoder_onnx/text_encoder.encodings"
                 ],stdout=subprocess.PIPE, stderr=subprocess.PIPE,env=env)
output, error = proc.communicate()
print(output.decode(),error.decode())

# Rename the model files to make them unique and helpful for subsequent stages
!mv $STABLE_DIFFUSION_MODELS/converted_text_encoder/qnn_model.cpp $STABLE_DIFFUSION_MODELS/converted_text_encoder/text_encoder.cpp
!mv $STABLE_DIFFUSION_MODELS/converted_text_encoder/qnn_model.bin $STABLE_DIFFUSION_MODELS/converted_text_encoder/text_encoder.bin
!mv $STABLE_DIFFUSION_MODELS/converted_text_encoder/qnn_model_net.json $STABLE_DIFFUSION_MODELS/converted_text_encoder/text_encoder_net.json

转换U-Net

预计执行时间:~ 1.5 小时

!mkdir $STABLE_DIFFUSION_MODELS/converted_unet

proc = subprocess.Popen([QNN_SDK_ROOT + "/bin/x86_64-linux-clang/qnn-onnx-converter",
                  "-o", STABLE_DIFFUSION_MODELS + "/converted_unet/qnn_model.cpp",
                   "-i",STABLE_DIFFUSION_MODELS + "/unet_onnx/unet.onnx",
                   "--input_list", STABLE_DIFFUSION_MODELS + "/unet_onnx/unet_input_list.txt",
                   "--act_bw", "16",
                   "--bias_bw", "32",
                   "--quantization_overrides", STABLE_DIFFUSION_MODELS + "/unet_onnx/unet.encodings",
                   "-l", "input_3", "NONTRIVIAL"
                 ],stdout=subprocess.PIPE, stderr=subprocess.PIPE,env=env)
output, error = proc.communicate()
print(output.decode(),error.decode())

# Rename the model files to make them unique and helpful for subsequent stages
!mv $STABLE_DIFFUSION_MODELS/converted_unet/qnn_model.cpp $STABLE_DIFFUSION_MODELS/converted_unet/unet.cpp
!mv $STABLE_DIFFUSION_MODELS/converted_unet/qnn_model.bin $STABLE_DIFFUSION_MODELS/converted_unet/unet.bin
!mv $STABLE_DIFFUSION_MODELS/converted_unet/qnn_model_net.json $STABLE_DIFFUSION_MODELS/converted_unet/unet_net.json

转换VAE解码器

预计执行时间:~25 分钟

!mkdir $STABLE_DIFFUSION_MODELS/converted_vae_decoder

proc = subprocess.Popen([QNN_SDK_ROOT + "/bin/x86_64-linux-clang/qnn-onnx-converter",
                  "-o", STABLE_DIFFUSION_MODELS + "/converted_vae_decoder/qnn_model.cpp",
                   "-i",STABLE_DIFFUSION_MODELS + "/vae_decoder_onnx/vae_decoder.onnx",
                   "--input_list", STABLE_DIFFUSION_MODELS + "/vae_decoder_onnx/vae_decoder_input_list.txt",
                   "--act_bw", "16",
                   "--bias_bw", "32",
                   "--quantization_overrides", STABLE_DIFFUSION_MODELS + "/vae_decoder_onnx/vae_decoder.encodings"
                 ],stdout=subprocess.PIPE, stderr=subprocess.PIPE,env=env)
output, error = proc.communicate()
print(output.decode(),error.decode())


# Rename for uniqueness
!mv $STABLE_DIFFUSION_MODELS/converted_vae_decoder/qnn_model.cpp $STABLE_DIFFUSION_MODELS/converted_vae_decoder/vae_decoder.cpp
!mv $STABLE_DIFFUSION_MODELS/converted_vae_decoder/qnn_model.bin $STABLE_DIFFUSION_MODELS/converted_vae_decoder/vae_decoder.bin
!mv $STABLE_DIFFUSION_MODELS/converted_vae_decoder/qnn_model_net.json $STABLE_DIFFUSION_MODELS/converted_vae_decoder/vae_decoder_net.json

QNN模型库

Qualcomm AI Engine Direct SDKqnn-model-lib-generator将模型.cpp和.bin文件编译为特定目标的共享对象库。此示例为 x86_64-linux 目标生成共享对象库。

此阶段的输入是上一步中生成的model.cpp和文件。model.bin

生成文本编码器模型库

proc = subprocess.Popen([QNN_SDK_ROOT + "/bin/x86_64-linux-clang/qnn-model-lib-generator",
                        "-c", STABLE_DIFFUSION_MODELS + "/converted_text_encoder/text_encoder.cpp",
                        "-b", STABLE_DIFFUSION_MODELS + "/converted_text_encoder/text_encoder.bin",
                        "-t", "x86_64-linux-clang",
                        "-o", STABLE_DIFFUSION_MODELS + "/converted_text_encoder"
                        ],stdout=subprocess.PIPE, stderr=subprocess.PIPE,env=env)
output, error = proc.communicate()
print(output.decode(),error.decode())

生成U-Net模型库

预计执行时间:~25 分钟

proc = subprocess.Popen([QNN_SDK_ROOT + "/bin/x86_64-linux-clang/qnn-model-lib-generator",
                        "-c", STABLE_DIFFUSION_MODELS + "/converted_unet/unet.cpp",
                        "-b", STABLE_DIFFUSION_MODELS + "/converted_unet/unet.bin",
                        "-t", "x86_64-linux-clang",
                        "-o", STABLE_DIFFUSION_MODELS + "/converted_unet"
                        ],stdout=subprocess.PIPE, stderr=subprocess.PIPE,env=env)
output, error = proc.communicate()
print(output.decode(),error.decode())

生成VAE解码器模型库

proc = subprocess.Popen([QNN_SDK_ROOT + "/bin/x86_64-linux-clang/qnn-model-lib-generator",
                        "-c", STABLE_DIFFUSION_MODELS + "/converted_vae_decoder/vae_decoder.cpp",
                        "-b", STABLE_DIFFUSION_MODELS + "/converted_vae_decoder/vae_decoder.bin",
                        "-t", "x86_64-linux-clang",
                        "-o", STABLE_DIFFUSION_MODELS + "/converted_vae_decoder"
                        ],stdout=subprocess.PIPE, stderr=subprocess.PIPE,env=env)
output, error = proc.communicate()
print(output.decode(),error.decode())

QNN HTP 上下文二进制文件

Qualcomm AI Engine Direct SDKqnn-context-binary-generator工具创建适用于 QNN HTP 后端的 QNN 上下文二进制文件。该二进制文件可以部署在运行 Android 的 Snapdragon Gen2 设备上运行。此步骤需要上一步中的模型共享对象库以及libQnnHtp.soQualcomm AI Engine Direct SDK 中提供的库。

通过传递为 QNN HTP 后端libQnnHtpBackendExtensions.so实现扩展的库,提供与 QNN HTP 后端相关的其他选项。该库可在 Qualcomm AI Engine Direct SDK 中找到。库和配置.json以如下所示的格式提供。有关后端扩展和配置参数的文档可在 Qualcomm AI Engine Direct SDK 文档中找到。

# HTP backend extensions config file (htp_backend_extensions.json) example
htp_backend_extensions_data = '''
{
    "backend_extensions": {
        "shared_library_path": "libQnnHtpNetRunExtensions.so",
        "config_file_path": "/tmp/htp_config.json"
    }
}
'''

# HTP backend config file (htp_config.json) example
htp_backend_config_data = '''
{
    "graphs": {
        "vtcm_mb":8,
        "graph_names":["qnn_model"]
    },
    "devices": [
        {
            "soc_id": 57,
            "dsp_arch": "v73",
            "cores":[{
                "core_id": 0,
                "perf_profile": "burst",
                "rpc_control_latency":100
            }]
        }
    ]
}
'''
#write the config files to a temporary location
with open('/tmp/htp_backend_extensions.json','w') as f:
    f.write(htp_backend_extensions_data)
with open('/tmp/htp_config.json','w') as f:
    f.write(htp_backend_config_data)
# Create a path under the models directory for serialized binaries
!mkdir $STABLE_DIFFUSION_MODELS/serialized_binaries

为文本编码器生成 QNN 上下文二进制文件

proc = subprocess.Popen([QNN_SDK_ROOT + "/bin/x86_64-linux-clang/qnn-context-binary-generator",
                             "--model", STABLE_DIFFUSION_MODELS + "/converted_text_encoder/x86_64-linux-clang/libtext_encoder.so",
                             "--backend", "libQnnHtp.so",
                             "--output_dir",  STABLE_DIFFUSION_MODELS + "/serialized_binaries",
                             "--binary_file", "text_encoder.serialized",
                             "--config_file", "/tmp/htp_backend_extensions.json",
                             "--log_level", "verbose"
                        ],stdout=subprocess.PIPE, stderr=subprocess.PIPE,env=env)
output, error = proc.communicate()
print(output.decode(),error.decode())

为 U-Net 生成 QNN 上下文二进制文件

预计执行时间:~2 分钟

proc = subprocess.Popen([QNN_SDK_ROOT + "/bin/x86_64-linux-clang/qnn-context-binary-generator",
                             "--model", STABLE_DIFFUSION_MODELS + "/converted_unet/x86_64-linux-clang/libunet.so",
                             "--backend", "libQnnHtp.so",
                             "--output_dir",  STABLE_DIFFUSION_MODELS + "/serialized_binaries",
                             "--binary_file", "unet.serialized",
                             "--config_file", "/tmp/htp_backend_extensions.json"
                        ],stdout=subprocess.PIPE, stderr=subprocess.PIPE,env=env)
output, error = proc.communicate()
print(output.decode(),error.decode())

为 VAE 解码器生成 QNN 上下文二进制文件

预计执行时间:~1.5 分钟

proc = subprocess.Popen([QNN_SDK_ROOT + "/bin/x86_64-linux-clang/qnn-context-binary-generator",
                             "--model", STABLE_DIFFUSION_MODELS + "/converted_vae_decoder/x86_64-linux-clang/libvae_decoder.so",
                             "--backend", "libQnnHtp.so",
                             "--output_dir",  STABLE_DIFFUSION_MODELS + "/serialized_binaries",
                             "--binary_file", "vae_decoder.serialized",
                             "--config_file", "/tmp/htp_backend_extensions.json"
                        ],stdout=subprocess.PIPE, stderr=subprocess.PIPE,env=env)
output, error = proc.communicate()
print(output.decode(),error.decode())

完成这些准备用于推理的稳定扩散模型的步骤后,这三个模型的 QNN 上下文二进制文件可在$STABLE_DIFFUSION_MODELS/serialized_binaries/

下一步是使用 Qualcomm AI Engine Direct SDK 中提供的可执行实用程序在 Snapdragon Gen2 Android 设备上执行准备好的模型(现在表示为序列化上下文二进制文件)。

  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值