deeplearning量化

量化配置

通过字典配置量化参数

TENSORRT_OP_TYPES = [

'mul', 'conv2d', 'pool2d', 'depthwise_conv2d', 'elementwise_add',

'leaky_relu'

]

TRANSFORM_PASS_OP_TYPES = ['conv2d', 'depthwise_conv2d', 'mul']

QUANT_DEQUANT_PASS_OP_TYPES = [

"pool2d", "elementwise_add", "concat", "softmax", "argmax", "transpose",

"equal", "gather", "greater_equal", "greater_than", "less_equal",

"less_than", "mean", "not_equal", "reshape", "reshape2",

"bilinear_interp", "nearest_interp", "trilinear_interp", "slice",

"squeeze", "elementwise_sub", "relu", "relu6", "leaky_relu", "tanh", "swish"

]

_quant_config_default = {

# weight quantize type, default is 'channel_wise_abs_max'

'weight_quantize_type': 'channel_wise_abs_max',

# activation quantize type, default is 'moving_average_abs_max'

'activation_quantize_type': 'moving_average_abs_max',

# weight quantize bit num, default is 8

'weight_bits': 8,

# activation quantize bit num, default is 8

'activation_bits': 8,

# ops of name_scope in not_quant_pattern list, will not be quantized

'not_quant_pattern': ['skip_quant'],

# ops of type in quantize_op_types, will be quantized

'quantize_op_types': ['conv2d', 'depthwise_conv2d', 'mul'],

# data type after quantization, such as 'uint8', 'int8', etc. default is 'int8'

'dtype': 'int8',

# window size for 'range_abs_max' quantization. defaulf is 10000

'window_size': 10000,

# The decay coefficient of moving average, default is 0.9

'moving_rate': 0.9,

# if True, 'quantize_op_types' will be TENSORRT_OP_TYPES

'for_tensorrt': False,

# if True, 'quantoze_op_types' will be TRANSFORM_PASS_OP_TYPES + QUANT_DEQUANT_PASS_OP_TYPES

'is_full_quantize': False

}

参数:

  • weight_quantize_type(str) - 参数量化方式。可选 'abs_max' , 'channel_wise_abs_max' , 'range_abs_max' , 'moving_average_abs_max' 。如果使用 TensorRT 加载量化后的模型来预测,使用 'channel_wise_abs_max' 。 默认 'channel_wise_abs_max' 。
  • activation_quantize_type(str) - 激活量化方式,可选 'abs_max' , 'range_abs_max' , 'moving_average_abs_max' 。如果使用 TensorRT 加载量化后的模型来预测,使用 'range_abs_max', 'moving_average_abs_max' ,默认 'moving_average_abs_max' 。
  • weight_bits(int) - 参数量化bit数,默认8, 可选1-8,推荐设为8,因为量化后的数据类型是 int8 。
  • activation_bits(int) - 激活量化bit数,默认8,可选1-8,推荐设为8,因为量化后的数据类型是 int8 。
  • not_quant_pattern(str | list[str]) - 所有 name_scope 包含 'not_quant_pattern' 字符串的 op ,都不量化, 设置方式参考 fluid.name_scope 。
  • quantize_op_types(list[str]) - 需要进行量化的 op 类型,目前支持 'conv2d', 'depthwise_conv2d', 'mul' 。
  • dtype(int8) - 量化后的参数类型,默认 int8 , 目前仅支持 int8 。
  • window_size(int) - 'range_abs_max' 量化方式的 window size ,默认10000。
  • moving_rate(int) - 'moving_average_abs_max' 量化方式的衰减系数,默认 0.9。
  • for_tensorrt(bool) - 量化后的模型是否使用 TensorRT 进行预测。如果是的话,量化op类型为: TENSORRT_OP_TYPES 。默认值为False.
  • is_full_quantize(bool) - 是否量化所有可支持op类型。可量化op为 TRANSFORM_PASS_OP_TYPES + QUANT_DEQUANT_PASS_OP_TYPES 。 默认值为False.

