量化参数的确定——ShrinkRange

发布时间:2026/9/2 12:35:46

量化参数的确定——ShrinkRange
摘要在执行PTQ或者QAT量化时确定FeatureMap的minmax值有很多种方式其它方式这里不做赘述主要介绍TI的edgevision中QAT相关实现代码使用的Percentile这种方式来确定FeatureMap的minmax理解感悟作为记录。工程代码中确定min,max的入口函数如下x_min,x_maxutils.extrema_fast(x,range_shrink_percentileTrue,fast_modeFalse)对应实现代码如下defextrema_fast(src,range_shrink_percentile0.0,channel_meanFalse,sigma0.0,fast_modeTrue):returnextrema(src,range_shrink_percentile,channel_mean,sigma,fast_mode)extrema函数实现如下defextrema(src,range_shrink_percentile0.0,channel_meanFalse,sigma0.0,fast_modeFalse):ifrange_shrink_percentile0andsigma0andchannel_meanFalse:mnsrc.min()mxsrc.max()returnmn,mxelifrange_shrink_percentile:# downsample for fast_modehist_array,mn,mx,mult_factor,offsettensor_histogram(src,fast_modefast_mode)ifhist_arrayisNone:returnmn,mx new_mn_scaled,new_mx_scaledextrema_hist_search(hist_array,range_shrink_percentile)new_mn(new_mn_scaled/mult_factor)offset new_mx(new_mx_scaled/mult_factor)offset# take care of floating point inaccuracies that can# increase the range (in rare cases) beyond the actual range.new_mnmax(mn,new_mn)new_mxmin(mx,new_mx)returnnew_mn,new_mxelifchannel_mean:dim[0,2,3]ifsrc.dim()4elseNonemntorch.amin(src,dimdim,keepdimFalse).mean()mxtorch.amax(src,dimdim,keepdimFalse).mean()returnmn,mxelifsigma:meantorch.mean(src)stdtorch.std(src)mnmean-sigma*std mxmeansigma*stdreturnmn,mxelse:assertFalse,unknown extrema computation mode其中的核心是tensor_histogram和extrema_hist_search的函数实现deftensor_histogram(src,fast_modeFalse):# downsample for fast_modefast_stride2fast_stride2fast_stride*2iffast_modeandlen(src.size())4and(src.size(2)fast_stride2)and(src.size(3)fast_stride2):r_startrandom.randint(0,fast_stride-1)c_startrandom.randint(0,fast_stride-1)srcsrc[...,r_start::fast_stride,c_start::fast_stride]#mnsrc.min()mxsrc.max()ifmn0andmx0:returnNone,mn,mx,1.0,0.0## compute range_shrink_percentile based min/max# frequency - bincount can only operate on unsignednum_bins255.0cum_freqfloat(100.0)offsetmn range_valtorch.abs(mx-mn)mult_factor(num_bins/range_val)tensor_int(src.contiguous().view(-1)-offset)*mult_factor tensor_intfunctional.round_g(tensor_int).int()# numpy version# hist np.bincount(tensor_int.cpu().numpy())# hist_sum np.sum(hist)# hist_array hist.astype(np.float32) * cum_freq / float(hist_sum)# torch versionhisttorch.bincount(tensor_int)# calculate appearing number for each element in tensorhist_sumtorch.sum(hist)histhist.float()*cum_freq/hist_sum.float()hist_arrayhist.cpu().numpy()returnhist_array,mn,mx,mult_factor,offset# this code is not parallelizable. better to pass a numpy arraydefextrema_hist_search(hist_array,range_shrink_percentile):new_mn_scaled0new_mx_scaledlen(hist_array)-1hist_sum_left0.0hist_sum_right0.0forh_idxinrange(len(hist_array)):r_idxlen(hist_array)-1-h_idx hist_sum_lefthist_array[h_idx]hist_sum_righthist_array[r_idx]ifhist_sum_leftrange_shrink_percentile:new_mn_scaledh_idxifhist_sum_rightrange_shrink_percentile:new_mx_scaledr_idx##returnnew_mn_scaled,new_mx_scaled代码实现就是这些且看每一步都在做什么。入口代码且不必说主要看最后的核心实现函数其中src参数就是featuremap入参进去也就是Tensor矩阵进来mnsrc.min() 和mxsrc.max()作为基础的min,max值 只要mn、mx不为0那就开始使用percentile这种方式来确定mn、mx参数假设输入srctorch.Tensor(np.random.randn(5, 5, 5))通过如下方式将所有点映射到[0,255], 推测这里使用255主要是使用8bit量化方式。num_bins255.0cum_freqfloat(100.0)offsetmn range_valtorch.abs(mx-mn)mult_factor(num_bins/range_val)tensor_int(src.contiguous().view(-1)-offset)*mult_factor tensor_intfunctional.round_g(tensor_int).int()而后取整并统计tensor_int在0-255上每个整数值出现的次数这里可以看如下测试获得相应结果srctensor([[[1.2441,-0.0867,0.9002,-0.1932,2.3541],[-0.4824,-0.3223,2.5375,-1.7840,1.9771],[0.3940,-1.4480,-0.3781,-0.7957,-1.0538],[-1.2109,-0.3825,0.9433,-1.1705,0.3820],[2.3790,0.0455,1.0485,-1.2459,0.1798]],[[-0.8588,1.2191,1.4201,0.6451,0.1503],[-0.1744,0.3837,-0.7574,-0.6267,-0.8850],[1.2707,0.0152,-0.8123,1.0253,-1.2014],[0.4145,-1.8473,-1.1998,-1.1097,-0.2954],[1.3490,0.3272,-0.7207,0.8277,-1.4434]],[[-0.4233,-0.5626,-0.5374,0.5536,0.7213],[2.1416,0.1454,1.3634,1.3695,0.2687],[0.0225,0.6928,0.5589,-0.1421,-1.0773],[-0.9817,1.0085,1.0390,0.6374,-0.4628],[-0.4807,-0.8651,0.9142,-0.1464,0.4845]],[[-0.5339,1.2211,0.5690,-0.3386,-0.8696],[-1.6646,-0.4744,2.2127,0.1378,-0.3506],[-0.4366,0.9862,-1.0315,-0.2987,-0.7905],[0.8619,0.1890,0.2300,1.4928,-0.3998],[0.3227,-1.3765,-0.7497,-0.0803,-1.1507]],[[0.1519,-0.8967,0.3365,-0.2855,-0.2702],[1.1136,0.3253,2.6808,0.4749,-1.1373],[-1.4715,-1.5497,-0.5941,-0.3381,-0.1578],[0.1751,0.4058,0.4405,1.0508,-0.8351],[1.3446,1.4361,1.0363,-0.2064,1.6912]]])histtensor([1,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,1,1,1,0,0,0,1,0,0,0,0,0,0,1,0,3,0,1,1,1,0,1,1,0,1,1,0,0,1,0,0,0,0,2,2,1,1,1,1,1,1,1,1,0,0,0,0,0,1,0,1,1,0,2,0,0,3,1,1,1,0,2,1,1,2,1,2,1,1,0,0,1,1,1,1,2,0,0,1,1,0,0,0,0,2,0,1,0,0,0,0,3,1,2,1,0,1,0,1,0,0,3,1,0,0,3,2,0,1,0,2,0,0,0,1,2,0,0,0,2,0,0,1,0,1,0,0,0,0,0,1,0,1,0,1,1,1,0,0,1,1,2,3,0,0,0,1,0,0,0,0,0,2,1,0,1,0,0,0,2,2,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1])之后对hist再做一次缩放的计算就得到来hist_arrray矩阵该矩阵会对mx、mn的更新起到决定性作用。histtorch.bincount(tensor_int)# calculate appearing number for each element in tensorhist_sumtorch.sum(hist)histhist.float()*cum_freq/hist_sum.float()hist_arrayhist.cpu().numpy()extrema_hist_search中进行mx、mn的更新, 从hist_array两端开始不断累积查找寻找到大于range_shrink_percentile的index并返回通过tensor_histogram函数返回的mult_factor, offset计算新的new_mn、new_mxnew_mn(new_mn_scaled/mult_factor)offset new_mx(new_mx_scaled/mult_factor)offset与原来的mn和mx进行比较从而更新mn和mxnew_mnmax(mn,new_mn)new_mxmin(mx,new_mx)returnnew_mn,new_mx这里不太理解的其实是最后new_mn、new_mx的反结算方式这算是一种更新方式而不是tensor_histogram的逆运算。

