【模型推理】量化实现分享三:详解 ACIQ 对称量化算法实现

大家好,我是极智视界,本文剖析一下ACIQ 对称量化算法实现,以 Tengine 的实现为例。

这是量化实现的第三篇,前面还有一、二,有兴趣的同学可以查阅

(1) 《【模型推理】量化实现分享一:详解 min-max 对称量化算法实现》;

(2)《【模型推理】量化实现分享二:详解 KL 对称量化算法实现》;

ACIQ 和前面的量化策略类似,也是会截取一个阈值 T,然后将 [-T, T] 映射到量化值域,不同的是寻找 T 的过程,本文不止讲原理,也结合 tengine 讲讲量化策略的实现。下面开始。

1、ACIQ 量化策略原理

ACIQ 量化策略在论文《Post training 4-bit quantization of convolutional networks for rapid-deployment》中被提出,先贴一下效果:

image

上图比对统一采用 8-bit 权值量化、4-bit 激活值量化,在量化效率上 ACIQ 比 KL 量化过程快 4000 倍(unbelievable~),在量化精度上,可以看到除了 resnet-101,其他测试的网络量化效果均好于 KL 量化,可以说是效率和效果一个也不落。

在文章的一开始,作者就写道 Unlike traditional approaches that focus on the quantization at the network level, in this work we propose to minimize the quantization effect at the tensor level. 可以看出 ACIQ 是从 Tensor 级别出发的量化策略,整个推导逻辑主要是:

(1) first, derive a generic expression for any given distribution for the expected MSE as a function of clipping value;

(2) then use this expression to develop a specifific expression for each distribution;

(3) finally, establish the optimal clipping values by solving the equations for which the derivative with respect to the clipping value are set to zero;

通常在量化的时候需要做裁剪,以应对原始数据的长尾问题,假设 α 为截断值,截断可以表示为:

image

ACIQ 需要一个较强先验假设:Tensor (feature map) 服从拉普拉斯分布或高斯分布,然后采用最优化思想求解量化过程截断值对应的最小量化损失,整个量化过程是将服从原始分布的值映射到 2^M量化离散值域,M 为量化比特数,意思是将上面的 [-α, α] 的值域等分给 2^M,如下图:

image

假设原始分布的概率密度函数为 f(x),截断值 α 以及量化函数 Q(x),则量化前后的 L2 Loss 可以这么计算:

image

以上算式很明显可以分为三个部分:

(1) [负无穷, -α];

(2) [-α, α];

(3) [α, 正无穷];

对于高斯分布N(0, σ^2) 或者 拉普拉斯分布 Laplace(0, b)) 这种 0 轴对称分布来说,(1) 和 (3) 是等价的,含义是 |x| 到 |α| 之间的均方误差 (mean-square-error)。在做 [-α, α] 等分映射到 2^M 后,每个量化值会取每段中间的值 q1、q2、q3 ... q2^M,第 (2) 项就是中间截断的累计误差。现在整个量化过程转化为求一个使 E[(X - Q(X))^2] 最小的截断值 α (深度学习到最后都是数学问题啊~),然后再结合先验分布,做一些公式的等价变换变换~之后,得到最终的整体量化损失优化目标函数:

image

数学上,要求目标函数的最小值 ==> 求偏导,令其为 0。

对于拉普拉斯分布来说,求偏导后的表达式为:

image

对于高斯分布来说,求偏导后的表达式为:

image

最后不管对于拉普拉斯分布还是高斯分布来说,M 是你想量化的比特位,还有像 β (拉普拉斯分布参数)、σ (高斯分布参数) 这些都是已知值,自然可以求出我们想要的截断值 α 了,对于对称量化来说有了截断值就 ok 了。

2、ACIQ 量化策略实现

下面来看 ACIQ 在 tengine 中的实现。

量化实现主要代码:

case ALGORITHM_ACIQ:{
 if (quant_tool.scale_file.empty()){
 quant_tool.scale_file = "table_aciq.scale";
 quant_tool.activation_quant_tool();
 }
 save_graph_i8_perchannel(quant_tool.model_file.c_str(), quant_tool.scale_file.c_str(), quant_tool.output_file, quant_tool.inplace, false);
 /* Evaluate quantitative losses */
 if (quant_tool.evaluate){
 fprintf(stderr, "[Quant Tools Info]: Step Evaluate, evaluate quantitative losses\n");
 quant_tool.assess_quant_loss(0);
 }
 break;
}

2.1 激活值量化

激活值量化入口:

quant_tool.activation_quant_tool();

首先就是求 min、max 值,这个过程和前面写过的量化策略是一样的逻辑,就不多说了,接着进 ACIQ 策略:

for (int i = 0; i < ir_graph->tensor_num; i++){
 struct tensor* t = ir_graph->tensor_list[i];
 if (t->tensor_type == TENSOR_TYPE_VAR || t->tensor_type == TENSOR_TYPE_INPUT){
 float absmax = 0.f;
 float act_scale = 1.f;
 int act_zero_point = 0;
 int emlement_num = t->elem_num;

 absmax = std::max(std::abs(max_activation[i]), std::abs(min_activation[i]));
 float threshold = compute_aciq_gaussian_clip(absmax, emlement_num, 8);
 act_scale = threshold / 127.f;

 /* the scale of softmax is always scale = 1 / 127.f */
 for (int j = 0; j < ir_graph->node_num; j++){
 struct node* noden = ir_graph->node_list[j];
 struct tensor* tensor_tmp = get_ir_graph_tensor(ir_graph, noden->output_tensors[0]);

 if (!(tensor_tmp->tensor_type == TENSOR_TYPE_INPUT || tensor_tmp->tensor_type == TENSOR_TYPE_VAR))
 continue;

 std::string tmp_op_name = get_op_name_from_type(noden->op.type);
 std::string cur_name = t->name;
 std::string tmp_name = tensor_tmp->name;

 if ((cur_name == tmp_name) && tmp_op_name == "Softmax"){
 act_scale = 1 / 127.f;
 break;}
 }
 fprintf(fp_aciq, "%s %f %d\n", ir_graph->tensor_list[i]->name, act_scale, act_zero_point);}
}

关键是这个函数,tengine 里默认先验服从高斯分布, int8 量化:

float threshold = compute_aciq_gaussian_clip(absmax, emlement_num, 8);

来看一下它的实现:

static float compute_aciq_gaussian_clip(float absmax, int N, int num_bits)
{
 const float alpha_gaussian[8] = {0, 1.71063519, 2.15159277, 2.55913646, 2.93620062, 3.28691474, 3.6151146, 3.92403714};   // 当8-bit量化时,α=3.92403714

 const double gaussian_const = (0.5 * 0.35) * (1 + sqrt(3.14159265358979323846 * log(4))); 

 double std = (absmax * 2 * gaussian_const) / sqrt(2 * log(N));

 return (float)(alpha_gaussian[num_bits - 1] * std);
}

这样就得到了截断值,然后就可以求 scale 了:

act_scale = threshold / 127.f;

这样就完成了激活值的量化。

2.2 权值&偏置量化

权值&偏置的量化过程和前面介绍过的 MIN-MAX 和 KL 量化的逻辑一样,这里不再赘述。

最后实践一下,可以发现 ACIQ 的量化过程十分的快,比 KL 量化快 4000 倍不是瞎说的,主要是源于先验的高斯分布 alpha_gaussian、gaussian_const、std 这些值不需要进行搜索。

image

以上分享了 ACIQ 的量化原理和实现,希望我的分享能对你的学习有一点帮助。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,874评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,102评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,676评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,911评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,937评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,935评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,860评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,660评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,113评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,363评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,506评论 1 346
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,238评论 5 341
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,861评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,486评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,674评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,513评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,426评论 2 352

推荐阅读更多精彩内容