quant_aware

paddleslim.quant.quant_aware(programplaceconfigscope=Nonefor_test=False)

在 program 中加入量化和反量化op, 用于量化训练。

参数:

  • program (fluid.Program) - 传入训练或测试program 。
  • place(fluid.CPUPlace | fluid.CUDAPlace) - 该参数表示 Executor 执行所在的设备。
  • config(dict) - 量化配置表。
  • scope(fluid.Scope, optional) - 传入用于存储 Variable 的 scope ,需要传入 program 所使用的 scope ,一般情况下,是 fluid.global_scope() 。设置为 None 时将使用 fluid.global_scope() ,默认值为 None 。
  • for_test(bool) - 如果 program 参数是一个测试 program , for_test 应设为True,否则设为False 。

返回

含有量化和反量化 operator 的 program 。

返回类型

  • 当 for_test=False ,返回类型为 fluid.CompiledProgram , 注意,此返回值不能用于保存参数 。
  • 当 for_test=True ,返回类型为 fluid.Program 。

注解

  • 此接口会改变program 结构,并且可能增加一些persistable的变量,所以加载模型参数时注意和相应的 program 对应。
  • 此接口底层经历了 fluid.Program -> fluid.framework.IrGraph -> fluid.Program 的转变,在 fluid.framework.IrGraph 中没有 Parameter 的概念,Variable 只有 persistable 和not persistable的区别,所以在保存和加载参数时,使用 fluid.io.save_persistables 和 fluid.io.load_persistables 接口。
  • 由于此接口会根据 program 的结构和量化配置来对program 添加op,所以 Paddle 中一些通过 fuse op 来加速训练的策略不能使用。已知以下策略在使用量化时必须设为False : fuse_all_reduce_ops, sync_batch_norm 。
  • 如果传入的 program 中存在和任何op都没有连接的 Variable ,则会在量化的过程中被优化掉。

convert

paddleslim.quant.convert(programplaceconfigscope=Nonesave_int8=False)

把训练好的量化 program ,转换为可用于保存 inference model 的 program 。

参数:

  • program (fluid.Program) - 传入测试 program 。
  • place(fluid.CPUPlace | fluid.CUDAPlace) - 该参数表示 Executor 执行所在的设备。
  • config(dict) - 量化配置表。
  • scope(fluid.Scope) - 传入用于存储 Variable 的 scope ,需要传入 program 所使用的 scope ,一般情况下,是 fluid.global_scope() 。设置为 None 时将使用 fluid.global_scope() ,默认值为 None 。
  • save_int8bool) - 是否需要返回参数为 int8 的 program 。该功能目前只能用于确认模型大小。默认值为 False 。

返回

  • program (fluid.Program) - freezed program,可用于保存inference model,参数为 float32 类型,但其数值范围可用int8表示。
  • int8_program (fluid.Program) - freezed program,可用于保存inference model,参数为 int8 类型。当 save_int8 为False 时,不返回该值。

注解

因为该接口会对 op 和 Variable 做相应的删除和修改,所以此接口只能在训练完成之后调用。如果想转化训练的中间模型,可加载相应的参数之后再使用此接口。

代码示例

#encoding=utf8

import paddle.fluid as fluid

import paddleslim.quant as quant

train_program = fluid.Program()

with fluid.program_guard(train_program):

image = fluid.data(name='x', shape=[None, 1, 28, 28])

label = fluid.data(name='label', shape=[None, 1], dtype='int64')

conv = fluid.layers.conv2d(image, 32, 1)

feat = fluid.layers.fc(conv, 10, act='softmax')

cost = fluid.layers.cross_entropy(input=feat, label=label)

avg_cost = fluid.layers.mean(x=cost)

use_gpu = True

place = fluid.CUDAPlace(0) if use_gpu else fluid.CPUPlace()

exe = fluid.Executor(place)

exe.run(fluid.default_startup_program())

eval_program = train_program.clone(for_test=True)

#配置

