A White Paper on Neural Network Deployment
  • ❤️‍🔥A White Paper on Neural Network Deployment
    • ❤️‍🔥A White Paper on Neural Network Deployment
    • 🤠CUDA
      • 🤑CPU|GPU程序执行流程
      • 🤗QiuckLearnFromPicture
      • 🤒GPU编程模型
      • 🫣线程束和线程束分化|Warp
      • 🤭Reduction|并行规约
      • 🤔全局内存(Global Memory)访问模式
      • 🫢Share Memory|共享内存|Bank Conflicts
      • 😷CUDA流和事件
      • 🫡Nsight system和Nsight compute
      • 🤫Grid-Stride Loops
    • 😄ONNX
      • 😉ONNX中的各类Proto
      • 🤔onnx->torch
      • 🥳0x00自定义算子
      • 😕0x01自定义算子
      • 🥴ONNX 模型的修改与调试
      • 😆ONNX中的一些概念
      • 😍用python操作ONNX
      • 🥹ONNX中的广播机制
      • 🤣外部数据
      • 🥰ONNX Model hub
      • 😘ONNX IR(Intermediate Representation)
      • 🥳ONNX后端
      • 🥸概述
    • 🐶TensorRT
      • 🐱TensorRT快速入门指南
      • 🐭文档简介
      • 🐹TensorRT的功能
      • 🐰TensorRT的C++接口解析
      • 🦊TensorRT的Python接口解析
      • 🐻TensorRT如何工作
      • 🐼trtexec的使用
      • 🐻‍❄️实战:解析onnx模型保存为engine文件|from scratch
      • 🐨实战:加载engine文件并执行推理|from scratch
      • 🐯手撕TensoRT源码|0x00
    • 🫶模型量化和剪枝
      • 🖕IEEE754标准
      • 🫰浮点运算产生的误差
      • 🤲映射和偏移
      • 🫴quantization from scratch|python
      • 👏动态量化范围
      • 🤝量化粒度
      • 👍校准
      • 👊Post-Training Quantization
      • ✊Quantization-Aware Training
      • 🤞pytorch-quantization使用文档
      • ✌️Polygraphy-Cheatsheet
    • 🤺杂文不杂
      • 😾Roofline_model
      • 🤖模型部署的几大误区
      • 😽手算Ampere架构各个精度的Throughout
      • 😻Tensor Core VS CUDA Core
      • 😺PNNX计算图结构剖析
      • 🎃融合BN和Conv层
      • 👾深度神经网络编译器原理简介
      • 👽在WSL2上安装CUDA_cuDNN_TensorRT
    • 🍀CPP
      • 🪵lamda表达式|C++11
      • 🌴智能指针|C++11
      • 🌲右值引用|移动语义|完美转发|C++11
      • 🫑emplace_back 减少内存拷贝和移动|C++11
      • 🥬多线程|互斥锁|条件变量|C++11
      • 🥒异步操作|C++11
      • 🍆原子变量|CAS操作|内存顺序|C++11
      • 🍏对象生存期和资源管理|RAII设计思想
      • 🍎Pimpl设计模式|编译防火墙
      • 🌶️std::variant|C++17
      • 🫛std::any|C++17
    • 🩷部署实战
      • ❤️yolov8Multitask
      • 💚yolov5
      • 🧡pointpillars
      • 💛centerpoint
      • 🩵deepstream
      • 💜BEVfusion
      • 💙BEVLane
      • 🖤Occupancy
    • ☯️重点参考书籍
Powered by GitBook
On this page

Was this helpful?

Edit on GitHub
  1. A White Paper on Neural Network Deployment
  2. 模型量化和剪枝

量化粒度

Previous动态量化范围Next校准

Last updated 1 year ago

Was this helpful?

量化中非常重要的概念: Quantization Granularity(量化粒度) 指的是对于一个Tensor,以多大的粒度去共享scale和z,或者dynamic range。

根据分组的依据不同,量化粒度有多种形式:

  • per-tensor/per-layer

  • per-channel/per-axis

  • per-col/per-row

  • per-embeding/per-token

  • per-block/group

一般来说,量化粒度越小,需要额外存储的量化系数就越多,比如针对卷积运算常见的 per-tensor/per-channel 量化,如下图所示,per-tensor 只需一组 (S, Z) 量化系数,而 per-channel 需要多组,提升了量化精度,但同时会一定程度增加量化后数据的大小

  • Per-tensor量化

    • 优点:低延迟: 一个tensor共享同一个量化参数

    • 缺点:高错误率: 一个scale很难覆盖所有FP32的 dynamic range

  • Per-channel (layer)量化

    • 优点:低错误率: 每一个channel都有自己的scale 来体现这个channel中的数据的dynamic range

    • 缺点:高延迟: 需要使用vector来存储每一个 channel的scale

从很多实验结果与测试中,对于weight和activation values的量化方法,一般会选取

  • 对于activation values,选取per-tensor量化

  • 对于weights,选取per-channel量化

为什么weight需要per-channel呢?主要是因为

  • BN计算与线性计算的融合 (BN folding)

线性变化𝑦=𝑤∗𝑥的BN folding可以把BN的参数融合在线性计算中。但是BN的可参数是per-channel的。如果 weights用per-tensor的话,会掉精度。

  • depthwise convolution

depthwise convolution中kernel的channel size是1,每一个kernel针对输入的对应的channel做卷积。所以每一个 channel中的参数可能差别会比较大。如果用per-tensor的话容易掉精度比较严重

e.g. 
• MobileNet: (FP32) 71.88, 
• MobileNet: (int8 Per-channel weight quantization)  71.56
 • MobileNet: (int8 Per-tensor weight quantization)  66.88
 • EfficientNet: (FP32) 76.85, 
• EfficientNet: (int8 Per-channel weight quantization)  76.72
 • EfficientNet: (int8 Per-tensor weight quantization)  12.93

目前的TensorRT已经默认对于Activation values选用Per-tensor,Weights选用 Per-channel,这是他们做了多次实验所得出的结果。很多其他平台的SDK可能不会 提供一些默认的量化策略,这时我们需要谨慎选择,尽快找到掉点的原因。

❤️‍🔥
🫶
🤝