相关新闻

MediaPipe 手部追踪迁移:Hand Landmarker 完整落地指南

MediaPipe 手部追踪迁移:Hand Landmarker 完整落地指南

2026/9/2 12:35:46

MediaPipe 手部追踪迁移:Hand Landmarker 完整落地指南 【免费下载链接】mediapipe Cross-platform, customizable ML solutions for live and streaming media. 项目地址: https://gitcode.com/GitHub_Trending/med/mediapipe MediaPipe 手部追踪迁移&#…

【模拟电子电路-电子元器件】

【模拟电子电路-电子元器件】

2026/9/2 12:35:46

模拟电子电路-电子元器件 ■ 电路公式 ■ 01. 欧姆定律 I = U/R ■ 02. 功率计算 P(W)=U*I ■ 03. 焦耳定律 ■ 硬件名词 ■ 01 耦合 ■ 02 阻抗 ■ 001 阻抗匹配 ■ 002 特性阻抗 ■ 03 电桥 ■ 04 谐振 ■ 05 纹波 ■ 06 谐波 ■ 07 滤波电容、去耦电容、旁路电容 ■ 08 噪…

AionUi 高级设置 3 步上手:多模型接入、自定义主题与多 Agent 管理

AionUi 高级设置 3 步上手:多模型接入、自定义主题与多 Agent 管理

