deepspeedԴ?码解???
Deepspeed训练使用已集成至git代码训练框架项目,此项目提供构建开源大模型训练框架的码解基础流程,并支持主流模型使用deepspeed进行Lora、码解Qlora等训练与主流模型的码解搭建博客的源码chat template模版等。
Deepspeed的码解核心是Zero策略,它包括ZeRO训练的码解Stages1, 2和3,旨在优化模型训练过程中的码解内存使用。
在训练模型时,码解显存主要用于模型参数、码解梯度、码解优化器与激活值四个部分。码解ZeRO策略特别针对梯度与优化器进行优化,码解支持完整的码解ZeRO Stages,简化内存管理。
Deepspeed的Zero策略通过Zero-2与Zero-3实现,配置示例与更详细的参数解析可参阅官方文档。
在单节点训练场景下,即单机单卡或单机多卡,应避免使用CUDA_VISIBLE_DEVICES与Deepspeed冲突。正确的做法是在localhost后指定训练用GPU。
与Trainer一起使用时,Deepspeed支持四种不同的混合方式。常见的组合是直接使用DS的AdamW优化器与DS的WarmupLR优化器,其中WarmupLR相当于HF的lr_scheduler_type中的constant_with_warmup类型,参数默认为auto。
Deepspeed配置与Trainer TrainingArguments的优先级问题,模型训练时首先查看ds config中的相关配置,若有则直接使用,若无则使用Trainer配置。若两边均配置,Trainer配置将失效。
使用Deepspeed与Trainer集成的训练代码非常简单,只需在TrainingArguments中配置即可。
训练命令参考官方源码,使用非常简洁,读者可根据文档进行实践。
查阅Deepspeed官方文档获取更多详细信息与支持。
官方链接:deepspeed.ai/docs/confi...
推荐阅读:DeepSpeed文档,了解全面用法。
关注官方GitHub问题讨论,解决使用过程中的具体问题。
LM训练 ZeRO系列
分布式训练的几个主题包括:
LLM训练 分布式通信,LLM训练 显存占用分析,LLM训练 高效训练方法,LLM训练 数据并行,LLM训练 ZeRO系列,LLM训练 流水线并行,LLM训练 张量并行,LLM训练 Megatron-LM 源码分析。
微软发布了四篇论文:
ZeRO: Memory optimizations Toward Training Trillion Parameter Models (/) - 提出了ZeRO-DP和 ZeRO-R
ZeRO-Offload: Democratizing Billion-Scale Model Training (/) - 微软
ZeRO-Infinity: Breaking the GPU Memory Wall for Extreme Scale Deep Learning (/) - 微软
ZeRO++: Extremely Efficient Collective Communication for Giant Model Training (/) - 微软
ZeRO1.1 概览
ZeRO包含两组优化:
(1)ZeRO-DP:减少模型状态PGO的显存占用
(2)ZeRO-R:减少剩余显存的消耗。
1.2 ZeRO-DP
目标是优化数据并行,减少显存冗余,最小化通信量。
原理是使用动态通信策略来分区优化器状态、梯度和参数。aocs源码
实现是对模型参数进行分区,梯度也相应分区,优化器只优化本分区的参数。
两个原则:类型:
1.2.1 ZeRO-Stage 1
原理是对优化器状态进行分区,每个rank更新相应参数后,收集构成完整模型。
流程:通信分析:单个GPU总通信量为2*ψ。
1.2.2 ZeRO-Stage 2
在Stage1基础上,对梯度进行分区。
ZeRO-2分割Optimizer States与Gradients。
用完即删原则:每个rank只对自己负责的参数Pi的梯度进行规约。
通信分析:同ZeRO-Stage1,单个GPU总通信量为2*ψ。
1.2.3 ZeRO-Stage 3
在Stage1/Stage2基础上,对模型参数进行分区。
ZeRO-3分割Optimizer States、Gradients和Parameters。
需要用时去取原则:计算特定layer时,对参数进行all-gather。
通信分析:单个GPU总通信量为3*ψ。
1.2.4 动画视频
The video below shows how ZeRO (with all three stages) performs a training step including forward pass, backward pass, and parameter update.
1.2.5 实验效果
实验配置:G 8*A、全参训练,bs=1,checkpointing=True。
实验全参训练,最多只能跑B模型,B模型跑不起来。
1.2.6 ZeRO-DP VS DDP
1.3 ZeRO-R
1.3.1 中间激活值
认为checkpoint方法虽然有用,但在大型LLM中激活值仍然占用大量显存。
eg:B的LLM,bs=,激活值显存占用GB。
方法:Offload到CPU中。
1.3.2 临时缓存区
在梯度reduce操作中,用于存储中间结果的临时缓冲区会消耗大量显存。
方法:申请固定大小的缓存区 constant size buffers 。
1.3.3 内存碎片
原因:内存碎片是tensor生命周期错配的结果。
问题:即使有足够的显存,可能会因为缺少连续内存而使得内存分配失败。
方法:ZeRO为激活检查点和梯度预先分配连续内存块,并在初始化时将它们复制到预先分配的连续内存中。
2、ZeRO-Offload
利用CPU内存来解决GPU显存不足的问题。
CPU:参数更新在CPU完成。
GPU:前向和后向的计算在GPU上完成。
3、ZeRO-Infinity
利用外接存储设备来解决GPU显存不足的问题。
4、ZeRO++
to do...
5、Deepspeed ZeRO源码
5.1 入口
5.1.1 总入口initialize()
源码地址:deepspeed.__init__
简介:选择不同的engin引擎。
5.1.2 ZeRO引擎DeepSpeedEngine
源码地址:deepspeed.runtime.engine
整体流程及关键方法如下所示:
(1)DeepSpeedEngine.init
核心内容:最重要的就是对优化器(Optimizer)的初始化。
ZeRO 的核心特性的实现都在优化器(Optimizer)中,核心方法_configure_zero_optimizer() 。
stage1/2 优化器:DeepSpeedZeroOptimizer
stage3 优化器:DeepSpeedZeRoOffload
(2)DeepSpeedEngine.forward
核心内容:在模型model进行前向传播,返回loss,ZeRO不需要进行特殊处理
(3)DeepSpeedEngine.backward
核心内容:获得各个rank上对应分片参数Pi的entityjava源码梯度Gi。
self.optimizer.backward()
Zero stage1:self.optimizer.reduce_gradients()
Zero stage2:self.overlapping_partition_gradients_reduce_epilogue
(4)DeepSpeedEngine.step
核心内容:基于梯度Gi更新对应的分片参数Pi,各rank收集最新的、完整的模型参数P
self.optimizer.step()
self.optimizer.zero_grad()
5.2 DeepSpeedZeroOptimizer
源码地址:deepspeed.runtime.zero.stage_1_and_2
简介:stage1/2 优化器,对参数的Optimizer States与Gradients进行分割。
5.2.1 init
核心思路:ZeRO初始化时候会对参数进行均匀切分给各个rank。通过参数分区,进而实现梯度、优化器的分区。
除此之外,注册梯度钩子函数reduce_partition_and_remove_grads(当梯度计算完成时自动调用该函数)
5.2.2 forward
在模型model进行前向传播,返回loss,ZeRO不需要进行特殊处理。
5.2.3 backward
5.2.4 reduce_ipg_grads()
ipg:Independent Parallel Gradient
简介:对连续的ipg梯度进行reduce。
DeepSpeed源码笔记3优化器
DeepSpeedZeroOptimizer_Stage3 是一个用于训练大模型的优化器,专门针对zero stage 3的策略。它通过将参数W划分为多份,每个GPU各自维护优化器状态、梯度和参数,以实现高效并行计算。具体实现过程如下:
在进行前向计算时,每个GPU负责其部分数据,所有GPU的数据被分成了三份,每块GPU读取一份。完成前向计算后,GPU之间执行all-gather操作,合并所有GPU的参数W,得到完整的W。
在执行反向传播时,同样进行all-gather操作,收集所有GPU的完整W,然后执行梯度计算。完成反向传播后,立即释放不属于当前GPU管理的W。
在计算梯度后,通过reduce-scatter操作聚合所有GPU的梯度G,得到完整的梯度。接着,释放非当前GPU管理的梯度G。最后,使用当前GPU维护的部分优化器状态O和聚合后的梯度G来更新参数W,无需额外的allreduce操作。
初始化阶段包括设置参数和配置,如optimizer、flatten、unflatten、dtype、gradient_accumulation_dtype等。这些配置决定了优化器的运行方式和性能。初始化还包括创建参数分组和设置特定的分片操作。
分配模型参数到各个GPU上,通过多种方法如创建参数分组、创建参数子分组等进行细致的划分和管理。这些分组和子分组的创建和管理,是为了更有效地进行梯度聚合和参数更新。
在执行反向传播后,调用LossScaler进行梯度计算,jdkobject源码随后通过特定的钩子函数(如reduce_partition_and_remove_grads)进行梯度聚合和释放。
执行优化器的step方法时,进行归一化梯度计算、更新参数和优化器状态,并在完成后清理和更新模型参数。此过程包括执行反向梯度聚合、更新模型参数权重、清理优化器状态和参数。
DeepSpeedZeRoOffload模块则负责模型参数的划分和管理工作,包括初始化、参数划分和状态更新等。初始化阶段会根据配置将参数分配到不同GPU上,并进行状态更新和参数访问的优化。
在进行参数划分时,首先将模型参数划分为非划分和划分的参数,并根据划分状态进一步处理。初始化外部参数后,会更新模块的状态,包括所有参数的存储位置和管理策略。
在执行partition_all_parameters方法时,根据GPU数量和参数大小计算每个GPU需要处理的部分,从模型参数中提取并分割到对应的GPU上,释放原参数并更新参数状态。
Init过程涉及到初始化配置、实现特定方法(如all_gather、partition等)和状态更新,确保模型参数能被正确地在不同GPU间共享和管理。对于特定的GPU(如主GPU),还会使用广播操作将参数分发给其他GPU。
第四课:XTuner 微调 LLM:1.8B、多模态、Agent
在本课程中,我们将带领大家体验如何利用XTuner完成个人小助手的微调过程,以实现定制化功能并优化性能。我们将通过对比微调前后的大模型,直观展示微调的效果与重要性。 首先,为了快速上手并对比微调效果,我们将采用上一期课后作业中使用QLoRA方式微调个人小助手的案例。直观对比结果如下: 微调前: 微调后: 明显可见,微调后的模型能够被调整成我们期望的样子。接下来,我们详细介绍微调的实现步骤。开发环境准备
1. 创建开发环境:访问InternStudio,创建开发机并选择合适的镜像和资源配置,确保具备运行XTuner所需的环境。 2. 进入终端界面,开始操作。 完成准备工作后,即可进入微调之旅。快速上手指南 为帮助您快速上手,我们将提供XTuner运行原理概述和关键步骤指引。环境安装
1. 安装XTuner源码到本地,便于后续使用。 2. 若安装速度较慢,可尝试使用优化方法提高效率。gpdb源码前期准备
数据集准备:创建文件夹,存放训练所需数据,生成包含输入和输出的数据对,根据需求调整数据集大小。 模型准备:选择适合微调的模型,如InternLM2-Chat-1.8B,直接使用代码创建文件夹并复制模型文件。 配置文件选择与修改:根据微调方法(如QLoRA)和模型类型选择配置文件,并根据实际需求进行调整。配置文件修改
完成数据集、模型和配置文件的准备后,通过XTuner工具箱中的工具进行配置文件的复制和修改,确保其符合微调需求。模型训练
1. 使用XTuner启动训练过程,确保文件保存路径正确,以便后续转换和整合。 2. 结合XTuner内置的deepspeed加速训练,选择合适类型(如deepspeed_zero1、deepspeed_zero2或deepspeed_zero3)。 3. 训练完成后,评估模型性能,对比微调前后差异。模型转换与整合
1. 将Pytorch训练的权重文件转换为Huggingface格式。 2. 准备原模型、训练好的adapter层和最终保存路径,使用XTuner指令整合模型。 3. 完成整合后,模型可用于对话测试,验证微调效果。对话测试与部署
1. 使用XTuner提供的对话代码与Huggingface格式模型进行对话,测试模型性能。 2. 部署模型到网页端demo,提供更广泛的用户体验。总结与作业
本课程涵盖了XTuner微调流程的关键步骤,包括环境搭建、数据集准备、模型与配置文件使用、训练、转换与整合、测试与部署。通过实践,您将能掌握微调技术的核心,实现个性化小助手。 完成作业,请访问指定链接。ML system 入坑指南
欢迎进入机器学习系统(ML system)的广阔领域。随着ChatGpt等大模型的兴起,人们愈发关注大模型的实际落地。然而,除了先进的算法,背后支撑的ML system——从分布式训练到高效推理的完整链路同样至关重要。优秀的基础设施是应用爆发的基石。对于刚刚踏入这个领域的“新手”以及对ML system感兴趣但并非该领域背景的其他领域人士,本文将分享个人的学习历程和指引,希望能为你们提供入门和进一步探索的指南。 让我们先从课程入手。学习路径的构建离不开坚实的知识基础。首先,掌握计算机基础,如数据结构,这是必不可少的。接下来,让我们深入探讨更专业性进阶课程: 南京大学JYY老师的操作系统课程:课程内容深入且作业繁重,质量与四大课程相当。 MIT的6.S操作系统课程:提供全面的资料、实验(lab)以及课程内容。 CMU的并行计算课程:介绍现代多处理器、CPU加速、分布式通讯协议、GPU加速(CUDA编程)、异构计算、同步和缓存等核心概念。 UCB的cs课程:专注于高性能计算(HPC)的原理和应用。 MIT的分布式系统课程:使用Go语言实现,了解传统分布式系统知识和历史对于现代分布式机器学习系统的学习具有一定的帮助,但并非必需。 在课程之外,还有专门针对机器学习系统的课程: CMU的深度学习系统课程:由陈天奇老师讲授,涵盖神经网络库实现、自动微分、GPU加速、模型部署和AI编译部分内容。课程内容全面,适合有一定基础的学习者阅读或作为参考。 Mini torch:一个用Python实现的简单版本torch,涉及自动微分、张量、GPU加速,适合新手入门。 MIT的Tiny ML课程:针对移动设备和嵌入式系统的课程,感谢@江湖骗子 @Lyken 学长的补充。 此外,还有华为Mindspore团队(我曾在此实习的团队)和一群专家联合推出的课程,涵盖了计算图、编译器前后端、分布式训练等内容,适合有一定基础的学习者阅读或作为工具书使用。微软发起的系统为AI工具书,正在快速迭代更新,补充基础知识。陈天奇老师的AI编译器课程以TVM为基础,是前沿领域的少数课程之一。对于大型模型的学习,理解最新的算法和模型架构变化是非常必要的,虽然很难有系统的课程,但通过阅读论文、官方网站、博客等资源,可以紧跟业界进展。可以参考李沐老师的论文精讲,关注影响力巨大的工作,如“多就是一切”(Muli is all you need)。
对于大规模分布式训练,目前没有非常系统的课程,但了解分布式训练的基本知识、并行策略和显存优化策略等对于学习者至关重要。这里简单总结了几个关键知识点和参考论文。
编程语言方面,Python是首选,但了解如何调用C(如Cpython、pybind)以及Python高级特性(如hook、装饰器)对于ML sys领域很有帮助。CUDA、OpenCL等并行计算技术也是非Nvidia芯片设备(如手机SoC)上进行异构加速的通用方案。
此外,还有一些工具和框架,如TensorRT、AI Template、Severing Triton-inference-server、clip-as-service、Mobile inference等,涵盖了推理引擎、模型服务等不同方面。对于分布式训练,ColossalAI、Megatron-LM、Deepspeed、huggingface accelerate、Bagua等框架提供了不同层次的支持,帮助解决大规模模型训练中的问题。
最后,对于学习者来说,探索源码、实际案例学习是深入理解ML sys领域知识的绝佳途径。此外,编程语言(如C++、Python)、CUDA、OpenCL等并行计算技术、分布式通讯技术以及大型深度学习框架(如TensorFlow、PyTorch)等都是学习的必备知识。同时,了解AI编译器、模型优化技术、系统设计和实现等方面的知识,对于构建高效、可扩展的机器学习系统至关重要。
极智AI | Colossal-AI高效异构内存管理系统
Colossal-AI高效异构内存管理系统旨在解决大模型训练中遇到的内存挑战。通过合理利用CPU内存和SSD硬盘,以及在GPU之间灵活转移数据,系统可以有效提升模型训练的效率和规模。
在数据并行训练场景下,传统做法直接在每个GPU上加载数据,导致内存冗余问题。微软的Deepspeed通过将其模型参数、梯度和优化器状态切分存储在不同GPU上,解决了内存浪费问题。此外,Deepspeed还支持模型参数卸载到CPU和NVMe硬盘,进一步提高GPU内存利用率,支持更大模型的训练。
ZeRO (Zero Redundancy Optimizer)是Deepspeed提出的异构内存管理解决方案,通过动态卸载数据到CPU或硬盘,消除内存冗余。然而,静态的内存管理策略在不同训练阶段可能产生内存浪费,限制了其效能。
Colossal-AI的Gemini内存管理系统采用基于块的内存管理策略,通过块机制优化张量移动。Gemini使用有限状态机来管理张量生命周期,根据算子执行前和后进行内存操作,实现动态内存管理。此外,Gemini通过最佳页面替换算法(如OPT)减少内存移动量,确保内存资源高效利用。
在数据块切分上,Gemini采用了对称切分方案,允许所有GPU进行数据移动,充分利用PCIE带宽,提高GPU与CPU间数据传输速度。同时,内存空间重用技术在不同时间节点之间共享同一块内存空间,进一步支持大规模训练。
通过Colossal-AI的Gemini内存管理系统,模型训练效率显著提升,可以充分利用GPU、CPU及硬盘资源,实现更大规模模型的高效训练。代码示例展示了如何在实际项目中应用Colossal-AI,提供了一个简单而强大的框架,使得AI项目更易于实施和管理。
加入知识星球「极智视界」,获取更多AI项目源码下载,畅享人工智能的科技魅力,让好玩的AI项目不再难玩。在这里,你将获得大量精心整备的AI项目,涵盖人脸、检测、分割、多模态、AIGC、自动驾驶、工业等领域,持续更新更多有趣项目。
一文了解预训练相关加速技巧
探索深度学习训练加速秘籍:deepspeed、Megatron与OneFlow
训练大模型不再是难题,得益于一系列开源工具。deepspeed,由微软打造,提供了强大的并行训练框架,包括3D并行性,特别是流水线并行、ZeRO内存优化技术。
首先,deepspeed的3D并行性关注数据、模型和流水线的协同工作。数据并行通过分散数据至多台worker,但通信开销大。模型并行则是将模型的不同层分布在不同设备上,流水线并行如PipeDream,通过分层并行计算,减少了通信瓶颈。PipeDream的挑战在于自动分层和权重管理,如Weight Stashing和Vertical Sync,确保一致性。
ZeRO内存优化技术解决了GPU内存瓶颈问题,如GPT-2模型在单GPU上内存不足。ZeRO通过在多设备间共享计算和内存资源,减少每个GPU的负担,特别是通过ZeRO-DP和ZeRO-Offload,将参数和梯度分布在CPU和GPU之间,显著降低内存需求。
NVIDIA的Megatron是专为GPT的模型库,集成了数据并行与模型并行,包括Tensor并行和Pipeline并行,旨在高效地扩展训练规模。OneFlow则以优化见长,减少了全局内存访问,通过延迟隐藏和梯度累加提高性能,尽管其MoE框架还未开源,但整体上展现了多种并行策略的整合。
比如,PaddlePaddle采用2D和3D并行策略,百度的"4D混合并行"是多种并行策略的综合应用。还有混合精度和后向重计算等优化手段,如Checkpointing,通过重新计算部分前向激活以节省内存。
这些工具和方法的出现,极大地推动了大模型训练的效率,但不断的技术迭代和优化仍在继续。深入理解并利用这些技巧,将助力你在深度学习的征途中加速前行。
参考文献:
[1] 掘金:深度学习流水线并行之PipeDream
[2-4] ZeRO相关论文
[5] ZeRO-Offload
[6] ZeRO-Infinity
[7] NVIDIA Megatron
[8-] 大模型训练实践与分析文章
[-] 优化方法与源码解析
自然语言处理大模型BLOOM模型结构源码解析(张量并行版)
BLOOM模型结构解析,采用Megatron-DeepSpeed框架进行训练,张量并行采用1D模式。基于BigScience开源代码仓库,本文将详细介绍张量并行版BLOOM的原理和结构。 单机版BLOOM解析见文章。 模型结构实现依赖mpu模块,推荐系列文章深入理解mpu工具。 Megatron-DeepSpeed张量并行工具代码mpu详解,覆盖并行环境初始化、Collective通信封装、张量并行层实现、测试以及Embedding层、交叉熵实现与测试。 Embedding层:Transformer Embedding层包含Word、Position、TokenType三类,分别将输入映射为稠密向量、注入位置信息、类别信息。通常,位置信息通过ALiBi注入,无需传统Position Embedding,TokenType Embedding为可选项。张量并行版BLOOM Embedding层代码在megatron/model/language_model.py,通过参数控制三类Embedding使用。 激活函数:位于megatron/model/utils.py,BLOOM激活函数采用近似公式实现。 掩码:张量并行版模型用于预训练,采用Causal Mask确保当前token仅见左侧token。掩码实现于megatron/model/fused_softmax.py,将缩放、mask、softmax融合。 ALiBi:位置信息注入机制,通过调整query-key点积中静态偏差实现。8个注意力头使用等比序列m计算斜率,个头则有不同序列。实现于megatron/model/transformer.py。 MLP层:全连接层结构,列并行第一层,行并行第二层,实现于megatron/model/transformer.py。 多头注意力层:基于标准多头注意力添加ALiBi,简化版代码位于megatron/model/transformer.py。 并行Transformer层:对应单机版BlookBlock,实现于megatron/model/transformer.py。 并行Transformer及语言模型:ParallelTransformer类堆叠多个ParallelTransformerLayer,TransformerLanguageModel类在开始添加Embedding层,在末尾添加Pooler,逻辑简单,代码未详述。 相关文章系列覆盖大模型研究、RETRO、MPT、ChatGLM-6B、BLOOM、LoRA、推理工具测试、LaMDA、Chinchilla、GLM-B等。2024-11-30 15:19
2024-11-30 14:35
2024-11-30 14:23
2024-11-30 13:55
2024-11-30 12:52