2
2
3
3
BERT-base模型是一个迁移能力很强的通用语义表示模型,但是模型中也有一些参数冗余。本教程将介绍如何使用PaddleSlim对BERT-base模型进行压缩。
4
4
5
+ ## 压缩原理
6
+
7
+ 1 . 对Fine-tuning得到模型通过计算参数及其梯度的乘积得到参数的重要性,把模型参数根据重要性进行重排序。
8
+ 2 . 超网络中最大的子网络选择和Bert-base模型网络结构一致的网络结构,其他小的子网络是对最大网络的进行不同的宽度选择来得到的,宽度选择具体指的是网络中的参数进行裁剪,所有子网络在整个训练过程中都是参数共享的。
9
+ 2 . 用重排序之后的模型参数作为超网络模型的初始化参数。
10
+ 3 . Fine-tuning之后的模型作为教师网络,超网络作为学生网络,进行知识蒸馏。
11
+
12
+ <p align =" center " >
13
+ <img src =" ./imgs/ofa_bert.jpg " width =" 950 " /><br />
14
+ 整体流程图
15
+ </p >
16
+
17
+
5
18
## 压缩结果
6
19
7
- 基于 ` bert-base-uncased ` 在GLUE dev数据集上的finetune结果进行压缩。压缩后模型精度和压缩前模型在GLUE dev数据集上的精度对比如下表所示:
20
+ 利用 ` bert-base-uncased ` 模型首先在GLUE数据集上进行finetune,得到需要压缩的模型,之后基于此模型进行压缩。压缩后模型参数大小减小26%(从110M减少到81M),压缩后模型在GLUE dev数据集上的精度和压缩前模型在GLUE dev数据集上的精度对比如下表所示:
8
21
9
22
| Task | Metric | Result | Result with PaddleSlim |
10
23
| :-----:| :----------------------------:| :-----------------:| :----------------------:|
@@ -17,13 +30,173 @@ BERT-base模型是一个迁移能力很强的通用语义表示模型,但是
17
30
| MNLI | Matched acc/MisMatched acc | 0.84422/0.84825 | 0.84687/0.85242 |
18
31
| RTE | Accuracy | 0.711191 | 0.718412 |
19
32
20
- 压缩后模型相比压缩前加速约59%(测试环境: T4, FP32, batch_size=16),模型参数大小减小26%(从110M减少到81M)。
33
+ <p align =" center " >
34
+ <strong >表1-1: GLUE数据集精度对比</strong >
35
+ </p >
36
+
37
+ 压缩前后模型的耗时如下表所示:
38
+
39
+ <table style =" width :100% ;" cellpadding =" 2 " cellspacing =" 0 " border =" 1 " bordercolor =" #000000 " >
40
+ <tbody>
41
+ <tr>
42
+ <td style="text-align:center">
43
+ <span style="font-size:18px;">Device</span>
44
+ </td>
45
+ <td style="text-align:center">
46
+ <span style="font-size:18px;">Batch Size</span>
47
+ </td>
48
+ <td style="text-align:center">
49
+ <span style="font-size:18px;">Model</span>
50
+ </td>
51
+ <td style="text-align:center">
52
+ <span style="font-size:18px;">TRT(FP16)</span>
53
+ </td>
54
+ <td style="text-align:center;">
55
+ <span style="font-size:18px;">Latency(ms)</span>
56
+ </td>
57
+ </tr>
58
+ <tr>
59
+ <td rowspan=8 align=center> T4 </td>
60
+ <td rowspan=4 align=center> 16 </td>
61
+ <td rowspan=2 align=center> BERT </td>
62
+ <td style="text-align:center">
63
+ <span style="font-size:18px">N</span>
64
+ </td>
65
+ <td style="text-align:center">
66
+ <span style="font-size:18px">110.71</span>
67
+ </td>
68
+ </tr>
69
+ <tr>
70
+ <td style="text-align:center">
71
+ <span style="font-size:18px">Y</span>
72
+ </td>
73
+ <td style="text-align:center">
74
+ <span style="font-size:18px">22.0</span>
75
+ </td>
76
+ </tr>
77
+ <tr>
78
+ <td rowspan=2 align=center>Compressed BERT </td>
79
+ <td style="text-align:center">
80
+ <span style="font-size:18px">N</span>
81
+ </td>
82
+ <td style="text-align:center">
83
+ <span style="font-size:18px">69.62</span>
84
+ </td>
85
+ </tr>
86
+ <tr>
87
+ <td style="text-align:center">
88
+ <span style="font-size:18px">Y</span>
89
+ </td>
90
+ <td style="text-align:center">
91
+ <span style="font-size:18px">14.93</span>
92
+ </td>
93
+ </tr>
94
+ <tr>
95
+ <td rowspan=4 align=center> 40 </td>
96
+ <td rowspan=2 align=center> BERT </td>
97
+ <td style="text-align:center">
98
+ <span style="font-size:18px">N</span>
99
+ </td>
100
+ <td style="text-align:center">
101
+ <span style="font-size:18px">252.78</span>
102
+ </td>
103
+ </tr>
104
+ <tr>
105
+ <td style="text-align:center">
106
+ <span style="font-size:18px">Y</span>
107
+ </td>
108
+ <td style="text-align:center">
109
+ <span style="font-size:18px">53.67</span>
110
+ </td>
111
+ </tr>
112
+ <tr>
113
+ <td rowspan=2 align=center>Compressed BERT </td>
114
+ <td style="text-align:center">
115
+ <span style="font-size:18px">N</span>
116
+ </td>
117
+ <td style="text-align:center">
118
+ <span style="font-size:18px">168.71</span>
119
+ </td>
120
+ </tr>
121
+ <tr>
122
+ <td style="text-align:center">
123
+ <span style="font-size:18px">Y</span>
124
+ </td>
125
+ <td style="text-align:center">
126
+ <span style="font-size:18px">37.22</span>
127
+ </td>
128
+ </tr>
129
+ <tr>
130
+ <td rowspan=2 align=center> V100 </td>
131
+ <td rowspan=2 align=center> 16 </td>
132
+ <td style="text-align:center">
133
+ <span style="font-size:18px;" align=center>BERT</span>
134
+ </td>
135
+ <td style="text-align:center">
136
+ <span style="font-size:18px">N</span>
137
+ </td>
138
+ <td style="text-align:center">
139
+ <span style="font-size:18px">33.28</span>
140
+ </td>
141
+ </tr>
142
+ <tr>
143
+ <td style="text-align:center">
144
+ <span style="font-size:18px;">Compressed BERT</span>
145
+ </td>
146
+ <td style="text-align:center">
147
+ <span style="font-size:18px">N</span>
148
+ </td>
149
+ <td style="text-align:center">
150
+ <span style="font-size:18px">21.83</span>
151
+ </td>
152
+ </tr>
153
+ <tr>
154
+ <td rowspan=2 align=center> Intel(R) Xeon(R) Gold 5117 CPU @ 2.00GHz </td>
155
+ <td rowspan=2 align=center> 16 </td>
156
+ <td style="text-align:center">
157
+ <span style="font-size:18px;" align=center>BERT</span>
158
+ </td>
159
+ <td style="text-align:center">
160
+ <span style="font-size:18px">N</span>
161
+ </td>
162
+ <td style="text-align:center">
163
+ <span style="font-size:18px">10831.73</span>
164
+ </td>
165
+ </tr>
166
+ <tr>
167
+ <td style="text-align:center">
168
+ <span style="font-size:18px;">Compressed BERT</span>
169
+ </td>
170
+ <td style="text-align:center">
171
+ <span style="font-size:18px">N</span>
172
+ </td>
173
+ <td style="text-align:center">
174
+ <span style="font-size:18px">7682.93</span>
175
+ </td>
176
+ </tr>
177
+ </tbody>
178
+ </table >
179
+ <br />
180
+ <p align =" center " >
181
+ <strong >表1-2: 模型速度对比</strong >
182
+ </p >
183
+
184
+ 压缩后模型在T4机器上相比原始模型在FP32的情况下加速59%,在TensorRT FP16的情况下加速47.3%。
185
+ 压缩后模型在V100机器上相比原始模型在FP32的情况下加速52.5%。
186
+ 压缩后模型在Intel(R) Xeon(R) Gold 5117 CPU上相比原始模型在FP32的情况下加速41%。
21
187
22
188
## 快速开始
23
189
本教程示例以GLUE/SST-2 数据集为例。
24
190
191
+ ### 环境依赖
192
+
193
+ 模型压缩功能依赖最新版本的PaddleNLP和PaddleSlim.
194
+ ``` shell
195
+ pip install paddleslim==2.0.0 -i https://pypi.org/simple
196
+ ```
197
+
25
198
### Fine-tuing
26
- 首先需要对Pretrain-Model在实际的下游任务上进行Finetuning,得到需要压缩的模型。
199
+ 首先需要对Pretrain-Model在实际的下游任务上进行Finetuning,得到需要压缩的模型。Fine-tuning流程参考 [ Fine-tuning教程 ] ( ../../benchmark/glue )
27
200
28
201
``` shell
29
202
cd ../../benchmark/glue/
@@ -47,14 +220,8 @@ python -u ./run_glue.py \
47
220
-- n_gpu 1 \
48
221
```
49
222
参数详细含义参考[README .md](../ ../ benchmark/ glue/ README .md)
50
- Fine- tuning 在dev上的结果如压缩结果表格中Result那一列所示。
51
-
52
- # ## 环境依赖
223
+ Fine- tuning 在dev上的结果如压缩结果表1 - 1 中Result那一列所示。
53
224
54
- 模型压缩功能依赖最新版本的PaddleNLP和PaddleSlim.
55
- ```shell
56
- pip install paddleslim== 2.0 .0 - i https:// pypi.org/ simple
57
- ```
58
225
59
226
# ## 压缩训练
60
227
@@ -71,6 +238,7 @@ python -u ./run_glue_ofa.py --model_type bert \
71
238
-- n_gpu 1 \
72
239
-- width_mult_list 1.0 0.8333333333333334 0.6666666666666666 0.5
73
240
```
241
+
74
242
其中参数释义如下:
75
243
- ` model_type ` 指示了模型类型,当前仅支持BERT模型。
76
244
- ` model_name_or_path ` 指示了某种特定配置的模型,对应有其预训练模型和预训练时使用的 tokenizer。若模型相关内容保存在本地,这里也可以提供相应目录地址。
@@ -85,19 +253,54 @@ python -u ./run_glue_ofa.py --model_type bert \
85
253
- ` n_gpu ` 表示使用的 GPU 卡数。若希望使用多卡训练,将其设置为指定数目即可;若为0,则使用CPU。
86
254
- ` width_mult_list ` 表示压缩训练过程中,对每层Transformer Block的宽度选择的范围。
87
255
88
- 压缩训练之后在dev上的结果如压缩结果表格中Result with PaddleSlim那一列所示,速度相比原始模型加速59% 。
256
+ 压缩训练之后在dev上的结果如压缩结果表格中Result with PaddleSlim那一列所示,延时情况如表1-2所示 。
89
257
90
- ## 压缩原理
91
258
92
- 1 . 对Fine-tuning得到模型通过计算参数及其梯度的乘积得到参数的重要性,把模型参数根据重要性进行重排序。
93
- 2 . 超网络中最大的子网络选择和Bert-base模型网络结构一致的网络结构,其他小的子网络是对最大网络的进行不同的宽度选择来得到的,宽度选择具体指的是网络中的参数进行裁剪,所有子网络在整个训练过程中都是参数共享的。
94
- 2 . 用重排序之后的模型参数作为超网络模型的初始化参数。
95
- 3 . Fine-tuning之后的模型作为教师网络,超网络作为学生网络,进行知识蒸馏。
259
+ ### 导出子模型
260
+ 根据传入的config导出相应的子模型并转为静态图模型。
261
+
262
+ 启动命令:
263
+
264
+ ``` shell
265
+ python -u ./export_model.py --model_type bert \
266
+ --model_name_or_path ${PATH_OF_MODEL_AFTER_OFA} \
267
+ --max_seq_length 128 \
268
+ --sub_model_output_dir ./tmp/$TASK_NAME /dynamic_model \
269
+ --static_sub_model ./tmp/$TASK_NAME /static_model \
270
+ --n_gpu 1 \
271
+ --width_mult 0.6666666666666666
272
+ ```
273
+
274
+ 其中参数释义如下:
275
+ - ` model_type ` 指示了模型类型,当前仅支持BERT模型。
276
+ - ` model_name_or_path ` 指示了某种特定配置的经过OFA训练后保存的模型,对应有其预训练模型和预训练时使用的tokenizer。若模型相关内容保存在本地,这里也可以提供相应目录地址。
277
+ - ` max_seq_length ` 表示最大句子长度,超过该长度将被截断。默认:128.
278
+ - ` sub_model_output_dir ` 指示了导出子模型动态图参数的目录。
279
+ - ` static_sub_model ` 指示了导出子模型静态图模型及参数的目录,设置为None,则表示不导出静态图模型。默认:None。
280
+ - ` n_gpu ` 表示使用的 GPU 卡数。若希望使用多卡训练,将其设置为指定数目即可;若为0,则使用CPU。默认:1.
281
+ - ` width_mult ` 表示导出子模型的宽度。默认:1.0.
282
+
283
+
284
+ ### OFA接口介绍
285
+
286
+ OFA API介绍参考[ API] ( https://github.com/PaddlePaddle/PaddleSlim/blob/release/2.0.0/docs/zh_cn/api_cn/dygraph/ofa/ofa_api.rst )
287
+
288
+ ## 另附:基于本代码对TinyBERT(L=4, D=312)进行压缩
289
+ 下游任务模型是从TinyBERT官方repo转换得到。
290
+
291
+ ### 压缩结果
292
+
293
+ | Task | Metric | TinyBERT(L=4, D=312) | Result with OFA |
294
+ | :-----:| :----------------------------:| :--------------------:| :----------------------:|
295
+ | SST-2 | Accuracy | [ 0.9234] ( ) | [ 0.9220] ( ) |
296
+ | QNLI | Accuracy | [ 0.8746] ( ) | [ 0.8720] ( ) |
297
+ | CoLA | Mattehew's corr | [ 0.4961] ( ) | [ 0.5048] ( ) |
298
+ | MRPC | F1/Accuracy | [ 0.8998/0.8554] ( ) | [ 0.9003/0.8578] ( ) |
299
+ | STS-B | Person/Spearman corr | [ 0.8635/0.8631] ( ) | [ 0.8717/0.8706] ( ) |
300
+ | QQP | Accuracy/F1 | [ 0.9047/0.8751] ( ) | [ 0.9034/0.8733] ( ) |
301
+ | MNLI | Matched acc/MisMatched acc | [ 0.8256/0.8294] ( ) | [ 0.8211/0.8261] ( ) |
302
+ | RTE | Accuracy | [ 0.6534] ( ) | [ 0.6787] ( ) |
96
303
97
- <p align =" center " >
98
- <img src =" ./imgs/ofa_bert.jpg " width =" 950 " /><br />
99
- 整体流程图
100
- </p >
101
304
102
305
## 参考论文
103
306
0 commit comments