2026/9/2 12:35:46

AionUi 高级设置 3 步上手:多模型接入、自定义主题与多 Agent 管理 【免费下载链接】AionUi Open-source 24/7 Cowork app for OpenClaw, Hermes, Claude Code, Codex, OpenCode and 20 more CLI Agent | Customize your assistants | Team them up|Star…

电力系统功率失衡影响与调频控制技术解析

电力系统功率失衡影响与调频控制技术解析

2026/9/2 13:35:48

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

vue-vben-admin AI 模块完整指南:5 分钟给后台加上数据预测和智能表单校验

vue-vben-admin AI 模块完整指南:5 分钟给后台加上数据预测和智能表单校验

2026/9/2 13:35:48

vue-vben-admin AI 模块完整指南:5 分钟给后台加上数据预测和智能表单校验 【免费下载链接】vue-vben-admin A modern vue admin panel built with Vue3, Shadcn UI, Vite, TypeScript, and Monorepo. Its fast! 项目地址: https://gitcode.com/GitHub_Trending/v…

Lightpanda 无头浏览器完整指南:省 9 倍内存、快 11 倍的极速方案

Lightpanda 无头浏览器完整指南:省 9 倍内存、快 11 倍的极速方案

2026/9/2 13:35:48

Lightpanda 无头浏览器完整指南:省 9 倍内存、快 11 倍的极速方案 【免费下载链接】browser Lightpanda: the headless browser designed for AI and automation 项目地址: https://gitcode.com/GitHub_Trending/browser32/browser AI 代理、大规模网页抓取、…

大模型推理加速100倍的工程路线与关键技术

大模型推理加速100倍的工程路线与关键技术

2026/9/2 13:35:48

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

4GB 显存如何跑 70B 大模型:AirLLM 低显存推理快速上手

4GB 显存如何跑 70B 大模型:AirLLM 低显存推理快速上手

2026/9/2 13:35:48

4GB 显存如何跑 70B 大模型:AirLLM 低显存推理快速上手 【免费下载链接】airllm AirLLM 70B inference with single 4GB GPU 项目地址: https://gitcode.com/GitHub_Trending/ai/airllm 跑一次 70B 推理,控制台蹦出一行 CUDA out of memory&#…

