README.md 5.6 KB
Newer Older
I
itminner 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149
# 在线量化示例

本示例介绍如何使用在线量化接口,来对训练好的分类模型进行量化, 可以减少模型的存储空间和显存占用。

## 接口介绍
```
quant_config_default = {
    'weight_quantize_type': 'abs_max',
    'activation_quantize_type': 'abs_max',
    'weight_bits': 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', 'elementwise_add', 'pool2d'],
    # 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 set quant_weight_only True, then only quantize parameters of layers which need to be quantized,
    # and activations will not be quantized.
    'quant_weight_only': False
}
```
量化配置表。
参数说明:
- weight_quantize_type(str): 参数量化方式。可选'abs_max',  'channel_wise_abs_max', 'range_abs_max', 'moving_average_abs_max',默认'abs_max'。
- activation_quantize_type(str): 激活量化方式,可选'abs_max', 'range_abs_max', 'moving_average_abs_max',默认'abs_max'。
- weight_bits(int): 参数量化bit数,默认8。
- activation_bits(int): 激活量化bit数,默认8。
- not_quant_pattern(str or str list): 所有name_scope包含not_quant_pattern字符串的op,都不量化。
- quantize_op_types(str of list): 需要进行量化的op类型。
- dtype(int8): 量化后的参数类型,默认int8。
- window_size(int): 'range_abs_max'量化的window size,默认10000。
- moving_rate(int): moving_average_abs_max 量化的衰减系数,默认 0.9。
- quant_weight_only(bool): 是否只量化参数,如果设为True,则激活不进行量化,默认False。
```
def quant_aware(program, 
                place, 
                config,
                scope=None, 
                for_test=False)
```
该接口会对传入的program插入可训练量化op。
参数介绍:
- program (fluid.program): 传入训练或测试program。
- place(fluid.CPUPlace or fluid.CUDAPlace(N): 该参数表示Executor执行所在的设备,这里的N为GPU对应的ID。
- config(dict): 量化配置表。
- scope(fluid.Scope): 传入用于存储var的scope,需要传入program所使用的scope,一般情况下,是fluid.global_scope()。
- for_test(bool): 如果program参数是一个测试用program,for_test应设为True,否则设为False。

返回参数:
-  program(fluid.Program): 插入量化op后的program。
   注意:如果for_test为False,这里返回的program是compiled program。

```
def convert(program, 
            place, 
            config, 
            scope=None, 
            save_int8=False)
```
把训练好的量化program,转换为可用于保存inference model的program。
注意,本接口返回的program,不可用于训练。
参数介绍:
- program (fluid.program): 传入测试program。
- place(fluid.CPUPlace or fluid.CUDAPlace(N): 该参数表示Executor执行所在的设备,这里的N为GPU对应的ID。
- config(dict): 量化配置表。
- -scope(fluid.Scope): 传入用于存储var的scope,需要传入program所使用的scope,一般情况下,是fluid.global_scope()。
- save_int8(bool): 是否需要导出参数为int8的program。

返回参数:
- program (fluid.program): freezed program,可用于保存inference model,参数为float32类型,但其数值范围可用int8表示。
- int8_program (fluid.program): freezed program,可用于保存inference model,参数为int8类型。


## 分类模型的离线量化流程

### 1. 配置量化参数

```
quant_config = {
    'weight_quantize_type': 'abs_max',
    'activation_quantize_type': 'moving_average_abs_max',
    'weight_bits': 8,
    'activation_bits': 8,
    'not_quant_pattern': ['skip_quant'],
    'quantize_op_types': ['conv2d', 'depthwise_conv2d', 'mul'],
    'dtype': 'int8',
    'window_size': 10000,
    'moving_rate': 0.9,
    'quant_weight_only': False
}
```

### 2. 对训练和测试program插入可训练量化op

```
val_program = quant_aware(val_program, place, quant_config, scope=None, for_test=True)

compiled_train_prog = quant_aware(train_prog, place, quant_config, scope=None, for_test=False)
```

###3.关掉指定build策略
```
build_strategy = fluid.BuildStrategy()
build_strategy.memory_optimize = False
build_strategy.enable_inplace = False
build_strategy.fuse_all_reduce_ops = False
build_strategy.sync_batch_norm = False
exec_strategy = fluid.ExecutionStrategy()
compiled_train_prog = compiled_train_prog.with_data_parallel(
        loss_name=avg_cost.name,
        build_strategy=build_strategy,
        exec_strategy=exec_strategy)
```
###4. freeze program
```
float_program, int8_program = convert(val_program, 
                                      place,
                                      quant_config,
                                      scope=None,
                                      save_int8=True)
```
###5.保存预测模型
```
fluid.io.save_inference_model(
    dirname=float_path,
    feeded_var_names=[image.name],
    target_vars=[out], executor=exe,
    main_program=float_program,
    model_filename=float_path + '/model',
    params_filename=float_path + '/params')

fluid.io.save_inference_model(
    dirname=int8_path,
    feeded_var_names=[image.name],
    target_vars=[out], executor=exe,
    main_program=int8_program,
    model_filename=int8_path + '/model',
    params_filename=int8_path + '/params')
```