## 训练性能 InternLM 深度整合了 Flash-Attention, Apex 等高性能模型算子,提高了训练效率。通过构建 Hybrid Zero 技术,实现计算和通信的高效重叠,大幅降低了训练过程中的跨节点通信流量。InternLM 支持 7B 模型从 8 卡扩展到 1024 卡,千卡规模下加速效率可高达 90%,训练吞吐超过 180TFLOPS,平均单卡每秒处理的 token 数量超过3600。下表为 InternLM 在不同配置下的扩展性测试数据: | GPU Number | 8 | 16 | 32 | 64 | 128 | 256 | 512 | 1024 | | ---------------- | ---- | ---- | ---- | ---- | ----- | ----- | ----- | ------ | | TGS (Tokens/GPU/Second) | 4078 | 3939 | 3919 | 3944 | 3928 | 3920 | 3835 | 3625 | | TFLOPS | 193 | 191 | 188 | 188 | 187 | 185 | 186 | 184 | 我们在GPU集群上测试了多种并行配置下,InternLM训练7B模型的性能。在每组测试中,每张GPU在单次迭代中处理的token数量一致。测试使用的硬件和参数配置如下表所示: | 硬件 | 硬件型号 | | ----------------------- | ----------------------------- | | GPU | nvidia_a100-sxm4-80gb | | Memory | 2TB | | Inter-machine bandwidth | 4 * 100Gb RoCE | | CPU | 128 core Intel(R) Xeon(R) CPU | | 超参 | tp=1 | tp=2 | | --------- | ---- | ---- | | micro_num | 4 | 4 | | micro_bsz | 2 | 4 | | seq_len | 2048 | 2048 | InternLM中`zero1`的配置决定了优化器状态的分配范围。 - `zero1=-1`表明优化器状态分布在全部数据并行节点(等同于Deepspeed Zero-1的效果) - `zero1=8,tp=1`的情况下,优化器状态分布在单节点8张GPU内,并且不同节点上的优化器状态保持一致。 ### 吞吐量测量 吞吐量定义为TGS,平均每GPU每秒处理的token的数量(Tokens per GPU per Second)。在该项测试的训练配置中,`pack_sample_into_one=False`,`checkpoint=False`, `dtype=torch.bfloat16`。测试结果如下表所示。采用`zero1=8,tp=1`,InternLM针对7B模型训练的扩展性,在千卡训练的加速效率可以达到`88%`。 | 并行配置 | 8卡 | 16卡 | 32卡 | 64卡 | 128卡 | 256卡 | 512卡 | 1024卡 | | ---------------- | ---- | ---- | ---- | ---- | ----- | ----- | ----- | ------ | | (tp=1, zero1=-1) | 4062 | 3842 | 3752 | 3690 | 3571 | 3209 | 2861 | 2271 | | (tp=1, zero1=8) | 4078 | 3939 | 3919 | 3944 | 3928 | 3920 | 3835 | 3625 | | (tp=2, zero1=-1) | 3822 | 3595 | 3475 | 3438 | 3308 | 3094 | 2992 | 2785 | | (tp=2, zero1=4) | 3761 | 3658 | 3655 | 3650 | 3651 | 3653 | 3589 | 3486 |
### FLOPS测试 模型训练的计算量参考 [Megatron](https://deepakn94.github.io/assets/papers/megatron-sc21.pdf) 论文中FLOPS计算方式。为了保证训练过程中的FLOPS恒定,在该项测试的训练配置中,`pack_sample_into_one=True`,`dtype=torch.bfloat16`。 当开启 Activation Ckpt后,测试结果如下表所示,InternLM针对7B模型的千卡训练,可以达到 `>180 TFLOPS`: - TGS: Tokens per GPU per Second - Global Bsz: 一个step中所有GPU处理的token数量 | TP | Zero1 | Pack Sample Into One | Activation Ckpt | GPU Num | Seq Len | Micro Bsz | Micro Num | Global Bsz | TGS | TFLOPS | |-|-|-|-|-|-|-|-|-|-|-| | 1 | 8 | TRUE | TRUE | 8 | 2048 | 8 | 1 | 0.125M | 3314 | 193 | | 1 | 8 | TRUE | TRUE | 16 | 2048 | 8 | 1 | 0.25M | 3268 | 191 | | 1 | 8 | TRUE | TRUE | 32 | 2048 | 8 | 1 | 0.5M | 3323 | 188 | | 1 | 8 | TRUE | TRUE | 64 | 2048 | 8 | 1 | 1M | 3217 | 188 | | 1 | 8 | TRUE | TRUE | 128 | 2048 | 8 | 1 | 2M | 3260 | 187 | | 1 | 8 | TRUE | TRUE | 256 | 2048 | 8 | 1 | 4M | 3215 | 187 | | 1 | 8 | TRUE | TRUE | 512 | 2048 | 8 | 1 | 8M | 3199 | 186 | | 1 | 8 | TRUE | TRUE | 1024 | 2048 | 8 | 1 | 16M | 3163 | 184 | | 1 | 8 | TRUE | TRUE | 512 | 2048 | 4 | 1 | 4M | 2963 | 173 | | 1 | 8 | TRUE | TRUE | 1024 | 2048 | 2 | 1 | 4M | 2341 | 136 | | 1 | 8 | TRUE | TRUE | 1024 | 2048 | 4 | 1 | 8M | 2796 | 160 | 当关闭 Activation Ckpt后,测试结果如下表所示: | TP | Zero1 | Pack Sample Into One | Activation Ckpt | GPU Num | Seq Len | Micro Bsz | Micro Num | Global Bsz | TGS | TFLOPS | |-|-|-|-|-|-|-|-|-|-|-| | 1 | 8 | TRUE | FALSE | 8 | 2048 | 2 | 4 | 0.125M | 4103 | 183 | | 1 | 8 | TRUE | FALSE | 16 | 2048 | 2 | 4 | 0.25M | 3939 | 177 | | 1 | 8 | TRUE | FALSE | 32 | 2048 | 2 | 4 | 0.5M | 3919 | 176 | | 1 | 8 | TRUE | FALSE | 64 | 2048 | 2 | 4 | 1M | 3944 | 174 | | 1 | 8 | TRUE | FALSE | 128 | 2048 | 2 | 4 | 2M | 3928 | 173 | | 1 | 8 | TRUE | FALSE | 256 | 2048 | 2 | 4 | 4M | 3920 | 173 | | 1 | 8 | TRUE | FALSE | 512 | 2048 | 2 | 4 | 8M | 3900 | 173 | | 1 | 8 | TRUE | FALSE | 1024 | 2048 | 2 | 4 | 16M | 3625 | 160 | | 1 | 8 | TRUE | FALSE | 512 | 2048 | 2 | 2 | 4M | 3084 | 139 | | 1 | 8 | TRUE | FALSE | 1024 | 2048 | 2 | 1 | 4M | 2346 | 105 | | 1 | 8 | TRUE | FALSE | 1024 | 2048 | 2 | 2 | 8M | 2817 | 124 |
### 显存占用测试 测试配置: | 配置 | 描述 | | :-------: | :-----: | | 分支 | develop | | commit id | 2b984ff | | 显卡 | A800 | | 重计算 | True | | micro_bsz | 1 | | micro_num | 4 | | dtype | bfloat16| ```python # InternLM/configs/7B_sft.py data = dict( # micro_num means the number of micro_batch contained in one gradient update micro_num=4, # packed_length = micro_bsz * SEQ_LEN micro_bsz=1, ... ) model = dict( checkpoint=True, dtype="torch.bfloat16", ... ) parallel = dict( zero1=dict(size=8, fsdp=False), tensor=1, pipeline=dict(size=1, interleaved_overlap=True), sequence_parallel=False, ) ``` 预训练测试: |模型|卡数|zero1|tp|pp|fsdp|显存(GB)| |:-:|:-:|:-:|:-:|:-:|:-:|:-:| | 7B | 3 | -1 | 1 | 3 |False| 75 | | 7B | 3 | -1 | 1 | 1 |True | 72 | | 7B | 4 | -1 | 4 | 1 |True | 52 | | 7B | 4 | -1 | 4 | 1 |False| 61 | | 7B | 4 | -1 | 1 | 4 |False| 69 | | 7B | 4 | -1 | 1 | 1 |True | 56 | | 7B | 5 | -1 | 1 | 1 |True | 49 | | 7B | 5 | -1 | 1 | 5 |False| 62 | | 7B | 6 | -1 | 1 | 1 |True | 39 | | 7B | 6 | -1 | 2 | 1 |True | 38 | | 7B | 6 | -1 | 1 | 6 |False| 56 | | 20B | 8 | -1 | 1 | 1 |True | 78 | | 20B | 8 | -1 | 8 | 1 |True | 71 | | 20B | 16 | -1 | 1 | 1 |True | 40 | | 20B | 16 | -1 | 8 | 1 |True | 39 | | 20B | 16 | -1 | 1 | 16 |False| 52 | Web_demo 测试: |模型|显卡|显存(GB)|内存(MB)| |:-:|:-:|:-:|:-:| | 7B | A800 | 14.5 | 2465 | | 7B | A800 | 39 | 9547 |