GSD Rust原生引擎性能优化全解析:ripgrep搜索与gitignore感知文件发现如何实现毫秒级响应

GSD Rust原生引擎性能优化全解析:ripgrep搜索与gitignore感知文件发现如何实现毫秒级响应

2026/9/2 13:25:48

GSD Rust原生引擎性能优化全解析:ripgrep搜索与gitignore感知文件发现如何实现毫秒级响应 【免费下载链接】gsd-2 A powerful meta-prompting, context engineering and spec-driven development system that enables agents to work for long periods of time auto…

备战数据库管理工程师校招:索引、事务、备份恢复核心考点解析

备战数据库管理工程师校招:索引、事务、备份恢复核心考点解析

2026/9/2 10:08:07

每年校招季我都会接触不少准备数据库方向笔试的同学,看到最多的状态就是:简历上写着“熟悉 MySQL”“了解索引优化”,一碰到数据库管理工程师的笔试卷,却在索引、事务、锁、备份恢复这些题目上翻车。网易这套 2018 校园招聘数据库…

数字电路时序基石:深入理解建立时间与保持时间

数字电路时序基石:深入理解建立时间与保持时间

2026/9/2 12:11:52

1. 这不是“背公式”的事:时间参数到底在约束什么你翻过数字电路教材,一定见过这两个词:建立时间(Setup Time)和保持时间(Hold Time)。它们常被并列写在触发器(Flip-Flop&#xff09…

蓝桥杯国赛超声波测距机:从单片机原理到嵌入式系统实战

蓝桥杯国赛超声波测距机:从单片机原理到嵌入式系统实战

2026/9/1 23:49:08

1. 项目缘起:从赛题到超声波测距机的诞生第八届蓝桥杯单片机设计与开发国赛的题目,我至今记忆犹新。它没有直接给出一个花哨的名字,而是用“超声波测距机”这个朴实无华的功能描述,精准地勾勒出了考核的核心。对于当时备赛的我而言…

单片机毕业设计-基于单片机与蓝牙通讯的输液状态监测终端设计与开发 基于 STM32 或 51 单片机的液位‑滴速‑温度多参数输液监护装置设计(024005)

单片机毕业设计-基于单片机与蓝牙通讯的输液状态监测终端设计与开发 基于 STM32 或 51 单片机的液位‑滴速‑温度多参数输液监护装置设计(024005)

2026/9/2 0:04:59

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于嵌入式单片机,Java、小程序技术领域和毕业项目实战 ✌️…

DeepSeek字幕翻译实战:从API调用到批量SRT转中文的完整方案

DeepSeek字幕翻译实战:从API调用到批量SRT转中文的完整方案

2026/9/2 0:04:59

这次我们来看一个很实用的 DeepSeek 落地场景:用 DeepSeek 把英文视频字幕自动翻译成中文。具体案例是《恶魔君》1989 年第 28 集的英转中字幕任务,标题写得很直白,但背后其实是一整套可以复用的技术流程:字幕解析、模型调用、批量…

用Python搭建搞笑语音助手:从语音识别到语音合成全教程

用Python搭建搞笑语音助手:从语音识别到语音合成全教程

2026/9/2 0:04:59

当你家里摆着一台天猫精灵,却总希望语音助手偶尔“不正经”一点,不用官方腔回答问题,而是张口就接几句搞笑段子,会是什么体验?我最近动手验证了一下这个想法——没有去改装任何市面上现有的智能音箱,而是直…

远程协作的工作台整理

远程协作的工作台整理

2026/9/2 6:21:32

远程协作的工作台整理远程协作的核心不是再加一个工具,而是让交接信息足够完整。异步任务要写明目标、输入位置、完成标准和需要决策的人。 工作台的最小配置 将日程、待办、代码和沟通入口收拢到少数固定位置;通知按紧急程度分层。工作台不需要模仿办公…

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

2026/9/2 6:21:32

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

2026/9/2 2:45:06

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…