|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461 |
-
- # 目录
-
- <!-- TOC -->
-
- - [目录](#目录)
- - [TinyBERT概述](#tinybert概述)
- - [模型架构](#模型架构)
- - [数据集](#数据集)
- - [环境要求](#环境要求)
- - [快速入门](#快速入门)
- - [脚本说明](#脚本说明)
- - [脚本和样例代码](#脚本和样例代码)
- - [脚本参数](#脚本参数)
- - [一般蒸馏](#一般蒸馏)
- - [任务蒸馏](#任务蒸馏)
- - [选项及参数](#选项及参数)
- - [选项](#选项)
- - [参数](#参数)
- - [训练流程](#训练流程)
- - [用法](#用法)
- - [Ascend处理器上运行](#ascend处理器上运行)
- - [在GPU处理器上运行](#在gpu处理器上运行)
- - [分布式训练](#分布式训练)
- - [Ascend处理器上运行](#ascend处理器上运行-1)
- - [GPU处理器上运行](#gpu处理器上运行)
- - [评估过程](#评估过程)
- - [用法](#用法-1)
- - [基于SST-2数据集进行评估](#基于sst-2数据集进行评估)
- - [基于MNLI数据集进行评估](#基于mnli数据集进行评估)
- - [基于QNLI数据集进行评估](#基于qnli数据集进行评估)
- - [模型描述](#模型描述)
- - [性能](#性能)
- - [评估性能](#评估性能)
- - [推理性能](#推理性能)
- - [随机情况说明](#随机情况说明)
- - [ModelZoo主页](#modelzoo主页)
-
- <!-- /TOC -->
-
- # TinyBERT概述
-
- 从推理角度看,[TinyBERT](https://github.com/huawei-noah/Pretrained-Language-Model/tree/master/TinyBERT)比[BERT-base](https://github.com/google-research/bert)(BERT模型基础版本)体积小了7.5倍、速度快了9.4倍,自然语言理解的性能表现更突出。TinyBert在预训练和任务学习两个阶段创新采用了转换蒸馏。
-
- [论文](https://arxiv.org/abs/1909.10351): Xiaoqi Jiao, Yichun Yin, Lifeng Shang, Xin Jiang, Xiao Chen, Linlin Li, Fang Wang, Qun Liu. [TinyBERT: Distilling BERT for Natural Language Understanding](https://arxiv.org/abs/1909.10351). arXiv preprint arXiv:1909.10351.
-
- # 模型架构
-
- TinyBERT模型的主干结构是转换器,转换器包含四个编码器模块,其中一个为自注意模块。一个自注意模块即为一个注意模块。
-
- # 数据集
-
- - 生成通用蒸馏阶段数据集
- - 下载[zhwiki](https://dumps.wikimedia.org/zhwiki/)或[enwiki](https://dumps.wikimedia.org/enwiki/)数据集进行预训练,
- - 使用[WikiExtractor](https://github.com/attardi/wikiextractor)提取和整理数据集中的文本,使用步骤如下:
- - pip install wikiextractor
- - python -m wikiextractor.WikiExtractor -o <output file path> -b <output file size> <Wikipedia dump file>
- - 将数据集转换为TFRecord格式。详见[BERT](https://github.com/google-research/bert)代码仓中的create_pretraining_data.py文件,同时下载对应的vocab.txt文件, 如果出现AttributeError: module 'tokenization' has no attribute 'FullTokenizer’,请安装bert-tensorflow。
- - 生成下游任务蒸馏阶段数据集
- - 下载数据集进行微调和评估,如[GLUE](https://github.com/nyu-mll/GLUE-baselines)
- - 将数据集文件从JSON格式转换为TFRecord格式。详见[BERT](https://github.com/google-research/bert)代码仓中的run_classifier.py文件。
-
- # 环境要求
-
- - 硬件(Ascend或GPU)
- - 使用Ascend或GPU处理器准备硬件环境。
- - 框架
- - [MindSpore](https://gitee.com/mindspore/mindspore)
- - 更多关于Mindspore的信息,请查看以下资源:
- - [MindSpore教程](https://www.mindspore.cn/tutorial/training/zh-CN/master/index.html)
- - [MindSpore Python API](https://www.mindspore.cn/doc/api_python/zh-CN/master/index.html)
-
- # 快速入门
-
- 从官网下载安装MindSpore之后,可以开始一般蒸馏。任务蒸馏和评估方法如下:
-
- ```bash
- # 单机运行一般蒸馏示例
- bash scripts/run_standalone_gd.sh
-
- Before running the shell script, please set the `load_teacher_ckpt_path`, `data_dir`, `schema_dir` and `dataset_type` in the run_standalone_gd.sh file first. If running on GPU, please set the `device_target=GPU`.
-
- # Ascend设备上分布式运行一般蒸馏示例
- bash scripts/run_distributed_gd_ascend.sh 8 1 /path/hccl.json
-
- Before running the shell script, please set the `load_teacher_ckpt_path`, `data_dir`, `schema_dir` and `dataset_type` in the run_distributed_gd_ascend.sh file first.
-
- # GPU设备上分布式运行一般蒸馏示例
- bash scripts/run_distributed_gd_gpu.sh 8 1 /path/data/ /path/schema.json /path/teacher.ckpt
-
- # 运行任务蒸馏和评估示例
- bash scripts/run_standalone_td.sh
-
- Before running the shell script, please set the `task_name`, `load_teacher_ckpt_path`, `load_gd_ckpt_path`, `train_data_dir`, `eval_data_dir`, `schema_dir` and `dataset_type` in the run_standalone_td.sh file first.
- If running on GPU, please set the `device_target=GPU`.
- ```
-
- 若在Ascend设备上运行分布式训练,请提前创建JSON格式的HCCL配置文件。
- 详情参见如下链接:
- https:gitee.com/mindspore/mindspore/tree/master/model_zoo/utils/hccl_tools.
-
- 如需设置数据集格式和参数,请创建JSON格式的视图配置文件,详见[TFRecord](https://www.mindspore.cn/doc/programming_guide/zh-CN/master/dataset_loading.html#tfrecord) 格式。
-
- ```text
- For general task, schema file contains ["input_ids", "input_mask", "segment_ids"].
-
- For task distill and eval phase, schema file contains ["input_ids", "input_mask", "segment_ids", "label_ids"].
-
- `numRows` is the only option which could be set by user, the others value must be set according to the dataset.
-
- For example, the dataset is cn-wiki-128, the schema file for general distill phase as following:
- {
- "datasetType": "TF",
- "numRows": 7680,
- "columns": {
- "input_ids": {
- "type": "int64",
- "rank": 1,
- "shape": [256]
- },
- "input_mask": {
- "type": "int64",
- "rank": 1,
- "shape": [256]
- },
- "segment_ids": {
- "type": "int64",
- "rank": 1,
- "shape": [256]
- }
- }
- }
- ```
-
- # 脚本说明
-
- ## 脚本和样例代码
-
- ```shell
- .
- └─bert
- ├─README.md
- ├─scripts
- ├─run_distributed_gd_ascend.sh # Ascend设备上分布式运行一般蒸馏的shell脚本
- ├─run_distributed_gd_gpu.sh # GPU设备上分布式运行一般蒸馏的shell脚本
- ├─run_standalone_gd.sh # 单机运行一般蒸馏的shell脚本
- ├─run_standalone_td.sh # 单机运行任务蒸馏的shell脚本
- ├─src
- ├─__init__.py
- ├─assessment_method.py # 评估过程的测评方法
- ├─dataset.py # 数据处理
- ├─gd_config.py # 一般蒸馏阶段的参数配置
- ├─td_config.py # 任务蒸馏阶段的参数配置
- ├─tinybert_for_gd_td.py # 网络骨干编码
- ├─tinybert_model.py # 网络骨干编码
- ├─utils.py # util函数
- ├─__init__.py
- ├─run_general_distill.py # 一般蒸馏训练网络
- ├─run_task_distill.py # 任务蒸馏训练评估网络
- ```
-
- ## 脚本参数
-
- ### 一般蒸馏
-
- ```text
- 用法:run_general_distill.py [--distribute DISTRIBUTE] [--epoch_size N] [----device_num N] [--device_id N]
- [--device_target DEVICE_TARGET] [--do_shuffle DO_SHUFFLE]
- [--enable_data_sink ENABLE_DATA_SINK] [--data_sink_steps N]
- [--save_ckpt_path SAVE_CKPT_PATH]
- [--load_teacher_ckpt_path LOAD_TEACHER_CKPT_PATH]
- [--save_checkpoint_step N] [--max_ckpt_num N]
- [--data_dir DATA_DIR] [--schema_dir SCHEMA_DIR] [--dataset_type DATASET_TYPE] [train_steps N]
-
- 选项:
- --device_target 代码实现设备,可选项为Ascend或CPU。默认为Ascend
- --distribute 是否多卡预训练,可选项为true(多卡预训练)或false。默认为false
- --epoch_size 轮次,默认为1
- --device_id 设备ID,默认为0
- --device_num 使用设备数量,默认为1
- --save_ckpt_path 保存检查点文件的路径,默认为""
- --max_ckpt_num 保存检查点文件的最大数,默认为1
- --do_shuffle 是否使能轮换,可选项为true或false,默认为true
- --enable_data_sink 是否使能数据下沉,可选项为true或false,默认为true
- --data_sink_steps 设置数据下沉步数,默认为1
- --save_checkpoint_step 保存检查点文件的步数,默认为1000
- --load_teacher_ckpt_path 加载检查点文件的路径,默认为""
- --data_dir 数据目录,默认为""
- --schema_dir schema.json的路径,默认为""
- --dataset_type 数据集类型,可选项为tfrecord或mindrecord,默认为tfrecord
- ```
-
- ### 任务蒸馏
-
- ```text
- usage: run_general_task.py [--device_target DEVICE_TARGET] [--do_train DO_TRAIN] [--do_eval DO_EVAL]
- [--td_phase1_epoch_size N] [--td_phase2_epoch_size N]
- [--device_id N] [--do_shuffle DO_SHUFFLE]
- [--enable_data_sink ENABLE_DATA_SINK] [--save_ckpt_step N]
- [--max_ckpt_num N] [--data_sink_steps N]
- [--load_teacher_ckpt_path LOAD_TEACHER_CKPT_PATH]
- [--load_gd_ckpt_path LOAD_GD_CKPT_PATH]
- [--load_td1_ckpt_path LOAD_TD1_CKPT_PATH]
- [--train_data_dir TRAIN_DATA_DIR]
- [--eval_data_dir EVAL_DATA_DIR]
- [--task_name TASK_NAME] [--schema_dir SCHEMA_DIR] [--dataset_type DATASET_TYPE]
-
- options:
- --device_target 代码实现设备,可选项为Ascend或CPU。默认为Ascend
- --do_train 是否使能训练任务,可选项为true或false,默认为true
- --do_eval 是否使能评估任务,可选项为true或false,默认为true
- --td_phase1_epoch_size td phase1的epoch size大小,默认为10
- --td_phase2_epoch_size td phase2的epoch size大小,默认为3
- --device_id 设备ID,默认为0
- --do_shuffle 是否使能轮换,可选项为true或false,默认为true
- --enable_data_sink 是否使能数据下沉,可选项为true或false,默认为true
- --save_ckpt_step 保存检查点文件的步数,默认为1000
- --max_ckpt_num 保存的检查点文件的最大数,默认为1
- --data_sink_steps 设置数据下沉步数,默认为1
- --load_teacher_ckpt_path 加载teacher检查点文件的路径,默认为""
- --load_gd_ckpt_path 加载通过一般蒸馏生成的检查点文件的路径,默认为""
- --load_td1_ckpt_path 加载通过任务蒸馏阶段1生成的检查点文件的路径,默认为""
- --train_data_dir 训练数据集目录,默认为""
- --eval_data_dir 评估数据集目录,默认为""
- --task_name 分类任务,可选项为SST-2、QNLI、MNLI,默认为""
- --schema_dir schema.json的路径,默认为""
- --dataset_type 数据集类型,可选项为tfrecord或mindrecord,默认为tfrecord
- ```
-
- ## 选项及参数
-
- `gd_config.py` and `td_config.py` 包含BERT模型参数与优化器和损失缩放选项。
-
- ### 选项
-
- ```text
- batch_size 输入数据集的批次大小,默认为16
- Parameters for lossscale:
- loss_scale_value 损失放大初始值,默认为
- scale_factor 损失放大的更新因子,默认为2
- scale_window 损失放大的一次更新步数,默认为50
-
- Parameters for optimizer:
- learning_rate 学习率
- end_learning_rate 结束学习率,取值需为正数
- power 幂
- weight_decay 权重衰减
- eps 增加分母,提高小数稳定性
- ```
-
- ### 参数
-
- ```text
- Parameters for bert network:
- seq_length 输入序列的长度,默认为128
- vocab_size 各内嵌向量大小,需与所采用的数据集相同。默认为30522
- hidden_size BERT的encoder层数
- num_hidden_layers 隐藏层数
- num_attention_heads 注意头的数量,默认为12
- intermediate_size 中间层数
- hidden_act 所采用的激活函数,默认为gelu
- hidden_dropout_prob BERT输出的随机失活可能性
- attention_probs_dropout_prob BERT注意的随机失活可能性
- max_position_embeddings 序列最大长度,默认为512
- save_ckpt_step 保存检查点数量,默认为100
- max_ckpt_num 保存检查点最大数量,默认为1
- type_vocab_size 标记类型的词汇表大小,默认为2
- initializer_range TruncatedNormal的初始值,默认为0.02
- use_relative_positions 是否采用相对位置,可选项为true或false,默认为False
- dtype 输入的数据类型,可选项为mstype.float16或mstype.float32,默认为mstype.float32
- compute_type Bert Transformer的计算类型,可选项为mstype.float16或mstype.float32,默认为mstype.float16
- ```
-
- ## 训练流程
-
- ### 用法
-
- #### Ascend处理器上运行
-
- 运行以下命令前,确保已设置load_teacher_ckpt_path、data_dir和schma_dir。请将路径设置为绝对全路径,例如/username/checkpoint_100_300.ckpt。
-
- ```bash
- bash scripts/run_standalone_gd.sh
- ```
-
- 以上命令后台运行,您可以在log.txt文件中查看运行结果。训练结束后,您可以在默认脚本文件夹中找到检查点文件。得到如下损失值:
-
- ```text
- # grep "epoch" log.txt
- epoch: 1, step: 100, outputs are (Tensor(shape=[1], dtype=Float32, 28.2093), Tensor(shape=[], dtype=Bool, False), Tensor(shape=[], dtype=Float32, 65536))
- epoch: 2, step: 200, outputs are (Tensor(shape=[1], dtype=Float32, 30.1724), Tensor(shape=[], dtype=Bool, False), Tensor(shape=[], dtype=Float32, 65536))
- ...
- ```
-
- > **注意**训练过程中会根据`device_num`和处理器总数绑定处理器内核。如果您不希望预训练中绑定处理器内核,请在scripts/run_distributed_gd_ascend.sh脚本中移除相关操作。
-
- #### 在GPU处理器上运行
-
- 运行以下命令前,确保已设置load_teacher_ckpt_path、data_dir、schma_dir和device_target=GPU。请将路径设置为绝对全路径,例如/username/checkpoint_100_300.ckpt。
-
- ```bash
- bash scripts/run_standalone_gd.sh
- ```
-
- 以上命令后台运行,您可以在log.txt文件中查看运行结果。训练结束后,您可以在默认脚本路径下脚本文件夹中找到检查点文件。得到如下损失值:
-
- ```text
- # grep "epoch" log.txt
- epoch: 1, step: 100, outputs are 28.2093
- ...
- ```
-
- ### 分布式训练
-
- #### Ascend处理器上运行
-
- 运行以下命令前,确保已设置load_teacher_ckpt_path、data_dir和schma_dir。请将路径设置为绝对全路径,例如/username/checkpoint_100_300.ckpt。
-
- ```bash
- bash scripts/run_distributed_gd_ascend.sh 8 1 /path/hccl.json
- ```
-
- 以上命令后台运行,您可以在log.txt文件中查看运行结果。训练后,可以得到默认log*文件夹路径下的检查点文件。 得到如下损失值:
-
- ```text
- # grep "epoch" LOG*/log.txt
- epoch: 1, step: 100, outputs are (Tensor(shape=[1], dtype=Float32, 28.1478), Tensor(shape=[], dtype=Bool, False), Tensor(shape=[], dtype=Float32, 65536))
- ...
- epoch: 1, step: 100, outputs are (Tensor(shape=[1], dtype=Float32, 30.5901), Tensor(shape=[], dtype=Bool, False), Tensor(shape=[], dtype=Float32, 65536))
- ...
- ```
-
- #### GPU处理器上运行
-
- 输入绝对全路径,例如:"/username/checkpoint_100_300.ckpt"。
-
- ```bash
- bash scripts/run_distributed_gd_gpu.sh 8 1 /path/data/ /path/schema.json /path/teacher.ckpt
- ```
-
- 以上命令后台运行,您可以在log.txt文件中查看运行结果。训练结束后,您可以在默认LOG*文件夹下找到检查点文件。得到如下损失值:
-
- ```text
- # grep "epoch" LOG*/log.txt
- epoch: 1, step: 1, outputs are 63.4098
- ...
- ```
-
- ## 评估过程
-
- ### 用法
-
- 如需运行后继续评估,请设置`do_train=true`和`do_eval=true`;如需单独运行评估,请设置`do_train=false`和`do_eval=true`。如需在GPU处理器上运行,请设置`device_target=GPU`。
-
- #### 基于SST-2数据集进行评估
-
- ```bash
- bash scripts/run_standalone_td.sh
- ```
-
- 以上命令后台运行,您可以在log.txt文件中查看运行结果。得出如下测试数据集准确率:
-
- ```bash
- # grep "The best acc" log.txt
- The best acc is 0.872685
- The best acc is 0.893515
- The best acc is 0.899305
- ...
- The best acc is 0.902777
- ...
- ```
-
- #### 基于MNLI数据集进行评估
-
- 运行如下命令前,请确保已设置加载与训练检查点路径。请将检查点路径设置为绝对全路径,例如,/username/pretrain/checkpoint_100_300.ckpt。
-
- ```bash
- bash scripts/run_standalone_td.sh
- ```
-
- 以上命令将在后台运行,请在log.txt文件中查看结果。测试数据集的准确率如下:
-
- ```text
- # grep "The best acc" log.txt
- The best acc is 0.803206
- The best acc is 0.803308
- The best acc is 0.810355
- ...
- The best acc is 0.813929
- ...
- ```
-
- #### 基于QNLI数据集进行评估
-
- 运行如下命令前,请确保已设置加载与训练检查点路径。请将检查点路径设置为绝对全路径,例如/username/pretrain/checkpoint_100_300.ckpt。
-
- ```bash
- bash scripts/run_standalone_td.sh
- ```
-
- 以上命令后台运行,您可以在log.txt文件中查看运行结果。测试数据集的准确率如下:
-
- ```text
- # grep "The best acc" log.txt
- The best acc is 0.870772
- The best acc is 0.871691
- The best acc is 0.875183
- ...
- The best acc is 0.891176
- ...
- ```
-
- ## 模型描述
-
- ## 性能
-
- ### 评估性能
-
- | 参数 | Ascend | GPU |
- | -------------------------- | ---------------------------------------------------------- | ------------------------- |
- | 模型版本 | TinyBERT | TinyBERT |
- | 资源 | Ascend 910;cpu 2.60GHz,192核;内存 755G;系统 Euler2.8 | NV SMX2 V100-32G, cpu:2.10GHz 64核, 内存:251G |
- | 上传日期 | 2020-08-20 | 2020-08-24 |
- | MindSpore版本 | 0.6.0 | 0.7.0 |
- | 数据集 | en-wiki-128 | en-wiki-128 |
- | 训练参数 | src/gd_config.py | src/gd_config.py |
- | 优化器| AdamWeightDecay | AdamWeightDecay |
- | 损耗函数 | SoftmaxCrossEntropy | SoftmaxCrossEntropy |
- | 输出 | 概率 | 概率 |
- | 损失 | 6.541583 | 6.6915 |
- | 速度 | 35.4毫秒/步 | 98.654毫秒/步 |
- | 总时长 | 17.3 小时 (3轮, 8卡) | 48小时 (3轮, 8卡) |
- | 参数 (M) | 15分钟 | 15分钟 |
- | 任务蒸馏检查点| 74M(.ckpt 文件) | 74M(.ckpt 文件) |
-
- #### 推理性能
-
- | 参数 | Ascend | GPU |
- | -------------------------- | ----------------------------- | ------------------------- |
- | 模型版本 | | |
- | 资源 | Ascend 910;系统 Euler2.8 | NV SMX2 V100-32G |
- | 上传日期 | 2020-08-20 | 2020-08-24 |
- | MindSpore版本 | 0.6.0 | 0.7.0 |
- | 数据集 | SST-2, | SST-2 |
- | batch_size | 32 | 32 |
- | 准确率 | 0.902777 | 0.9086 |
- | 速度 | | |
- | 总时长 | | |
- | 推理模型 | 74M(.ckpt 文件) | 74M(.ckpt 文件) |
-
- # 随机情况说明
-
- run_standaloned_td.sh脚本中设置了do_shuffle来轮换数据集。
-
- gd_config.py和td_config.py文件中设置了hidden_dropout_prob和attention_pros_dropout_prob,使网点随机失活。
-
- run_general_distill.py文件中设置了随机种子,确保分布式训练初始权重相同。
-
- # ModelZoo主页
-
- 请浏览官网[主页](https://gitee.com/mindspore/mindspore/tree/master/model_zoo)。
|