config = {'weight_quantize_type': 'abs_max',

'activation_quantize_type': 'moving_average_abs_max'}

build_strategy = fluid.BuildStrategy()

exec_strategy = fluid.ExecutionStrategy()

#调用api

quant_train_program = quant.quant_aware(train_program, place, config, for_test=False)

quant_eval_program = quant.quant_aware(eval_program, place, config, for_test=True)

#关闭策略

build_strategy.fuse_all_reduce_ops = False

build_strategy.sync_batch_norm = False

quant_train_program = quant_train_program.with_data_parallel(

loss_name=avg_cost.name,

build_strategy=build_strategy,

exec_strategy=exec_strategy)

inference_prog = quant.convert(quant_eval_program, place, config)

更详细的用法参考 量化训练demo 。

quant_post

paddleslim.quant.quant_post(executor, model_dir, quantize_model_path,sample_generator, model_filename=None, params_filename=None, batch_size=16,batch_nums=None, scope=None, algo='KL', quantizable_op_type=["conv2d", "depthwise_conv2d", "mul"], is_full_quantize=False, weight_bits=8, activation_bits=8, is_use_cache_file=False, cache_dir="./temp_post_training")

对保存在 ${model_dir} 下的模型进行量化,使用 sample_generator 的数据进行参数校正。

参数:

  • executor (fluid.Executor) - 执行模型的executor,可以在cpu或者gpu上执行。
  • model_dirstr) - 需要量化的模型所在的文件夹。
  • quantize_model_path(str) - 保存量化后的模型的路径
  • sample_generator(python generator) - 读取数据样本,每次返回一个样本。
  • model_filename(str, optional) - 模型文件名,如果需要量化的模型的参数存在一个文件中,则需要设置 model_filename 为模型文件的名称,否则设置为 None 即可。默认值是 None 。
  • params_filename(str) - 参数文件名,如果需要量化的模型的参数存在一个文件中,则需要设置 params_filename 为参数文件的名称,否则设置为 None 即可。默认值是 None 。
  • batch_size(int) - 每个batch的图片数量。默认值为16 。
  • batch_nums(int, optional) - 迭代次数。如果设置为 None ,则会一直运行到 sample_generator 迭代结束, 否则,迭代次数为 batch_nums, 也就是说参与对 Scale 进行校正的样本个数为 'batch_nums' * 'batch_size' .
  • scope(fluid.Scope, optional) - 用来获取和写入 Variable , 如果设置为 None ,则使用 fluid.global_scope() . 默认值是 None .
  • algo(str) - 量化时使用的算法名称,可为 'KL' 或者 'direct' 。该参数仅针对激活值的量化,因为参数值的量化使用的方式为 'channel_wise_abs_max' . 当 algo 设置为 'direct' 时,使用校正数据的激活值的绝对值的最大值当作 Scale 值,当设置为 'KL' 时,则使用KL散度的方法来计算 Scale 值。默认值为 'KL' 。
  • quantizable_op_type(list[str]) - 需要量化的 op 类型列表。默认值为 ["conv2d", "depthwise_conv2d", "mul"] 。
  • is_full_quantize(bool) - 是否量化所有可支持的op类型。如果设置为False, 则按照 'quantizable_op_type' 的设置进行量化。如果设置为True, 则按照 量化配置 中 QUANT_DEQUANT_PASS_OP_TYPES + QUANT_DEQUANT_PASS_OP_TYPES 定义的op进行量化。
  • weight_bits(int) - weight的量化比特位数, 默认值为8。
  • activation_bits(int) - 激活值的量化比特位数, 默认值为8。
  • is_use_cache_file(bool) - 是否使用硬盘对中间结果进行存储。如果为False, 则将中间结果存储在内存中。默认值为False。
  • cache_dir(str) - 如果 'is_use_cache_file' 为True, 则将中间结果存储在此参数设置的路径下。默认值为 ./temp_post_training 。

返回

无。

