README.md 6.49 KB
Newer Older
yuguo960516's avatar
gpt2  
yuguo960516 committed
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
# Generative Pre-Training2(GPT2)
## 模型介绍
GPT2模型:第二代生成式预训练模型(Generative Pre-Training2)。
## 模型结构
GPT2使用 Transformer 的 Decoder 结构,并对 Transformer Decoder 进行了一些改动,原本的 Decoder 包含了两个 Multi-Head Attention 结构,GPT2 只保留了 Mask Multi-Head Attention。

我们为了用户可以使用OneFlow-Libai快速验证GPT2模型预训练,统计性能或验证精度,提供了一个GPT2网络示例,主要网络参数:

```
model.cfg.num_attention_heads = 16
model.cfg.hidden_size = 384
model.cfg.ffn_hidden_size = 1536
model.cfg.hidden_layers = 6
model.cfg.max_seq_length = 1024
```

完整的GPT2网络配置在configs/common/model/gpt.py中

同时,我们提供了一个更大的GPT2-13B网络为了用户可以快速在DCU集群上使用OneFlow-Libai进行较大规模的混合并行分布式预训练验证(该网络可能并不具有实际训练价值),该网络结构在GPT2基础上进行扩充,主要网络参数如下,参数量共有13.1B:

```
model.cfg.num_attention_heads = 32
model.cfg.hidden_size = 4096
model.cfg.ffn_hidden_size = 4096*4
model.cfg.hidden_layers = 64
model.cfg.max_seq_length = 1024
```

## 数据集
我们在libai目录下集成了部分小数据集供用户快速验证:

    ./nlp_data
## GPT2预训练

### 环境配置

推荐使用docker方式运行,提供[光源](https://www.sourcefind.cn/#/service-details)拉取的docker镜像:image.sourcefind.cn:5000/dcu/admin/base/oneflow:0.9.1-centos7.6-dtk-22.10.1-py39-latest

进入docker:

    cd libai
    pip3 install -r requirements.txt -i https://mirrors.aliyun.com/pypi/simple
    pip3 install pybind11 -i https://mirrors.aliyun.com/pypi/simple
    pip3 install -e . -i https://mirrors.aliyun.com/pypi/simple

### 训练

该预训练脚本运行环境为1节点,4张DCU-Z100-16G。

并行配置策略在configs/gpt2_pretrain.py中,使用自动混合精度:

```
train.amp.enabled = True
train.train_micro_batch_size = 4
train.dist.data_parallel_size = 4
train.dist.tensor_parallel_size = 1
train.dist.pipeline_parallel_size = 1
```

预训练命令:

    cd libai
    bash tools/train.sh tools/train_net.py configs/gpt2_pretrain.py 4

### 性能和收敛性

训练数据:[https://oneflow-static.oss-cn-beijing.aliyuncs.com/ci-files/dataset/libai/gpt_dataset](链接)

使用的GPGPU:4张DCU-Z100-16G。

模型性能及收敛性:

| 卡数 | 分布式工具 |       性能       |            收敛性             |
| :--: | :--------: | :--------------: | :---------------------------: |
|  4   | Libai-main | 129.55 samples/s | total_loss: 4.336/10000 iters |

## GPT2-13B预训练

### 环境配置

要求DCU集群Slurm环境正常。

推荐用户使用预编译好的python3.9包来快速建立python3虚拟环境:

    cd libai
    export PYTHON3_LIB_PATH=/python_lib_path
    virtualenv -p /python_bin_path/python3 --system-site-packages venv_oneflow
    source env.sh	#进入venv_oneflow虚拟环境
    
    pip3 install --upgrade pip -i https://mirrors.aliyun.com/pypi/simple	#更新pip
    pip3 install -r requirements.txt -i https://mirrors.aliyun.com/pypi/simple
    pip3 install pybind11 -i https://mirrors.aliyun.com/pypi/simple
    pip3 install -e . -i https://mirrors.aliyun.com/pypi/simple
    pip3 install oneflow-0.9.1+dtk2210.git.8ea46d6-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

yuguo960516's avatar
readme  
yuguo960516 committed
96
97
98
99
100
101
102
103
104
105
106
107
### 混合并行配置指南

首先,可以在一个节点内的多卡上做模型并行切分。因为模型并行通信开销大(前后向可能都需要all-reduce通信),而节点内设备间带宽高;另外模型并行组大小越大,流水线Stage可以减少,继而可以减少流水线中的气泡;所以一般可以节点内所有设备作为一个模型并行组。

然后,在模型并行组大小确定后,单节点的可以容纳的模型大小基本确定,就可以据此再依次把多层 Layer 的模型分布到多个节点上,形成流水线并行。在实际中,先固定数据并行是1,参考上面总结固定模型并行大小,再加流水线并行的stage,直到模型可以放的下,不出现oom。

最后,情况就变得简单了,继续加节点,使用更高的数据并行规模,把一个模型并行组的模型复制出多个数据并行组的模型,对数据切分,形成更多的数据并行组,如此就可以形成一个3D并行的切分结果。

值得注意的是,在采用以上策略时,核心要素有几点。首先保证流水并行stage数量小,气泡尽可能少,所以有时可能会再扩大模型并行至2节点。其次,可以同时采用zero策略来不增加通信量的前提下减少显存占用,一般zero 1就可以最多减少75%左右的模型状态(下放的是优化器状态),当然使用zero 2也可以,但是需要注意是否会在真实训练场景中造成性能下降。然后,配合设置Gradient Accumulation Step以及Activation Checkpointing技术来进一步减少模型中间状态对显存的占用,一般Gradient Accumulation Step设置为流水并行度的1-2倍。最后,当显存占用优化明显后,就可以在相同规模的节点上放下更大的macro bs,尽量挤满显存,最终带来可观的性能提升。

当然,在不同参数量的网络下,以上配置需要进行调整,但是思路类似

yuguo960516's avatar
gpt2  
yuguo960516 committed
108
### 训练
yuguo960516's avatar
readme  
yuguo960516 committed
109

yuguo960516's avatar
gpt2  
yuguo960516 committed
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
该预训练脚本需要24个节点,每节点4张DCU-Z100-16G。

混合并行配置策略在configs/gpt2-13B_pretrain.py中,使用自动混合精度:

```
train.amp.enabled = True
train.train_micro_batch_size = 2
train.num_accumulation_steps = 4
train.activation_checkpoint.enabled = True
train.zero_optimization.enabled = True
train.zero_optimization.stage = 1
train.dist.data_parallel_size = 6
train.dist.tensor_parallel_size = 4
train.dist.pipeline_parallel_size = 4 
```

进入登陆节点,预训练命令:

    cd libai
    source submit_job.sh
    tail -f log/xxx.out.log	#查看输出log
    tail -f log/xxx.err.log	#查看错误log

### 性能和收敛性

训练数据:[https://oneflow-static.oss-cn-beijing.aliyuncs.com/ci-files/dataset/libai/gpt_dataset](链接)

使用的GPGPU:96张DCU-Z100-16G。

模型性能及收敛性:
| 卡数 | 分布式工具 | 性能 | 收敛性 |
| :------: | :------: | :------: |:------: |
| 96 | Libai-main | 2.27 samples/s | total_loss: 5.56/1299 iters |
## 参考
* https://libai.readthedocs.io/en/latest/tutorials/get_started/quick_run.html
* https://github.com/Oneflow-Inc/oneflow
* https://github.com/Oneflow-Inc/libai/blob/main/docs/source/notes/FAQ.md