6
6
* [ Step1:获取模型压缩参数 compression_args] ( #获取模型压缩参数compression_args )
7
7
* [ Step2:实例化 Trainer 并调用 compress()] ( #实例化Trainer并调用compress() )
8
8
* [ Trainer 实例化参数介绍] ( #Trainer实例化参数介绍 )
9
- * [ Step3:实现自定义评估函数和 loss 计算函数 (按需可选)] ( #实现自定义评估函数和loss计算函数 (按需可选) )
9
+ * [ Step3:实现自定义评估函数 (按需可选)] ( #实现自定义评估函数 (按需可选) )
10
10
* [ Step4:传参并运行压缩脚本] ( #传参并运行压缩脚本 )
11
11
* [ CompressionArguments 参数介绍] ( #CompressionArguments参数介绍 )
12
12
* [ 三大场景模型压缩 API 使用示例] ( #三大场景模型压缩API使用示例 )
@@ -118,11 +118,45 @@ compression_args = parser.parse_args_into_dataclasses()
118
118
#### Trainer 实例化参数介绍
119
119
120
120
- ** --model** 待压缩的模型,目前支持 ERNIE、BERT、RoBERTa、ERNIE-M、ELECTRA、ERNIE-Gram、PP-MiniLM、TinyBERT 等结构相似的模型,是在下游任务中微调后的模型,当预训练模型选择 ERNIE 时,需要继承 ` ErniePretrainedModel ` 。以分类任务为例,可通过` AutoModelForSequenceClassification.from_pretrained(model_name_or_path) ` 等方式来获取,这种情况下,` model_name_or_path ` 目录下需要有 model_config.json, model_state.pdparams 文件;
121
- - ** --data_collator** 三类任务均可使用 PaddleNLP 预定义好的 [ DataCollator 类] ( ../../ paddlenlp/data/data_collator.py ) ,` data_collator ` 可对数据进行 ` Pad ` 等操作。使用方法参考 [ 示例代码] ( ../model_zoo/ernie-3.0/compress_seq_cls.py ) 即可;
121
+ - ** --data_collator** 三类任务均可使用 PaddleNLP 预定义好的 [ DataCollator 类] ( ../paddlenlp/data/data_collator.py ) ,` data_collator ` 可对数据进行 ` Pad ` 等操作。使用方法参考 [ 示例代码] ( ../model_zoo/ernie-3.0/compress_seq_cls.py ) 即可;
122
122
- ** --train_dataset** 裁剪训练需要使用的训练集,是任务相关的数据。自定义数据集的加载可参考 [ 文档] ( https://huggingface.co/docs/datasets/loading ) 。不启动裁剪时,可以为 None;
123
123
- ** --eval_dataset** 裁剪训练使用的评估集,也是量化使用的校准数据,是任务相关的数据。自定义数据集的加载可参考 [ 文档] ( https://huggingface.co/docs/datasets/loading ) 。是 Trainer 的必选参数;
124
124
- ** --tokenizer** 模型 ` model ` 对应的 ` tokenizer ` ,可使用 ` AutoTokenizer.from_pretrained(model_name_or_path) ` 来获取。
125
- - ** --criterion** 模型的 loss 对象,是一个 nn.Layer 对象,用于在 ofa_utils.py 计算模型的 loss 用于计算梯度从而确定神经元重要程度。
125
+ - ** --criterion** 模型的 loss 计算方法,可以是一个 nn.Layer 对象,也可以是一个函数,用于在 ofa_utils.py 计算模型的 loss 用于计算梯度从而确定神经元重要程度。
126
+
127
+ 其中,` criterion ` 函数定义示例:
128
+
129
+ ``` python
130
+ # 支持的形式一:
131
+ def criterion (logits , labels ):
132
+ loss_fct = paddle.nn.BCELoss()
133
+ start_ids, end_ids = labels
134
+ start_prob, end_prob = outputs
135
+ start_ids = paddle.cast(start_ids, ' float32' )
136
+ end_ids = paddle.cast(end_ids, ' float32' )
137
+ loss_start = loss_fct(start_prob, start_ids)
138
+ loss_end = loss_fct(end_prob, end_ids)
139
+ loss = (loss_start + loss_end) / 2.0
140
+ return loss
141
+
142
+ # 支持的形式二:
143
+ class CrossEntropyLossForSQuAD (paddle .nn .Layer ):
144
+
145
+ def __init__ (self ):
146
+ super (CrossEntropyLossForSQuAD, self ).__init__ ()
147
+
148
+ def forward (self , y , label ):
149
+ start_logits, end_logits = y
150
+ start_position, end_position = label
151
+ start_position = paddle.unsqueeze(start_position, axis = - 1 )
152
+ end_position = paddle.unsqueeze(end_position, axis = - 1 )
153
+ start_loss = paddle.nn.functional.cross_entropy(input = start_logits,
154
+ label = start_position)
155
+ end_loss = paddle.nn.functional.cross_entropy(input = end_logits,
156
+ label = end_position)
157
+ loss = (start_loss + end_loss) / 2
158
+ return loss
159
+ ```
126
160
127
161
用以上参数实例化 Trainer 对象,之后直接调用 ` compress() ` 。` compress() ` 会根据选择的策略进入不同的分支,以进行裁剪或者量化的过程。
128
162
@@ -147,11 +181,11 @@ trainer = Trainer(
147
181
trainer.compress()
148
182
```
149
183
150
- <a name =" 实现自定义评估函数和loss计算函数( 按需可选)" ></a >
184
+ <a name =" 实现自定义评估函数( 按需可选)" ></a >
151
185
152
- ### Step3:实现自定义评估函数和 loss 计算函数(按需可选) ,以适配自定义压缩任务
186
+ ### Step3:实现自定义评估函数 ,以适配自定义压缩任务
153
187
154
- 当使用 DynaBERT 裁剪功能时,如果模型、Metrics 不符合下表的情况,那么模型压缩 API 中自带的评估函数和计算 loss 的参数可能需要自定义 。
188
+ 当使用 DynaBERT 裁剪功能时,如果模型、Metrics 不符合下表的情况,那么模型压缩 API 中评估函数需要自定义 。
155
189
156
190
目前 DynaBERT 裁剪功能只支持 SequenceClassification 等三类 PaddleNLP 内置 class,并且内置评估器对应为 Accuracy、F1、Squad。
157
191
@@ -163,33 +197,26 @@ trainer.compress()
163
197
164
198
- 如果模型是自定义模型,需要继承 ` XXXPretrainedModel ` ,例如当预训练模型选择 ERNIE 时,继承 ` ErniePretrainedModel ` ,模型需要支持调用 ` from_pretrained() ` 导入模型,且只含 ` pretrained_model_name_or_path ` 一个必选参数,` forward ` 函数返回 ` logits ` 或者 ` tuple of logits ` ;
165
199
166
- - 如果模型是自定义模型,或者数据集比较特殊,压缩 API 中 loss 的计算不符合使用要求,需要自定义 ` custom_dynabert_calc_loss ` 函数。计算 loss 后计算梯度,从而得出计算神经元的重要性以便裁剪使用。可参考下方示例代码。
167
- - 输入每个 batch 的数据,返回模型的 loss。
168
- - 将该函数传入 ` compress() ` 中的 ` custom_dynabert_calc_loss ` 参数;
169
-
170
- - 如果评估器也不满足上述所支持情况,需实现自定义 ` custom_dynabert_evaluate ` 评估函数,需要同时支持 ` paddleslim.nas.ofa.OFA ` 模型和 ` paddle.nn.layer ` 模型。可参考下方示例代码。
200
+ - 如果模型是自定义模型,或者数据集比较特殊,压缩 API 中 loss 的计算不符合使用要求,需要自定义 ` custom_evaluate ` 评估函数,需要同时支持 ` paddleslim.nas.ofa.OFA ` 模型和 ` paddle.nn.layer ` 模型。可参考下方示例代码。
171
201
- 输入` model ` 和 ` dataloader ` ,返回模型的评价指标(单个 float 值)。
172
- - 将该函数传入 ` compress() ` 中的 ` custom_dynabert_evaluate ` 参数;
202
+ - 将该函数传入 ` compress() ` 中的 ` custom_evaluate ` 参数;
173
203
174
- ` custom_dynabert_evaluate ()` 函数定义示例:
204
+ ` custom_evaluate ()` 函数定义示例:
175
205
176
206
``` python
177
207
import paddle
178
208
from paddle.metric import Accuracy
179
- from paddleslim.nas.ofa import OFA
180
209
181
210
@paddle.no_grad ()
182
- def evaluate_seq_cls (model , data_loader ):
211
+ def evaluate_seq_cls (self , model , data_loader ):
183
212
metric = Accuracy()
184
213
model.eval()
185
214
metric.reset()
186
215
for batch in data_loader:
187
216
logits = model(input_ids = batch[' input_ids' ],
188
- token_type_ids = batch[' token_type_ids' ],
189
- # 必须写这一行
190
- attention_mask = [None , None ])
217
+ token_type_ids = batch[' token_type_ids' ])
191
218
# Supports paddleslim.nas.ofa.OFA model and nn.layer model.
192
- if isinstance (model, OFA ):
219
+ if isinstance (model, paddleslim.nas.ofa. OFA ):
193
220
logits = logits[0 ]
194
221
correct = metric.compute(logits, batch[' labels' ])
195
222
metric.update(correct)
@@ -199,22 +226,11 @@ trainer.compress()
199
226
return res
200
227
```
201
228
202
- ` custom_dynabert_calc_loss ` 函数定义示例:
203
229
204
- ``` python
205
- def calc_loss (loss_fct , model , batch , head_mask ):
206
- logits = model(input_ids = batch[" input_ids" ],
207
- token_type_ids = batch[" token_type_ids" ],
208
- # 必须写下面这行
209
- attention_mask = [None , head_mask])
210
- loss = loss_fct(logits, batch[" labels" ])
211
- return loss
212
- ```
213
- 在调用 ` compress() ` 时传入这 2 个自定义函数:
230
+ 在调用 ` compress() ` 时传入这个自定义函数:
214
231
215
232
``` python
216
- trainer.compress(custom_dynabert_evaluate = evaluate_seq_cls,
217
- custom_dynabert_calc_loss = calc_loss)
233
+ trainer.compress(custom_evaluate = evaluate_seq_cls)
218
234
```
219
235
220
236
@@ -253,8 +269,8 @@ python compress.py \
253
269
254
270
公共参数中的参数和具体的压缩策略无关。
255
271
256
- - ** --strategy** 模型压缩策略,目前支持 ` 'dynabert+ptq' ` 、 ` 'dynabert' ` 和 ` 'ptq' ` 。
257
- 其中 ` 'dynabert' ` 代表基于 DynaBERT 的宽度裁剪策略,` 'ptq' ` 表示静态离线量化, ` 'dynabert+ptq' ` 代表先裁剪后量化。默认是 ` 'dynabert+ptq' ` ;
272
+ - ** --strategy** 模型压缩策略,目前支持 ` 'dynabert+ptq' ` 、 ` 'dynabert' ` 、 ` 'ptq' ` 和 ` 'qat '` 。
273
+ 其中 ` 'dynabert' ` 代表基于 DynaBERT 的宽度裁剪策略,` 'ptq' ` 表示静态离线量化, ` 'dynabert+ptq' ` 代表先裁剪后量化。` qat ` 表示量化训练。 默认是 ` 'dynabert+ptq' ` ;
258
274
259
275
- ** --output_dir** 模型压缩后模型保存目录;
260
276
@@ -387,7 +403,7 @@ python compress_qa.py \
387
403
388
404
### Paddle2ONNX 部署
389
405
390
- ONNX 导出及 ONNXRuntime 部署请参考:[ ONNX 导出及 ONNXRuntime 部署指南] ( ./deploy/paddle2onnx/README.md )
406
+ ONNX 导出及 ONNXRuntime 部署请参考:[ ONNX 导出及 ONNXRuntime 部署指南] ( ../model_zoo/ernie-3.0 /deploy/paddle2onnx/README.md )
391
407
392
408
393
409
### Paddle Lite 移动端部署
0 commit comments