英伟达TensorRT 8-bit Inference推理
作者:互联网
英伟达TensorRT 8-bit Inference推理
引论
● 目标:将FP32 CNN转换为INT8,不会造成显著的精度损失。
● 原因:Int8 Math具有更高的吞吐量和更低的内存需求。
● 挑战:INT8的精度和动态范围,明显低于FP32。
● 解决方案:在将训练模型权权重化为INT8时,及在INT8计算激活时,将信息损失降至最低。
● 结果:方法已在TensorRT中实现。不需要任何额外的微调或重训练。
Outline
● INT8 compute
● Quantization
● Calibration
● Workflow in TensorRT
● Results
INT8推理挑战
● 与FP32相比,INT8的精度和动态范围明显更低。
● 需要的不仅仅是从FP32到INT8的简单类型转换。
高通量INT8数学
● 需要sm_61+(Pascal TitanX,GTX 1080,特斯拉P4,P40等等)。
● 在32位结果中,累加四路byte字节点积。
Context
● Performance.
● No accuracy loss.
● Hence solution has to be “simple” and compute efficient.
Linear quantization
Representation:
Tensor Values=FP32 scale factor * int8 array+FP32 bias
● 解决方案必须“简单”,计算效率高。
张量值=FP32比例因子*int8数组+FP32偏差
真的需要bias吗?
两个矩阵:
A=scale_A * QA+bias_A
B=scale_B * QB+bias_B
Let’s multiply those 2 matrices:
A * B=scale_A * scale_B * QA * QB
+ scale_A * QA * bias_B
+ scale_B * QB * bias_A
+ bias_A * bias_B
将这两个矩阵相乘:
真的需要bias吗?
不,两个矩阵:
A=scale_A * QA
B=scale_B * QB
将两个矩阵相乘:
A * B=scale_A * scale_B * QA * QB
对称线性量化
Representation:
张量值=FP32比例因子*int8数组
整个int8张量的一个FP32比例因子
问:如何设置比例因子?
Quantization
● No saturation: map |max| to 127
● 无饱和度:将| max |映射到127
Quantization
● 无饱和度:将| max |映射到127
● 通常,精度损失严重
● 无饱和度:将| max |映射到127
● 饱和超过|阈值|至127
● 通常,精度损失严重
Quantization
问:如何优化阈值选择?
● 在INT8表示的范围和精度间,进行折衷权衡。
两种编码的“相对熵”
● INT8模型编码与原始FP32模型相同的信息。
● 尽量减少信息损失。
● 信息损失由ullback-Leibler散度(又称相对熵或信息散度)衡量。
○ P,Q-两种离散概率分布。
○ KL_divergence(P,Q):= SUM(P[i] * log(P[i]/Q[i]),i)
● 直觉:KL散度度量,在近似给定编码时,丢失的信息量。
解决方案:校准
● 在校准数据集上运行FP32推理。
● 对于每一层:
○ 收集激活的直方图。
○ 生成许多具有不同饱和阈值的,量化分布。
○ 选择最小化KL_divergence(ref_distr,quant_distr)。
● 在典型的桌面工作站上,整个过程需要几分钟。
校准数据集
● 表示
● 多种多样的
● 理想情况下,验证数据集的子集。
● 1000份样品
校准结果
校准结果#1
校准结果#2
校准结果#2
校准结果#3
校准结果#4
校准结果#5
TensorRT中的工作流
TensorRT中的典型工作流
● 需要:
○ 用FP32训练的模型。
○ 校准数据集。
● TensorRT将:
○ 在FP32中,对校准数据集,运行推理。
○ 收集所需的统计数据。
○ 运行校准算法→ 优化比例因子。
○ 量化FP32权重→ INT8。
○ 生成“CalibrationTable”和INT8执行引擎。
Results
Results – Accuracy
TensorRT 2.1,已启用所有优化。ILSVRC2012验证数据集,batch批处理=25幅图像。对未用于校准的500batches,进行了准确度测量。
Results – Performance
TensorRT 2.1,已启用所有优化。
公开挑战/改进
● ReLU后激活的Unsigned int8。
● RNNs→ 开放性研究问题。
● 微调饱和阈值。
● 公开API,接受用户提供的自定义比例因子。
Conclusion
● 引入了一种自动,无参数的方法,用于将FP32 CNN模型,转换为INT8。
● 对称线性量化,用于权重和激活。
● 量化原始FP32数据,使信息损失最小化。
● 使用FP32训练的大众化,公开可用的CNN模型,可转换为INT8,INT8模型的精度与FP32基线相当。
熵校准-伪码
输入:FP32直方图H,共2048个bins单元:bin[0],…,bin[2047]
For i in range( 128,2048):
reference_distribution_P=[bin[0],...,bin[i-1]] // take first ‘ i ‘ bins from H
outliers_count=sum( bin[i],bin[i+1],…,bin[2047])
reference_distribution_P[i-1] += outliers_count
P/=sum(P) // normalize distribution P
candidate_distribution_Q=quantize [bin[0],…,bin[i-1]] into 128 levels // explained later
expand candidate_distribution_Q to ‘ i ’ bins // explained later
Q/=sum(Q) // normalize
distribution Q divergence[i]=KL_divergence( reference_distribution_P,
candidate_distribution_Q)
End For
Find index ‘m’ for which divergence[m] is minimal
threshold=( m+0.5) * ( width of a bin)
候选分布Q
● KL_divergence(P,Q) 要求 len(P) == len(Q)
● 候选分布 Q 源自融合‘ i ’ bins,从bin[0] 到 bin[i-1],生成 128 bins
● 随后,Q 再次‘expanded’到‘i’ bins
简单示例:
参考分布P由8 bins组成,希望量化到2 bins:
P=[1,0,2,3,5,3,1,7]
融合到 2 bins (8/2=4 连续 bins 合并成一个 bin) [1+0+2+3,5+3+1+7]=[6,16]
随后,按比例expand 到 8 bins,原始分布P保存为empty bins:
Q=[6/3,0,6/3,6/3,16/4,16/4,16/4,16/4]=[2,0,2,2,4,4,4,4]
now we should normalize both distributions,after that we can compute
规范化这两个分布,可以计算
KL_divergence P/=sum(P) Q/=sum(Q) result=KL_divergence(P,Q)
INT8 conv内核的伪代码
// I8 input tensors: I8_input,I8_weights,I8 output tensors: I8_output
// F32 bias (original bias from the F32 model)
// F32 scaling factors: input_scale,output_scale,weights_scale[K] I32_gemm_out=I8_input * I8_weights // Compute INT8 GEMM (DP4A)
F32_gemm_out=(float)
I32_gemm_out // Cast I32 GEMM output to F32 float
// At this point we have F32_gemm_out which is scaled by ( input_scale * weights_scale[K]),
// 要将最终结果存储在int8中,需要使scale等于“output_scale”,必须重新缩放:
// (this multiplication is done in F32,*_gemm_out arrays are in NCHW format)
For i in 0,... K-1:
rescaled_F32_gemm_out[:,i,:,:]=F32_gemm_out[:,i,:,:] * [output_scale/(input_scale * weights_scale[i])]
//添加bias偏差,要执行添加,必须重新缩放原始F32 bias,使用“输出_比例”进行缩放:
rescaled_F32_gemm_out _with_bias=rescaled_F32_gemm_out+output_scale * bias //
Perform ReLU (in F32)
F32_result=ReLU(rescaled_F32_gemm_out _with_bias)
//转换为INT8,保存为全局
I8_output=Saturate( Round_to_nearest_integer( F32_result))
Results - Performance - Pascal Titan X
TensorRT FP32 vs TensorRT INT8
Pascal TitanX
Results - Performance - DRIVE PX 2,dGPU
TensorRT FP32 vs TensorRT INT8
DRIVE PX 2,dGPU
参考链接:
https://on-demand.gputechconf.com/gtc/2017/presentation/s7310-8-bit-inference-with-tensorrt.pdf
标签:伟达,scale,Inference,校准,FP32,F32,bias,bit,INT8 来源: https://www.cnblogs.com/wujianming-110117/p/15554294.html