当前位置: 首页 > news >正文

探索多种方案下 LLM 的预训练性能

Base 版

此处采用最基础 Torch
的 DDP

算法,作为基础的对比版本,运行的脚本如下:

torchrun --nnodes 1 --nproc_per_node 8 pretrain_hf.py
–model_config_path …/config/config.json
–tokenizer_name_or_path …/ckpt/Llama-2-13b-hf
–per_device_train_batch_size 8
–do_train
–seed 1234
–fp16
–num_train_epochs 1
–lr_scheduler_type cosine
–learning_rate 2e-5
–warmup_ratio 0.05
–weight_decay 0.01
–logging_strategy steps
–logging_steps 10
–save_strategy steps
–save_total_limit 1
–save_steps 100
–gradient_accumulation_steps 8
–model_max_length 2048
–output_dir ‘./hf_logs’
–overwrite_output_dir
–gradient_checkpointing
–ddp_find_unused_parameters False

FSDP 版

FSDP是从DeepSpeed ZeRO
以及FairScale的FSDP中获取灵感的一种完全数据分片并行的方法。

HuggingFace 的 transformers 已经原生支持了 FSDP,可以在原生代码的运行命令上增加2行配置来使用:

--fsdp "full_shard auto_wrap" \
--fsdp_config 'fsdp.json' \

HuggingFace 的 transformers 已经原生支持了 DeepSpeed,其用法也非常简单,只需要添加一个配置文件和一个参数即可:

以下是zero-2的配置文件

{
“fp16”: {
“enabled”: “auto”,
“loss_scale”: 0,
“loss_scale_window”: 100,
“initial_scale_power”: 16,
“hysteresis”: 2,
“min_loss_scale”: 1e-10
},

"zero_optimization": {
    "stage": 2,
    "allgather_partitions": true,
    "allgather_bucket_size": 1e8,
    "overlap_comm": true,
    "reduce_scatter": true,
    "reduce_bucket_size": 1e8,
    "contiguous_gradients": true
},

"gradient_accumulation_steps": "auto",
"gradient_clipping": "auto",
"steps_per_print": 2000,
"train_batch_size": "auto",
"train_micro_batch_size_per_gpu": "auto",
"wall_clock_breakdown": false

}

使用该配置文件如下:

–deepspeed ‘ds_zero2_no_offload.json’ \

运行结果如下所示,与原版 DDP 相比性能提升约 15.4% :

***** train metrics *****
epoch = 0.98
train_loss = 7.6718
train_runtime = 0:16:35.35
train_samples_per_second = 31.297
train_steps_per_second = 0.04

如果使用 zero3 算法,结果如下,zero2 略有下降 :

***** train metrics *****
epoch = 0.98
train_loss = 9.5239
train_runtime = 0:16:55.82
train_samples_per_second = 30.667
train_steps_per_second = 0.01

如果使用 zero3 算法同时使用 offload,性能略有下降:

***** train metrics *****
epoch = 0.98
train_loss = 9.3981
train_runtime = 0:17:21.20
train_samples_per_second = 29.919
train_steps_per_second = 0.01

FlashAttention
if training_args.flash_attn:
from utils.flash_attn_patch import replace_llama_attn_with_flash_attn
replace_llama_attn_with_flash_attn()

只需要在运行文件中增加一句使能即可:

--flash_attn \

运行结果如下所示,与原版 DDP 相比性能提升约 52.7% :

***** train metrics *****
epoch = 0.98
train_loss = 8.0186
train_runtime = 0:12:32.22
train_samples_per_second = 41.413
train_steps_per_second = 0.04

FlashAttention + FSDP 性能如下,略有下降:

***** train metrics *****
epoch = 0.98
train_loss = 9.9216
train_runtime = 0:12:55.09
train_samples_per_second = 40.191
train_steps_per_second = 0.039

FlashAttention + DeepSpeed 性能如下,略有提升:

***** train metrics *****
epoch = 0.98
train_loss = 8.0758
train_runtime = 0:12:17.55
train_samples_per_second = 42.237
train_steps_per_second = 0.041

ColossalAI 的优化算法实现 llama 模型的预训练。

首先尝试 Gemini 算法,这是 ColossalAI 提出的异构内存空间管理器。它通过在 CPU 和 GPU 中容纳模型数据,并仅在必要时将数据移动到当前设备,可以同时利用 GPU 内存、CPU 内存(由 CPU DRAM 或 NVMe SSD内存组成)来突破单GPU内存墙的限制。

