【mnn】——模型离线量化流程代码浅析

2024-06-13 08:08

本文主要是介绍【mnn】——模型离线量化流程代码浅析,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

mnn, 离线量化

1. 前言

mnn的离线量化,需要首先将其他模型转换成mnn的模型表达,再进行量化。

这里我们采用MAX_ABS进行weight权重量化,KL散度进行激活值的量化,int8对称量化。

2. Code

2.1 mnn模型读入与解析

std::unique_ptr<MNN::NetT> netT;{std::ifstream input(modelFile);std::ostringstream outputOs;outputOs << input.rdbuf();netT = MNN::UnPackNet(outputOs.str().c_str());}// temp build net for inferenceflatbuffers::FlatBufferBuilder builder(1024);auto offset = MNN::Net::Pack(builder, netT.get());builder.Finish(offset);int size      = builder.GetSize();auto ocontent = builder.GetBufferPointer();// model buffer for creating mnn Interpreterstd::unique_ptr<uint8_t> modelForInference(new uint8_t[size]);memcpy(modelForInference.get(), ocontent, size);std::unique_ptr<uint8_t> modelOriginal(new uint8_t[size]);memcpy(modelOriginal.get(), ocontent, size);netT.reset();netT = MNN::UnPackNet(modelOriginal.get());

2.2 创建Calibration数据dataloader
这个Calibration是整个量化的主流程,整体流程可以归纳为:

  • fake quant weight,对原有的模型进行假量化,就是将模型的权重用MAX_ABS量化到int8,再从int8反量化到float类型。这里是为了统计的激活值的范围更精确。
  • 将假量化模型和浮点模型的tensor放入两个不同的map

2.3 离线量化
整体流程:

  • 给假量化模型传入图片,更新每个tensor的最大值,最小值
    在这里插入图片描述
  • 计算所有tensor的分布,将激活值用2048个bin进行离散,统计其直方图
    在这里插入图片描述
  • 通过KL散度为每个tensor计算一个阈值threshold,并将阈值转换为浮点和int8之间转换的scale
    在这里插入图片描述
  • 将量化参数,tensor scale,int8 weight等量化参数写回模型。 注意这里需要将浮点的weight clear掉。
for (const auto iter :  _scales) {std::unique_ptr<MNN::TensorDescribeT> describe(new MNN::TensorDescribeT);describe->index = _tensorIdx[iter.first];describe->quantInfo.reset(new MNN::TensorQuantInfoT);describe->quantInfo->scale = iter.second;describe->quantInfo->type = MNN::DataType_DT_INT8;describe->quantInfo->min = -1 * _featureClampValue;describe->quantInfo->max = 1 * _featureClampValue;_originalModel->extraTensorDescribe.emplace_back(std::move(describe));          // 1. extraTensorDescribe量化后添加的属性,在哪里使用??}SymmetricQuantizeWeight(param->weight.data(), weightSize, quantizedWeight.data(), quantizedWeightScale.data(), outputChannel, _weightClampValue);param->quanParameter = IDSTEncoder::encode(param->weight, quantizedWeightScale, weightSize/channles, channles, false, quantizedWeight.data(), -_weightClampValue);          // 3. 
param->quanParameter->scaleIn = inputScale;
param->quanParameter->scaleOut = outputScale;
if (param->common->relu6) {param->common->relu  = true;param->common->relu6 = false;
}
param->weight.clear();          // 4. 清除原有的weight
  • 重新写回到模型

总结

  • 整个代码还是很清晰的,结构也很明确。只是后续要如何使用这些量化参数需要深入到mnn的框架里,后面再补上mnn框架代码的浅析

这篇关于【mnn】——模型离线量化流程代码浅析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1056741

相关文章

Python使用Tenacity一行代码实现自动重试详解

《Python使用Tenacity一行代码实现自动重试详解》tenacity是一个专为Python设计的通用重试库,它的核心理念就是用简单、清晰的方式,为任何可能失败的操作添加重试能力,下面我们就来看... 目录一切始于一个简单的 API 调用Tenacity 入门:一行代码实现优雅重试精细控制:让重试按我

Spring Boot 中的默认异常处理机制及执行流程

《SpringBoot中的默认异常处理机制及执行流程》SpringBoot内置BasicErrorController,自动处理异常并生成HTML/JSON响应,支持自定义错误路径、配置及扩展,如... 目录Spring Boot 异常处理机制详解默认错误页面功能自动异常转换机制错误属性配置选项默认错误处理

Spring Boot从main方法到内嵌Tomcat的全过程(自动化流程)

《SpringBoot从main方法到内嵌Tomcat的全过程(自动化流程)》SpringBoot启动始于main方法,创建SpringApplication实例,初始化上下文,准备环境,刷新容器并... 目录1. 入口:main方法2. SpringApplication初始化2.1 构造阶段3. 运行阶

使用Go实现文件复制的完整流程

《使用Go实现文件复制的完整流程》本案例将实现一个实用的文件操作工具:将一个文件的内容完整复制到另一个文件中,这是文件处理中的常见任务,比如配置文件备份、日志迁移、用户上传文件转存等,文中通过代码示例... 目录案例说明涉及China编程知识点示例代码代码解析示例运行练习扩展小结案例说明我们将通过标准库 os

Python实现MQTT通信的示例代码

《Python实现MQTT通信的示例代码》本文主要介绍了Python实现MQTT通信的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一... 目录1. 安装paho-mqtt库‌2. 搭建MQTT代理服务器(Broker)‌‌3. pytho

MySQL进行数据库审计的详细步骤和示例代码

《MySQL进行数据库审计的详细步骤和示例代码》数据库审计通过触发器、内置功能及第三方工具记录和监控数据库活动,确保安全、完整与合规,Java代码实现自动化日志记录,整合分析系统提升监控效率,本文给大... 目录一、数据库审计的基本概念二、使用触发器进行数据库审计1. 创建审计表2. 创建触发器三、Java

Ubuntu 24.04启用root图形登录的操作流程

《Ubuntu24.04启用root图形登录的操作流程》Ubuntu默认禁用root账户的图形与SSH登录,这是为了安全,但在某些场景你可能需要直接用root登录GNOME桌面,本文以Ubuntu2... 目录一、前言二、准备工作三、设置 root 密码四、启用图形界面 root 登录1. 修改 GDM 配

浅析Spring如何控制Bean的加载顺序

《浅析Spring如何控制Bean的加载顺序》在大多数情况下,我们不需要手动控制Bean的加载顺序,因为Spring的IoC容器足够智能,但在某些特殊场景下,这种隐式的依赖关系可能不存在,下面我们就来... 目录核心原则:依赖驱动加载手动控制 Bean 加载顺序的方法方法 1:使用@DependsOn(最直

Spring Security中用户名和密码的验证完整流程

《SpringSecurity中用户名和密码的验证完整流程》本文给大家介绍SpringSecurity中用户名和密码的验证完整流程,本文结合实例代码给大家介绍的非常详细,对大家的学习或工作具有一定... 首先创建了一个UsernamePasswordAuthenticationTChina编程oken对象,这是S

Java中调用数据库存储过程的示例代码

《Java中调用数据库存储过程的示例代码》本文介绍Java通过JDBC调用数据库存储过程的方法,涵盖参数类型、执行步骤及数据库差异,需注意异常处理与资源管理,以优化性能并实现复杂业务逻辑,感兴趣的朋友... 目录一、存储过程概述二、Java调用存储过程的基本javascript步骤三、Java调用存储过程示