关于大模型实践的一些总结

随着近期ChatGPT的迅速出圈,加速了的大模型时代变革。以Transformer、MOE结构为代表的大模型,传统的单机单卡训练模式肯定不能满足上千亿参数的模型训练,这时候我们就需要解决内存墙和通信墙等一系列问题,在单机多卡或者多机多卡进行模型训练。

刚好最近一段时间,我也在探索大模型相关的一些技术,下面做一个简单的总结。

GPU集群

由于目前只有3台A800 GPU服务器,共24卡。基于目前现有的一些AI框架和大模型,无法充分利用3台服务器。比如:OPT-66B一共有64层Transformer,当使用Alpa进行流水线并行时,而通过流水线并行对模型进行切分时,要么使用16卡,要么使用8卡,没法直接使用24卡,因此,GPU服务器最好是购买偶数台(如2台、4台、8台)。

具体的硬件配置如下:

  • CPUs:  每个节点具有 1TB 内存的 Intel CPU,物理CPU个数为64,每颗CPU核数为16。
  • GPUs:  24 卡 A800 80GB GPUs ,每个节点 8 个 GPU(3 个节点)。

目前使用Huggingface Transformers和DeepSpeed进行通过数据并行进行训练(fine tuning),单卡可以跑三百亿参数(启用ZeRO-2或ZeRO-3),如OPT-30B,具体训练教程参考官方样例。

使用Alpa进行流水线并行和数据并行进行训练(fine tuning)时,使用了3台共24卡(PP:12,DP:2)进行训练OPT-30B,具体训练教程参考官方样例。但是进行模型训练之前需要先进行模型格式转换,将HF格式转换为Alpa格式的模型文件,具体请参考官方代码。如果不想转换,官网也提供了转换好的模型格式,具体请参考文档:Serving OPT-175B, BLOOM-176B and CodeGen-16B using Alpa。

关于大模型实践的一些总结_第1张图片 image.png

大模型算法

模型结构

如:Transformer、MOE等,如果说Transformer结构使得模型突破到上亿参数量,MoE 稀疏混合专家结构使模型参数量产生进一步突破,达到数万亿规模。

大模型算法

如:Bert、GPT-3、Switch Transformer、GLaM等,

目前业界可以下载到的一些大模型

  • GLM-10B/130B :双语(中文和英文)双向稠密模型
  • OPT-2.7B/13B/30B/66B :Meta开源的预训练语言模型
  • LLaMA-7B/13B/30B/65B :Meta开源的基础大语言模型
  • Alpaca(LLaMA-7B):一个强大的可复现的智能跟随模型,种子任务都是英语,收集的数据也都是英文,因此训练出来的模型未对中文优化
  • BELLE(BLOOMZ-7B/LLaMA-7B):本项目基于  Stanford Alpaca,针对中文做了优化,模型调优仅使用由ChatGPT生产的数据(不包含任何其他数据)
  • ChatGLM-6B :中英双语的对话语言模型
  • Bloom-7B/13B/176B:可以处理46 种语言,包括法语、汉语、越南语、印度尼西亚语、加泰罗尼亚语、13 种印度语言(如印地语)和 20 种非洲语言。其中,Bloomz系列模型是基于 xP3 数据集微调。 推荐用于英语的提示(prompting);Bloomz-mt系列模型是基于 xP3mt 数据集微调。推荐用于非英语的提示(prompting)

前两天测试了BELLE,对中文的效果感觉还不错。具体的模型训练(预训练)方法可参考Hugingface Transformers的样例,SFT(指令精调)方法可参考Alpaca的训练代码。

分布式并行及显存优化技术

并行技术

  • 数据并行(如:PyTorch DDP)
  • 模型/张量并行(如:Megatron-LM(1D)、Colossal-AI(2D、2.5D、3D))
  • 流水线并行(如:GPipe、PipeDream、PipeDream-2BW、PipeDream Flush(1F1B))
  • 多维混合并行(如:3D并行(数据并行、模型并行、流水线并行))
  • 自动并行(如:Alpa(自动算子内/算子间并行))
  • 优化器相关的并行(如:ZeRO( 零冗余优化器,在执行的逻辑上是数据并行,但可以达到模型并行的显存优化效果)、PyTorch FSDP)

显存优化技术

  • 重计算(Recomputation):Activation checkpointing(Gradient checkpointing),本质上是一种用时间换空间的策略。
  • 卸载(Offload)技术:一种用通信换显存的方法,简单来说就是让模型参数、激活值等在CPU内存和GPU显存之间左右横跳。如:ZeRO-Offload、ZeRO-Infinity等。

分布式训练框架

如何选择一款分布式训练框架

  • 训练成本:不同的训练工具,训练同样的大模型,成本是不一样的。对于大模型,训练一次动辄上百万/千万美元的费用。合适的成本始终是正确的选择。
  • 训练类型:是否支持数据并行、张量并行、流水线并行、多维混合并行、自动并行等
  • 效率:将普通模型训练代码变为分布式训练所需编写代码的行数,我们希望越少越好。
  • 灵活性:你选择的框架是否可以跨不同平台使用?

常见的分布式训练框架

  • 第一类:深度学习框架自带的分布式训练功能。如:TensorFlow、PyTorch、MindSpore、Oneflow、PaddlePaddle等。
  • 第二类:基于现有的深度学习框架(如:PyTorch、Flax)进行扩展和优化,从而进行分布式训练。如:Megatron-LM(张量并行)、DeepSpeed(Zero-DP)、Colossal-AI(高维模型并行,如2D、2.5D、3D)、Alpa(自动并行)等