目前 DeepSpeed采用的 Zero-offload 在CPU和GPU内存之间静态划分模型数据,并且它们的内存布局对于不同的训练配置是恒定的。如下图左边所示,当 GPU 内存不足以满足其相应的模型数据要求时,即使当时CPU上仍有可用内存,系统也会崩溃。而 ColossalAI 可以通过将一部分模型数据换出到CPU上来完成训练,这就是Gemini。它管理CPU和GPU二者内存空间。它的内存管理器由两部分组成,分别是MemStatsCollector(MSC)和StatefulTensorMgr(STM),可以让张量在训练过程中动态分布在CPU-GPU的存储空间内。
Zero-Offload和Gemini的内存管理方案比较

Gemini 还利用了深度学习网络训练过程的迭代特性,将迭代分为warmup和non-warmup两个阶段,开始时的一个或若干迭代步属于预热阶段,其余的迭代步属于正式阶段。在warmup阶段为MSC收集信息,而在non-warmup阶段STM入去MSC收集的信息来移动tensor,以达到最小化CPU-GPU数据移动volume的目的。
Gemini在不同训练阶段的运行流程

下面是该算法的用法:

colossalai run --nproc_per_node 8 pretrain_colossalai.py
–config …/config/config.json
–plugin gemini_cuda
–batch_size 28
–lr 2e-5
–weigth_decay 0.01
–warmup_steps 2
–grad_checkpoint
–max_length 2048
–mixed_precision fp16
–flash_attention

从日志可以看到该算法对GPU及CPU的内存分配情况:

Booster init max CUDA memory: 1523.89 MB
Booster init max CPU memory: 6737.21 MB
Max CUDA memory usage: 36608.19 MB

此时可观察到 GPU 及 CPU 的使用情况,可以清楚看到该算法在二者间动态使用的过程
GPU 的使用情况
CPU 的使用情况

性能如下所示,与原版 DDP 相比性能提升约 50.7%,其中主要的性能提升来源于 FlashAttention:

train_runtime = 0:12:42.53
train_samples_per_second = 40.882

如果不使能 FlashAttention,性能如下,与原版 DDP 相比性能提升约 8.1 %:

train_runtime = 0:17:42.36
train_samples_per_second = 29.333

Sophia Optimizer

Sophia 优化器使用随机估计作为 Hessian 矩阵对角线的 pre-conditioner,并采用剪切(clipping)机制来控制最坏情况下的参数大小更新。在像 GPT-2 这样的预训练语言模型上,Sophia 与 Adam 相比,在减少了 50% step 数量的情况下实现了相同的验证预训练损失,这相当于总计算量减少了 50%,wall-clock 时间减少了 50%。

相关文章:

  • Spring Boot 七种事务传播行为只有 REQUIRES_NEW 和 NESTED 支持部分回滚的分析
  • C++26新特性解读: 结构化绑定作为条件
  • 在linux中GCC、Yum 与 Apt - get 的区别
  • OCRmyPDF 开源核弹
  • PyCharm 下载与安装教程:从零开始搭建你的 Python 开发环境
  • 【江协科技STM32】PWR电源控制(学习笔记)
  • 排序算法-插入排序
  • Tomcat深度解析:Java Web服务的核心引擎
  • Java 线程池与 Kotlin 协程 高阶学习
  • 子网划分2
  • OSPF五种数据包详解
  • FPGA实现LED流水灯
  • Leetcode 3500. Minimum Cost to Divide Array Into Subarrays
  • Spring IOC:容器管理与依赖注入秘籍
  • RK3568 pinctrl内容讲解
  • Python----机器学习(距离计算方式:欧式距离,曼哈顿距离,切比雪夫距离,余弦相似度,汉明距离,闵可夫斯基距离,Jaccard指数,半正矢距离)
  • 探索PHP的未来发展与应用趋势
  • Java面试黄金宝典27
  • transformer架构与其它架构对比
  • K8S学习之基础六十六:Rancher部署
  • 下达专项资金、党政主官田间调研……全国多地力保夏粮稳收
  • 最火“五一”预订!小长假前两日多地接待游客量两位数增长,出境游订单井喷
  • 竞彩湃|德甲保级白热化,都灵主帅直面旧主
  • 五一假期首日,上海外滩客流超55万人次
  • 上海与世界|黄菊与上海建设中国式全球城市
  • 三家“券商系”公募同日变更掌门人,新董事长均为公司股东方老将