注解

  • 因为该接口会收集校正数据的所有的激活值,当校正图片比较多时,设置 'is_use_cache_file' 为True, 将中间结果存储在硬盘中。另外,'KL' 散度的计算比较耗时。
  • 目前 Paddle-Lite 有int8 kernel来加速的op只有 ['conv2d', 'depthwise_conv2d', 'mul'] , 其他op的int8 kernel将陆续支持。

代码示例

警告

此示例不能直接运行,因为需要加载 ${model_dir} 下的模型,所以不能直接运行。

import paddle.fluid as fluid

import paddle.dataset.mnist as reader

from paddleslim.quant import quant_post

val_reader = reader.train()

use_gpu = True

place = fluid.CUDAPlace(0) if use_gpu else fluid.CPUPlace()

exe = fluid.Executor(place)

quant_post(

executor=exe,

model_dir='./model_path',

quantize_model_path='./save_path',

sample_generator=val_reader,

model_filename='__model__',

params_filename='__params__',

batch_size=16,

batch_nums=10)

quant_embedding

paddleslim.quant.quant_embedding(programplaceconfigscope=None)

对 Embedding 参数进行量化。

参数:

  • program(fluid.Program) - 需要量化的program
  • scope(fluid.Scope, optional) - 用来获取和写入 Variable, 如果设置为 None,则使用 fluid.global_scope() .
  • place(fluid.CPUPlace | fluid.CUDAPlace) - 运行program的设备
  • config(dict) - 定义量化的配置。可以配置的参数有:
    • 'params_name' (str, required): 需要进行量化的参数名称,此参数必须设置。
    • 'quantize_type' (str, optional): 量化的类型,目前支持的类型是 'abs_max', 待支持的类型有 'log', 'product_quantization' 。 默认值是 'abs_max' .
    • 'quantize_bits' (int, optional): 量化的bit数,目前支持的bit数为8。默认值是8.
    • 'dtype' (str, optional): 量化之后的数据类型, 目前支持的是 'int8'. 默认值是 int8 。
    • 'threshold' (float, optional): 量化之前将根据此阈值对需要量化的参数值进行 clip. 如果不设置,则跳过 clip 过程直接量化。

返回

量化之后的program

返回类型

fluid.Program

代码示例

import paddle.fluid as fluid

import paddleslim.quant as quant

train_program = fluid.Program()

with fluid.program_guard(train_program):

input_word = fluid.data(name="input_word", shape=[None, 1], dtype='int64')

input_emb = fluid.embedding(

input=input_word,

is_sparse=False,

size=[100, 128],

param_attr=fluid.ParamAttr(name='emb',

initializer=fluid.initializer.Uniform(-0.005, 0.005)))

infer_program = train_program.clone(for_test=True)

use_gpu = True

place = fluid.CUDAPlace(0) if use_gpu else fluid.CPUPlace()

exe = fluid.Executor(place)

exe.run(fluid.default_startup_program())

config = {'params_name': 'emb', 'quantize_type': 'abs_max'}

quant_program = quant.quant_embedding(infer_program, place, config)

