You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

README_CN.md 22 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454
  1. # 目录
  2. <!-- TOC -->
  3. - [目录](#目录)
  4. - [TinyBERT概述](#tinybert概述)
  5. - [模型架构](#模型架构)
  6. - [数据集](#数据集)
  7. - [环境要求](#环境要求)
  8. - [快速入门](#快速入门)
  9. - [脚本说明](#脚本说明)
  10. - [脚本和样例代码](#脚本和样例代码)
  11. - [脚本参数](#脚本参数)
  12. - [一般蒸馏](#一般蒸馏)
  13. - [任务蒸馏](#任务蒸馏)
  14. - [选项及参数](#选项及参数)
  15. - [选项](#选项)
  16. - [参数](#参数)
  17. - [训练流程](#训练流程)
  18. - [用法](#用法)
  19. - [Ascend处理器上运行](#ascend处理器上运行)
  20. - [在GPU处理器上运行](#在gpu处理器上运行)
  21. - [分布式训练](#分布式训练)
  22. - [Ascend处理器上运行](#ascend处理器上运行-1)
  23. - [GPU处理器上运行](#gpu处理器上运行)
  24. - [评估过程](#评估过程)
  25. - [用法](#用法-1)
  26. - [基于SST-2数据集进行评估](#基于sst-2数据集进行评估)
  27. - [基于MNLI数据集进行评估](#基于mnli数据集进行评估)
  28. - [基于QNLI数据集进行评估](#基于qnli数据集进行评估)
  29. - [模型描述](#模型描述)
  30. - [性能](#性能)
  31. - [评估性能](#评估性能)
  32. - [推理性能](#推理性能)
  33. - [随机情况说明](#随机情况说明)
  34. - [ModelZoo主页](#modelzoo主页)
  35. <!-- /TOC -->
  36. # TinyBERT概述
  37. 从推理角度看,[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在预训练和任务学习两个阶段创新采用了转换蒸馏。
  38. [论文](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.
  39. # 模型架构
  40. TinyBERT模型的主干结构是转换器,转换器包含四个编码器模块,其中一个为自注意模块。一个自注意模块即为一个注意模块。
  41. # 数据集
  42. - 下载zhwiki或enwiki数据集进行一般蒸馏。使用[WikiExtractor](https://github.com/attardi/wikiextractor)提取和整理数据集中的文本。如需将数据集转化为TFRecord格式。详见[BERT](https://github.com/google-research/bert)代码库中的create_pretraining_data.py文件。
  43. - 下载GLUE数据集进行任务蒸馏。将数据集由JSON格式转化为TFRecord格式。详见[BERT](https://github.com/google-research/bert)代码库中的run_classifier.py文件。
  44. # 环境要求
  45. - 硬件(Ascend或GPU)
  46. - 使用Ascend或GPU处理器准备硬件环境。如需试用昇腾处理器,请发送[申请表](https://obs-9be7.obs.cn-east-2.myhuaweicloud.com/file/other/Ascend%20Model%20Zoo%E4%BD%93%E9%AA%8C%E8%B5%84%E6%BA%90%E7%94%B3%E8%AF%B7%E8%A1%A8.docx)到ascend@huawei.com。申请通过后,即可获得资源。
  47. - 框架
  48. - [MindSpore](https://gitee.com/mindspore/mindspore)
  49. - 更多关于Mindspore的信息,请查看以下资源:
  50. - [MindSpore教程](https://www.mindspore.cn/tutorial/training/zh-CN/master/index.html)
  51. - [MindSpore Python API](https://www.mindspore.cn/doc/api_python/zh-CN/master/index.html)
  52. # 快速入门
  53. 从官网下载安装MindSpore之后,可以开始一般蒸馏。任务蒸馏和评估方法如下:
  54. ```bash
  55. # 单机运行一般蒸馏示例
  56. bash scripts/run_standalone_gd.sh
  57. 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`.
  58. # Ascend设备上分布式运行一般蒸馏示例
  59. bash scripts/run_distributed_gd_ascend.sh 8 1 /path/hccl.json
  60. 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.
  61. # GPU设备上分布式运行一般蒸馏示例
  62. bash scripts/run_distributed_gd_gpu.sh 8 1 /path/data/ /path/schema.json /path/teacher.ckpt
  63. # 运行任务蒸馏和评估示例
  64. bash scripts/run_standalone_td.sh
  65. 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.
  66. If running on GPU, please set the `device_target=GPU`.
  67. ```
  68. 若在Ascend设备上运行分布式训练,请提前创建JSON格式的HCCL配置文件。
  69. 详情参见如下链接:
  70. https:gitee.com/mindspore/mindspore/tree/master/model_zoo/utils/hccl_tools.
  71. 如需设置数据集格式和参数,请创建JSON格式的视图配置文件,详见[TFRecord](https://www.mindspore.cn/doc/programming_guide/zh-CN/master/dataset_loading.html#tfrecord) 格式。
  72. ```text
  73. For general task, schema file contains ["input_ids", "input_mask", "segment_ids"].
  74. For task distill and eval phase, schema file contains ["input_ids", "input_mask", "segment_ids", "label_ids"].
  75. `numRows` is the only option which could be set by user, the others value must be set according to the dataset.
  76. For example, the dataset is cn-wiki-128, the schema file for general distill phase as following:
  77. {
  78. "datasetType": "TF",
  79. "numRows": 7680,
  80. "columns": {
  81. "input_ids": {
  82. "type": "int64",
  83. "rank": 1,
  84. "shape": [256]
  85. },
  86. "input_mask": {
  87. "type": "int64",
  88. "rank": 1,
  89. "shape": [256]
  90. },
  91. "segment_ids": {
  92. "type": "int64",
  93. "rank": 1,
  94. "shape": [256]
  95. }
  96. }
  97. }
  98. ```
  99. # 脚本说明
  100. ## 脚本和样例代码
  101. ```shell
  102. .
  103. └─bert
  104. ├─README.md
  105. ├─scripts
  106. ├─run_distributed_gd_ascend.sh # Ascend设备上分布式运行一般蒸馏的shell脚本
  107. ├─run_distributed_gd_gpu.sh # GPU设备上分布式运行一般蒸馏的shell脚本
  108. ├─run_standalone_gd.sh # 单机运行一般蒸馏的shell脚本
  109. ├─run_standalone_td.sh # 单机运行任务蒸馏的shell脚本
  110. ├─src
  111. ├─__init__.py
  112. ├─assessment_method.py # 评估过程的测评方法
  113. ├─dataset.py # 数据处理
  114. ├─gd_config.py # 一般蒸馏阶段的参数配置
  115. ├─td_config.py # 任务蒸馏阶段的参数配置
  116. ├─tinybert_for_gd_td.py # 网络骨干编码
  117. ├─tinybert_model.py # 网络骨干编码
  118. ├─utils.py # util函数
  119. ├─__init__.py
  120. ├─run_general_distill.py # 一般蒸馏训练网络
  121. ├─run_task_distill.py # 任务蒸馏训练评估网络
  122. ```
  123. ## 脚本参数
  124. ### 一般蒸馏
  125. ```text
  126. 用法:run_general_distill.py [--distribute DISTRIBUTE] [--epoch_size N] [----device_num N] [--device_id N]
  127. [--device_target DEVICE_TARGET] [--do_shuffle DO_SHUFFLE]
  128. [--enable_data_sink ENABLE_DATA_SINK] [--data_sink_steps N]
  129. [--save_ckpt_path SAVE_CKPT_PATH]
  130. [--load_teacher_ckpt_path LOAD_TEACHER_CKPT_PATH]
  131. [--save_checkpoint_step N] [--max_ckpt_num N]
  132. [--data_dir DATA_DIR] [--schema_dir SCHEMA_DIR] [--dataset_type DATASET_TYPE] [train_steps N]
  133. 选项:
  134. --device_target 代码实现设备,可选项为Ascend或CPU。默认为Ascend
  135. --distribute 是否多卡预训练,可选项为true(多卡预训练)或false。默认为false
  136. --epoch_size 轮次,默认为1
  137. --device_id 设备ID,默认为0
  138. --device_num 使用设备数量,默认为1
  139. --save_ckpt_path 保存检查点文件的路径,默认为""
  140. --max_ckpt_num 保存检查点文件的最大数,默认为1
  141. --do_shuffle 是否使能轮换,可选项为true或false,默认为true
  142. --enable_data_sink 是否使能数据下沉,可选项为true或false,默认为true
  143. --data_sink_steps 设置数据下沉步数,默认为1
  144. --save_checkpoint_step 保存检查点文件的步数,默认为1000
  145. --load_teacher_ckpt_path 加载检查点文件的路径,默认为""
  146. --data_dir 数据目录,默认为""
  147. --schema_dir schema.json的路径,默认为""
  148. --dataset_type 数据集类型,可选项为tfrecord或mindrecord,默认为tfrecord
  149. ```
  150. ### 任务蒸馏
  151. ```text
  152. usage: run_general_task.py [--device_target DEVICE_TARGET] [--do_train DO_TRAIN] [--do_eval DO_EVAL]
  153. [--td_phase1_epoch_size N] [--td_phase2_epoch_size N]
  154. [--device_id N] [--do_shuffle DO_SHUFFLE]
  155. [--enable_data_sink ENABLE_DATA_SINK] [--save_ckpt_step N]
  156. [--max_ckpt_num N] [--data_sink_steps N]
  157. [--load_teacher_ckpt_path LOAD_TEACHER_CKPT_PATH]
  158. [--load_gd_ckpt_path LOAD_GD_CKPT_PATH]
  159. [--load_td1_ckpt_path LOAD_TD1_CKPT_PATH]
  160. [--train_data_dir TRAIN_DATA_DIR]
  161. [--eval_data_dir EVAL_DATA_DIR]
  162. [--task_name TASK_NAME] [--schema_dir SCHEMA_DIR] [--dataset_type DATASET_TYPE]
  163. options:
  164. --device_target 代码实现设备,可选项为Ascend或CPU。默认为Ascend
  165. --do_train 是否使能训练任务,可选项为true或false,默认为true
  166. --do_eval 是否使能评估任务,可选项为true或false,默认为true
  167. --td_phase1_epoch_size td phase1的epoch size大小,默认为10
  168. --td_phase2_epoch_size td phase2的epoch size大小,默认为3
  169. --device_id 设备ID,默认为0
  170. --do_shuffle 是否使能轮换,可选项为true或false,默认为true
  171. --enable_data_sink 是否使能数据下沉,可选项为true或false,默认为true
  172. --save_ckpt_step 保存检查点文件的步数,默认为1000
  173. --max_ckpt_num 保存的检查点文件的最大数,默认为1
  174. --data_sink_steps 设置数据下沉步数,默认为1
  175. --load_teacher_ckpt_path 加载teacher检查点文件的路径,默认为""
  176. --load_gd_ckpt_path 加载通过一般蒸馏生成的检查点文件的路径,默认为""
  177. --load_td1_ckpt_path 加载通过任务蒸馏阶段1生成的检查点文件的路径,默认为""
  178. --train_data_dir 训练数据集目录,默认为""
  179. --eval_data_dir 评估数据集目录,默认为""
  180. --task_name 分类任务,可选项为SST-2、QNLI、MNLI,默认为""
  181. --schema_dir schema.json的路径,默认为""
  182. --dataset_type 数据集类型,可选项为tfrecord或mindrecord,默认为tfrecord
  183. ```
  184. ## 选项及参数
  185. `gd_config.py` and `td_config.py` 包含BERT模型参数与优化器和损失缩放选项。
  186. ### 选项
  187. ```text
  188. batch_size 输入数据集的批次大小,默认为16
  189. Parameters for lossscale:
  190. loss_scale_value 损失放大初始值,默认为
  191. scale_factor 损失放大的更新因子,默认为2
  192. scale_window 损失放大的一次更新步数,默认为50
  193. Parameters for optimizer:
  194. learning_rate 学习率
  195. end_learning_rate 结束学习率,取值需为正数
  196. power 幂
  197. weight_decay 权重衰减
  198. eps 增加分母,提高小数稳定性
  199. ```
  200. ### 参数
  201. ```text
  202. Parameters for bert network:
  203. seq_length 输入序列的长度,默认为128
  204. vocab_size 各内嵌向量大小,需与所采用的数据集相同。默认为30522
  205. hidden_size BERT的encoder层数
  206. num_hidden_layers 隐藏层数
  207. num_attention_heads 注意头的数量,默认为12
  208. intermediate_size 中间层数
  209. hidden_act 所采用的激活函数,默认为gelu
  210. hidden_dropout_prob BERT输出的随机失活可能性
  211. attention_probs_dropout_prob BERT注意的随机失活可能性
  212. max_position_embeddings 序列最大长度,默认为512
  213. save_ckpt_step 保存检查点数量,默认为100
  214. max_ckpt_num 保存检查点最大数量,默认为1
  215. type_vocab_size 标记类型的词汇表大小,默认为2
  216. initializer_range TruncatedNormal的初始值,默认为0.02
  217. use_relative_positions 是否采用相对位置,可选项为true或false,默认为False
  218. dtype 输入的数据类型,可选项为mstype.float16或mstype.float32,默认为mstype.float32
  219. compute_type Bert Transformer的计算类型,可选项为mstype.float16或mstype.float32,默认为mstype.float16
  220. ```
  221. ## 训练流程
  222. ### 用法
  223. #### Ascend处理器上运行
  224. 运行以下命令前,确保已设置load_teacher_ckpt_path、data_dir和schma_dir。请将路径设置为绝对全路径,例如/username/checkpoint_100_300.ckpt。
  225. ```bash
  226. bash scripts/run_standalone_gd.sh
  227. ```
  228. 以上命令后台运行,您可以在log.txt文件中查看运行结果。训练结束后,您可以在默认脚本文件夹中找到检查点文件。得到如下损失值:
  229. ```text
  230. # grep "epoch" log.txt
  231. epoch: 1, step: 100, outputs are (Tensor(shape=[1], dtype=Float32, 28.2093), Tensor(shape=[], dtype=Bool, False), Tensor(shape=[], dtype=Float32, 65536))
  232. epoch: 2, step: 200, outputs are (Tensor(shape=[1], dtype=Float32, 30.1724), Tensor(shape=[], dtype=Bool, False), Tensor(shape=[], dtype=Float32, 65536))
  233. ...
  234. ```
  235. > **注意**训练过程中会根据`device_num`和处理器总数绑定处理器内核。如果您不希望预训练中绑定处理器内核,请在scripts/run_distributed_gd_ascend.sh脚本中移除相关操作。
  236. #### 在GPU处理器上运行
  237. 运行以下命令前,确保已设置load_teacher_ckpt_path、data_dir、schma_dir和device_target=GPU。请将路径设置为绝对全路径,例如/username/checkpoint_100_300.ckpt。
  238. ```bash
  239. bash scripts/run_standalone_gd.sh
  240. ```
  241. 以上命令后台运行,您可以在log.txt文件中查看运行结果。训练结束后,您可以在默认脚本路径下脚本文件夹中找到检查点文件。得到如下损失值:
  242. ```text
  243. # grep "epoch" log.txt
  244. epoch: 1, step: 100, outputs are 28.2093
  245. ...
  246. ```
  247. ### 分布式训练
  248. #### Ascend处理器上运行
  249. 运行以下命令前,确保已设置load_teacher_ckpt_path、data_dir和schma_dir。请将路径设置为绝对全路径,例如/username/checkpoint_100_300.ckpt。
  250. ```bash
  251. bash scripts/run_distributed_gd_ascend.sh 8 1 /path/hccl.json
  252. ```
  253. 以上命令后台运行,您可以在log.txt文件中查看运行结果。训练后,可以得到默认log*文件夹路径下的检查点文件。 得到如下损失值:
  254. ```text
  255. # grep "epoch" LOG*/log.txt
  256. epoch: 1, step: 100, outputs are (Tensor(shape=[1], dtype=Float32, 28.1478), Tensor(shape=[], dtype=Bool, False), Tensor(shape=[], dtype=Float32, 65536))
  257. ...
  258. epoch: 1, step: 100, outputs are (Tensor(shape=[1], dtype=Float32, 30.5901), Tensor(shape=[], dtype=Bool, False), Tensor(shape=[], dtype=Float32, 65536))
  259. ...
  260. ```
  261. #### GPU处理器上运行
  262. 输入绝对全路径,例如:"/username/checkpoint_100_300.ckpt"。
  263. ```bash
  264. bash scripts/run_distributed_gd_gpu.sh 8 1 /path/data/ /path/schema.json /path/teacher.ckpt
  265. ```
  266. 以上命令后台运行,您可以在log.txt文件中查看运行结果。训练结束后,您可以在默认LOG*文件夹下找到检查点文件。得到如下损失值:
  267. ```text
  268. # grep "epoch" LOG*/log.txt
  269. epoch: 1, step: 1, outputs are 63.4098
  270. ...
  271. ```
  272. ## 评估过程
  273. ### 用法
  274. 如需运行后继续评估,请设置`do_train=true`和`do_eval=true`;如需单独运行评估,请设置`do_train=false`和`do_eval=true`。如需在GPU处理器上运行,请设置`device_target=GPU`。
  275. #### 基于SST-2数据集进行评估
  276. ```bash
  277. bash scripts/run_standalone_td.sh
  278. ```
  279. 以上命令后台运行,您可以在log.txt文件中查看运行结果。得出如下测试数据集准确率:
  280. ```bash
  281. # grep "The best acc" log.txt
  282. The best acc is 0.872685
  283. The best acc is 0.893515
  284. The best acc is 0.899305
  285. ...
  286. The best acc is 0.902777
  287. ...
  288. ```
  289. #### 基于MNLI数据集进行评估
  290. 运行如下命令前,请确保已设置加载与训练检查点路径。请将检查点路径设置为绝对全路径,例如,/username/pretrain/checkpoint_100_300.ckpt。
  291. ```bash
  292. bash scripts/run_standalone_td.sh
  293. ```
  294. 以上命令将在后台运行,请在log.txt文件中查看结果。测试数据集的准确率如下:
  295. ```text
  296. # grep "The best acc" log.txt
  297. The best acc is 0.803206
  298. The best acc is 0.803308
  299. The best acc is 0.810355
  300. ...
  301. The best acc is 0.813929
  302. ...
  303. ```
  304. #### 基于QNLI数据集进行评估
  305. 运行如下命令前,请确保已设置加载与训练检查点路径。请将检查点路径设置为绝对全路径,例如/username/pretrain/checkpoint_100_300.ckpt。
  306. ```bash
  307. bash scripts/run_standalone_td.sh
  308. ```
  309. 以上命令后台运行,您可以在log.txt文件中查看运行结果。测试数据集的准确率如下:
  310. ```text
  311. # grep "The best acc" log.txt
  312. The best acc is 0.870772
  313. The best acc is 0.871691
  314. The best acc is 0.875183
  315. ...
  316. The best acc is 0.891176
  317. ...
  318. ```
  319. ## 模型描述
  320. ## 性能
  321. ### 评估性能
  322. | 参数 | Ascend | GPU |
  323. | -------------------------- | ---------------------------------------------------------- | ------------------------- |
  324. | 模型版本 | TinyBERT | TinyBERT |
  325. | 资源 | Ascend 910, cpu:2.60GHz 192核, 内存:755G | NV SMX2 V100-32G, cpu:2.10GHz 64核, 内存:251G |
  326. | 上传日期 | 2020-08-20 | 2020-08-24 |
  327. | MindSpore版本 | 0.6.0 | 0.7.0 |
  328. | 数据集 | en-wiki-128 | en-wiki-128 |
  329. | 训练参数 | src/gd_config.py | src/gd_config.py |
  330. | 优化器| AdamWeightDecay | AdamWeightDecay |
  331. | 损耗函数 | SoftmaxCrossEntropy | SoftmaxCrossEntropy |
  332. | 输出 | 概率 | 概率 |
  333. | 损失 | 6.541583 | 6.6915 |
  334. | 速度 | 35.4毫秒/步 | 98.654毫秒/步 |
  335. | 总时长 | 17.3 小时 (3轮, 8卡) | 48小时 (3轮, 8卡) |
  336. | 参数 (M) | 15分钟 | 15分钟 |
  337. | 任务蒸馏检查点| 74M(.ckpt 文件) | 74M(.ckpt 文件) |
  338. #### 推理性能
  339. | 参数 | Ascend | GPU |
  340. | -------------------------- | ----------------------------- | ------------------------- |
  341. | 模型版本 | | |
  342. | 资源 | Ascend 910 | NV SMX2 V100-32G |
  343. | 上传日期 | 2020-08-20 | 2020-08-24 |
  344. | MindSpore版本 | 0.6.0 | 0.7.0 |
  345. | 数据集 | SST-2, | SST-2 |
  346. | batch_size | 32 | 32 |
  347. | 准确率 | 0.902777 | 0.9086 |
  348. | 速度 | | |
  349. | 总时长 | | |
  350. | 推理模型 | 74M(.ckpt 文件) | 74M(.ckpt 文件) |
  351. # 随机情况说明
  352. run_standaloned_td.sh脚本中设置了do_shuffle来轮换数据集。
  353. gd_config.py和td_config.py文件中设置了hidden_dropout_prob和attention_pros_dropout_prob,使网点随机失活。
  354. run_general_distill.py文件中设置了随机种子,确保分布式训练初始权重相同。
  355. # ModelZoo主页
  356. 请浏览官网[主页](https://gitee.com/mindspore/mindspore/tree/master/model_zoo)。