SNPE 模型量化实战

一. SNPE模型部署的整体流程

大致步骤:训练模型 -> 模型转.dlc -> 模型量化 -> 验证量化结果 -> 模型部署
在这里插入图片描述

二. 安装SNPE环境(docker 安装)

1. docker登录

docker login cr.d.xiaomi.net -u org_46522 -p 46370020336295373ad3815abd6db118

2. 拉取SNPE镜像

docker pull cr.d.xiaomi.net/ailab-vision-doc/snpe_dev:18.04

3. 开启一个后台docker container

docker run -it --privileged -d --name snpe-1.50  -v /dev/bus/usb:/dev/bus/usb -v /home/:/home/ --net=host cr.d.xiaomi.net/ailab-vision-doc/snpe_dev:18.04

三. SNPE使用

1. 启动一个container

# 查看之前已经启动的container
docker container ls -a
# 61744239ab70是container id
docker container start 61744239ab70
# 开启一个docker 终端
docker exec -it 61744239ab7 /bin/bash

注:py35、py36切换python环境,1.4x以下需要python3.5环境,1.5需要python3.6环境
snpe环境目录为/root/snpe/snpe-1.xxx

2. 环境变量设置:(以snpe1.50为例)

根据实际需要设置vim ~/.bashrc文件中的环境变量:

export SNPE_ROOT="/root/snpe/snpe-1.50.0.2622/"
export PYTHON_VERSION="python3.6"
export PYTHON_ENV="py36"

然后跳转到对应的目录的bin中,执行环境设置:

cd /root/snpe/snpe-1.xxx/bin
source envsetup.sh -t $TENSORFLOW_DIR (tensorflow)
source envsetup.sh -o $ONNX_DIR   (onnx)

如果docker中没有对应版本的snpe目录,在官网上下载:snpe官网。 然后从/home/对应的路径拷贝至/root/snpe/目录中。

四. SNPE 模型转换和量化

1. 模型转换

snpe-tensorflow-to-dlc --input_network ./hed.pb  --input_dim my_input "1,384,384,3" --out_node my_output --output_path my.dlc

2. 模型量化

准备量化的输入图片数据:首先从测试集中获取N张图片(N的取值范围推荐在50~200之间),然后将图片转换成raw文件,转换脚本可参考

#!/usr/bin/python
# coding=utf8
# Author: guopei

import numpy as np
import os
import cv2
import shutil
import random
from tqdm import tqdm


def get_image_path_list(dataset_path_list, N):
    """
    从数据集中随机抽取N张图片
    Args:
        dataset_path_list:
        N:

    Returns:

    """
    image_path_list = []
    for dataset_path in dataset_path_list:
        for dir_path, _, file_names in os.walk(dataset_path):
            for file_name in file_names:
                # if 'input' not in file_name:
                #     continue
                img_path = os.path.join(dir_path, file_name)
                image_path_list.append(img_path)
    random.shuffle(image_path_list)
    return image_path_list[:N]


def preprocess(image):
    """
    对图片进行预处理,image的通道顺序需要是BGR
    Args:
        image:

    Returns:

    """
    image = np.array(image)
    # 如果输出是float32,那么输入也一定要转换成float32
    image = cv2.resize(image, (528, 784), cv2.INTER_LINEAR)
    image = cv2.cvtColor(image, cv2.COLOR_BGR2YUV)
    image = image[:,:,0]
    image = image.astype(np.float32)
    # 归一化
    image = image / 255.
    return image


def convert(image_path_list, raw_data_dir_save_path):
    """
    把图片转换成raw文件
    Args:
        image_path_list:        待转换的图片的路径列表
        raw_data_dir_save_path: raw文件的保存路径

    Returns:

    """
    if os.path.exists(raw_data_dir_save_path):
        shutil.rmtree(raw_data_dir_save_path)
    os.mkdir(raw_data_dir_save_path)
    raw_data_path_list_file = raw_data_dir_save_path + '_list.txt'
    if os.path.exists(raw_data_path_list_file):
        os.remove(raw_data_path_list_file)

    with open(raw_data_path_list_file, 'w') as f:
        for index, img_path in enumerate(image_path_list):
            raw_name = os.path.basename(img_path).split('.')[0] + '.raw'
            raw_data_path = os.path.join(raw_data_dir_save_path, raw_name)
            f.write(raw_data_path + '\n')
            image = cv2.imread(img_path)
            image = preprocess(image)
            image.tofile(raw_data_path)


if __name__ == '__main__':
    image_path_list = get_image_path_list(
        dataset_path_list=['/home/guopei/jpgs'], N=2)
    convert(image_path_list=image_path_list,
            raw_data_dir_save_path='./img_raws')

转换过程中需要注意以下几点:
一定要按照模型对输入数据的要求对图片进行预处理;
一定要将图片转换成float32;

转化结束后,将得到一个包含所有raw文件的文件夹和一个包含所有raw文件绝对路径的list文件。
模型量化:

snpe-dlc-quantize 
--input_dlc my.dlc 
--input_list quantize_data_list.txt 
--output_dlc my_quant.dlc 
--optimizations cle --optimizations bc --enable_htp