deeplearning量化的更多相关文章

  1. deeplearning模型量化实战

    deeplearning模型量化实战 MegEngine 提供从训练到部署完整的量化支持,包括量化感知训练以及训练后量化,凭借"训练推理一体"的特性,MegEngine更能保证量化 ...

  2. tensorflow模型量化

    tensorflow模型量化/DATA/share/DeepLearning/code/tensorflow/bazel-bin/tensorflow/tools/graph_transforms/t ...

  3. deeplearning算法优化原理

    deeplearning算法优化原理目录· 量化原理介绍 · 剪裁原理介绍 · 蒸馏原理介绍 · 轻量级模型结构搜索原理介绍 1. Quantization Aware Training量化介绍1.1 ...

  4. deeplearning模型库

    deeplearning模型库 1. 图像分类 数据集:ImageNet1000类 1.1  量化 分类模型Lite时延(ms) 设备 模型类型 压缩策略 armv7 Thread 1 armv7 T ...

  5. Atitit  图像处理Depixelizing Pixel Art像素风格画的矢量化

    Atitit  图像处理Depixelizing Pixel Art像素风格画的矢量化 在去年的时候,偶然看到hqx算法. 一个高质量的插值放大算法. 与双线性插值等插值算法相比,这个算法放大后对人眼 ...

  6. 《量化投资:以MATLAB为工具》连载(2)基础篇-N分钟学会MATLAB(中)

    http://www.matlabsky.com/thread-43937-1-1.html   <量化投资:以MATLAB为工具>连载(3)基础篇-N分钟学会MATLAB(下)     ...

  7. 《量化投资:以MATLAB为工具》连载(1)基础篇-N分钟学会MATLAB(上)

    http://blog.sina.com.cn/s/blog_4cf8aad30102uylf.html <量化投资:以MATLAB为工具>连载(1)基础篇-N分钟学会MATLAB(上) ...

  8. 矢量化的HTML5拓扑图形组件设计

    HT一直被客户称道的就是其全矢量化的设计特色,矢量相比传统图片好处太多了: www.hightopo.com/guide/guide/core/vector/ht-vector-guide.html ...

  9. K-means算法和矢量量化

    语音信号的数字处理课程作业——矢量量化.这里采用了K-means算法,即假设量化种类是已知的,当然也可以采用LBG算法等,不过K-means比较简单.矢量是二维的,可以在平面上清楚的表示出来. 1. ...

随机推荐

  1. 【Nginx(四)】Nginx配置集群 负载均衡策略

    1.Nginx常见的负载均衡策略 ip_hash (固定分发) 简介:根据请求按访问ip的hash结果分配,这样每个用户就可以固定访问一个后端服务器 场景:服务器业务分区.业务缓存.Session需要 ...

  2. hdu1466 递推

    题意:       给你n条直线,不会存在三线共点,输出所有的可能交点数.. 思路:       这个是个地推的题目,假设当前的线段i,他里面有r条是随意的,有(i - r)条是平行的,那么当前的交点 ...

  3. 【原创】Centos8安装ansible

    1.安装步骤 # 安装epel扩展源 dnf install https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rp ...

  4. Msfvenonm生成一个后门木马

    在前一篇文章中我讲了什么是Meterpreter,并且讲解了Meterpreter的用法.传送门-->Metasploit之Meterpreter 今天我要讲的是我们用Msfvenom制作一个木 ...

  5. Portswigger web security academy:Reflected XSS

    Portswigger web security academy:Reflected XSS 目录 Portswigger web security academy:Reflected XSS Ref ...

  6. WPF之数据绑定基类

    数据绑定方法 在使用集合类型作为列表控件的ItemsSource时一般会考虑使用ObservalbeCollection,它实现了INotifyCollectionChanged和INotifyPro ...

  7. vue的快速入门【IDEA版本】

    和vscode相比,使用IDEA进行前端开发并没有那么容易,需要先进行配置 . 安装vue插件,重启idea 鼠标右键添加vue component 点击 file 打开设置 settings,展开 ...

  8. 想要测试Dubbo接口?测试的关键点在哪里?

    Dubbo接口如何测试? 这个dubbo如何测试,dubbo接口测试什么玩意儿?   RPC的有一个类型,叫Dubbo接口. 那这个接口如何测试?测试的关键点在哪里? 这个面试问题,我觉得大家可能就有 ...

  9. c语言编程学习之二维数组

    二维数组 c语言按照行主序存储二维数组.也就是说,二维数组元素在内存中的位置是连续的,每行末尾元素(若不是最后一行)的下一个元素就是下一行的首元素. 如下图所示 接下来我们来分析一下如何将二维数组所有 ...

  10. Asp.NetCore Web开发之Nlog日志配置

    接着讲基于ASP .net Core 的web开发,这节主要讲一下如何使用和配置Nlog进行日志记录. 日志在开发中的作用是很重要的,使用日志,程序出了错误可以及时捕获并记录下来,开发人员可以通过日志 ...