目前训练超大规模语言模型主要有两条技术路线

  1. TPU + XLA + TensorFlow/JAX :由Google主导,由于TPU和自家云平台GCP深度绑定
  2. GPU + PyTorch + Megatron-LM + DeepSpeed :由NVIDIA、Meta、MicroSoft大厂加持,社区氛围活跃,也更受到大家欢迎。

参数高效微调(PEFT)技术

在面对特定的下游任务时,如果进行Full FineTuning(即对预训练模型中的所有参数都进行微调),太过低效;而如果采用固定预训练模型的某些层,只微调接近下游任务的那几层参数,又难以达到较好的效果。

PEFT技术旨在通过最小化微调参数的数量和计算复杂度,来提高预训练模型在新任务上的性能,从而缓解大型预训练模型的训练成本。这样一来,即使计算资源受限,也可以利用预训练模型的知识来迅速适应新任务,实现高效的迁移学习。因此,PEFT技术可以在提高模型效果的同时,大大缩短模型训练时间和计算成本,让更多人能够参与到深度学习研究中来。

  • Prefix Tuning:与full fine-tuning更新所有参数的方式不同,该方法是在输入token之前构造一段任务相关的virtual tokens作为Prefix,然后训练的时候只更新Prefix部分的参数,而Transformer中的其他部分参数固定。该方法其实和构造Prompt类似,只是Prompt是人为构造的“显式”的提示,并且无法更新参数,而Prefix则是可以学习的“隐式”的提示。 同时,为了防止直接更新Prefix的参数导致训练不稳定的情况,他们在Prefix层前面加了MLP结构(相当于将Prefix分解为更小维度的Input与MLP的组合后输出的结果),训练完成后,只保留Prefix的参数。
  • Prompt Tuning:该方法可以看作是Prefix Tuning的简化版本,只在输入层加入prompt tokens,并不需要加入MLP进行调整来解决难训练的问题。随着预训练模型参数量的增加,Prompt Tuning的方法会逼近fine-tuning的结果。
  • P-Tuning:该方法的提出主要是为了解决这样一个问题:大模型的Prompt构造方式严重影响下游任务的效果。P-Tuning将Prompt转换为可以学习的Embedding层,并用MLP+LSTM的方式来对prompt embedding进行一层处理。
  • P-Tuning v2:让Prompt Tuning能够在不同参数规模的预训练模型、针对不同下游任务的结果上都达到匹敌Fine-tuning的结果。相比Prompt Tuning和P-tuning的方法,P-Tuning v2方法在多层加入了Prompts tokens作为输入,带来两个方面的好处:
    1. 带来更多可学习的参数(从P-tuning和Prompt Tuning的0.1%增加到0.1%-3%),同时也足够参数高效。
    2. 加入到更深层结构中的Prompt能给模型预测带来更直接的影响。
  • Adapter Tuning:该方法设计了Adapter结构(首先是一个down-project层将高维度特征映射到低维特征,然后过一个非线形层之后,再用一个up-project结构将低维特征映射回原来的高维特征;同时也设计了skip-connection结构,确保了在最差的情况下能够退化为identity),并将其嵌入Transformer的结构里面,在训练时,固定住原来预训练模型的参数不变,只对新增的Adapter结构进行微调。同时为了保证训练的高效性(也就是尽可能少的引入更多参数)。
  • LoRA:在涉及到矩阵相乘的模块,引入A、B这样两个低秩矩阵模块去模拟full fine-tuning的过程,相当于只对语言模型中起关键作用的低秩本质维度进行更新。

典型应用

  1. ChatGLM-Tuning :一种平价的chatgpt实现方案,基于清华的 ChatGLM-6B + LoRA 进行finetune。
  2. Alpaca-Lora:使用低秩自适应(LoRA)复现斯坦福羊驼的结果。Stanford Alpaca 是在 LLaMA 整个模型上微调,而 Alpaca-Lora 则是利用 Lora 技术,在冻结原模型 LLaMA 参数的情况下,通过往模型中加入额外的网络层,并只训练这些新增的网络层参数。由于这些新增参数数量较少,这样不仅微调的成本显著下降,还能获得和全模型微调类似的效果。
  3. BLOOM-LORA:由于LLaMA的限制,我们尝试使用Alpaca-Lora重新实现BLOOM-LoRA。

PEFT实现

  1. PEFT:Huggingface推出的PEFT库。
  2. unify-parameter-efficient-tuning:一个参数高效迁移学习的统一框架。

经验与教训

经验

  • 对于同一模型,选择不同的训练框架,对于资源的消耗情况可能存在显著差异(比如使用Huggingface Transformers和DeepSpeed训练OPT-30相对于使用Alpa对于资源的消耗会低不少)。
  • 进行大模型模型训练时,先使用小规模模型(如:OPT-125m/2.7b)进行尝试,然后再进行大规模模型(如:OPT-13b/30b...)的尝试,便于出现问题时进行排查。

教训

  • 针对已有的环境进行分布式训练环境搭建时,一定要注意之前环境的python、pip、virtualenv、setuptools的版本。不然创建的虚拟环境即使指定对了Python版本,也可能会遇到很多安装依赖库的问题。
  • 遇到需要升级GLIBC等底层库需要升级的提示时,一定要慎重,不要轻易升级,否则,可能会造成系统宕机或很多命令无法操作等情况。

结语

实践出真知,以上是这段时间进行大模型实践的一点点总结,写的有一些主观和片面,后续会持续更新自己研究大模型获得的一些认知和实践经验。

你可能感兴趣的:(人工智能工程化(MLOps),深度学习,人工智能,自然语言处理)