–input_list就是上一步骤生成的包含所有raw文件绝对路径的list文件,
–optimizations cle --optimizations bc对应的量化算法效果最佳,但是这种量化算法对模型结构有一定的限制且量化速度较慢,如果使用这种量化算法出现量化失败,可以将–optimizations cle --optimizations bc这两个选项去掉,使用snpe默认的量化算法。
–enable_htp选项一定需要, 否则dsp运行的初始化非常慢, 这里千万注意,官网没有介绍;

五. 验证量化后的模型

snpe-net-run --container my_quant.dlc --input_list ./quantize_data_list.txt --output_dir ./my_dir

将得到的raw转换成图片,可参考代码:

      
import numpy as np
import os
import cv2
import shutil


def postProcess(net_output):
    predEdge = (net_output[..., 0:1] * 255).astype(np.uint8)
    predSegment = (net_output[..., 1:2] * 255).astype(np.uint8)
    return predEdge, predSegment


def convert(raw_data_dir_path, converted_image_dir_save_path):
    if os.path.exists(converted_image_dir_save_path):
        shutil.rmtree(converted_image_dir_save_path)
    os.mkdir(converted_image_dir_save_path)

    count = 0
    for dir_path, _, filenames in os.walk(raw_data_dir_path):
        for filename in filenames:
            if 'raw' not in filename:
                continue
            raw_file_path = os.path.join(dir_path, filename)
            net_output = np.fromfile(raw_file_path, dtype='float32').reshape((384, 384, 2))
            predEdge, predSegment = postProcess(net_output)
            edge_save_path = os.path.join(converted_image_dir_save_path, str(count).zfill(3) + '_output1.jpg')
            segment_save_path = os.path.join(converted_image_dir_save_path, str(count).zfill(3) + '_output2.jpg')
            print(edge_save_path)
            count += 1
            cv2.imwrite(edge_save_path, predEdge)
            cv2.imwrite(segment_save_path, predSegment)


if __name__ == '__main__':
    raw_data_dir_path = 'dlc_output_now'
    converted_image_dir_save_path = raw_data_dir_path + '_convert'
    convert(raw_data_dir_path, converted_image_dir_save_path)

每天进步一点,欢迎技术交流!!!

<think>好的,用户想了解NPU如何支持大型模型在本地进行部署和运算的方法或教程。我需要先回顾已有的引用内容,看看哪些信息可以直接应用。 根据引用[2],NPU是专为神经网络计算设计的,能高效处理并行任务,提升图像识别、自然语言处理等领域的性能,这对大模型推理有帮助。引用[3]提到全志Tina的NPU支持模型转换,如Caffe、TensorFlow Lite等格式的导入导出,这可能涉及模型优化步骤。引用[4]讨论了量化方法,需要确定浮点范围,这对模型压缩很重要。 接下来需要整合这些信息,分步骤说明NPU部署大模型的方法。首先,模型优化和压缩是关键,可能包括量化和剪枝。然后模型转换,将训练好的模型转换为NPU支持的格式。接着是硬件集成,需要驱动和中间件支持。最后是性能调优,如内存管理和算子优化。 还要考虑用户可能需要具体步骤或工具,比如推荐厂商提供的SDK,或者量化工具的使用。此外,可能涉及代码示例,比如模型转换的脚本或部署的代码片段。 需要确保回答结构清晰,分点说明,并引用相关引用。同时,生成的相关问题要围绕模型优化、工具使用、挑战和量化方法展开。</think>### NPU支持大型模型本地部署与运算方法 #### 一、核心原理 NPU(神经网络处理器)通过专用指令集和硬件加速架构,可对$y=Wx+b$这类矩阵运算实现百倍于CPU的能效比。其核心能力体现在对卷积计算、注意力机制等神经网络算子实现硬件级加速[^2]。 #### 二、实施步骤 1. **模型优化** - 量化压缩:将浮点模型转换为8位定点模型,计算范围确定公式: $$ Q = \text{round}\left(\frac{255 \times (R - R_{min})}{R_{max} - R_{min}}\right) $$ 可减少75%内存占用[^4] - 算子融合:将Conv+BN+ReLU合并为单算子 - 层剪枝:移除冗余网络层 2. **模型转换** 使用厂商工具链(如全志Tina NPU SDK)执行: ```bash # 示例模型转换命令 tf2npu --input model.pb --output npu_model.bin --quantize int8 ``` 支持ONNX/TensorFlow/Caffe等格式转换[^3] 3. **硬件集成** - 加载NPU驱动模块 - 配置DMA内存通道 - 部署轻量级推理框架(如Tengine) 4. **性能调优** - 内存复用:通过内存池管理减少分配开销 - 流水线并行:重叠数据搬运与计算 - 算子优化:针对NPU指令集重构计算图 #### 三、典型工具链 | 工具类型 | 示例 | 功能 | |----------------|----------------------|-------------------------| | 模型转换器 | TensorRT、SNPE | 格式转换与量化 | | 性能分析器 | Vtune、Arm Streamline | 热点分析与瓶颈定位 | | 部署框架 | OpenVINO、MNN | 运行时管理与资源调度 | #### 四、实战案例 基于全志V853芯片部署BERT模型的代码框架: ```c++ // 初始化NPU上下文 npu_context ctx = create_npu_context(); // 加载模型 npu_model model = load_model(ctx, "bert.bin"); // 创建张量 tensor input_tensor = create_input_tensor(model); // 执行推理 run_model(model, input_tensor); // 获取输出 float* logits = get_output_data(model); ```
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值