再议大模型微调之Zero策略

news/2024/9/24 16:31:23/

1. 引言

尽管关于使用Deepspeed的Zero策略的博客已经满天飞了,特别是有许多经典的结论都已经阐述了,今天仍然被问到说,如果我只有4块40G的A100,能否进行全量的7B的大模型微调呢?

正所谓“纸上得来终觉浅,绝知此事要躬行。”不能以“何不食肉糜?”来回复人家说,为啥不用4块80G的A100呢。我们也知道,如果手上有3090/4090级别的显卡,那基本上就是走lora训练,没有任何问题。如果有4块80G的A100,则闭眼走全量微调。但是如果有4块40G的A100呢?甚至说4块32G的V100行不行呢?

先说结论,可以!

2. 背景知识介绍

说到Deepspeed和Zero,相信大家对着一幅图一点都不陌生,被各个帖子广为传颂,用于介绍Zero-1/2/3之间的不同,非常形象直观,如果还想深入了解,参见《deepspeed官方介绍》(看一下,2021年Deepspeed就有这工具了,现在反而成了训练大模型的流行工具)。

在这里插入图片描述

2. 实验设置

我这里使用了1个50K样本的对话数据集,长度截断为1024,训练3个epoch,使用LLama_factory的脚本进行baichuan2的训练。其中zero_3的配置文件如下所示:

{"train_batch_size": "auto","train_micro_batch_size_per_gpu": "auto","gradient_accumulation_steps": "auto","gradient_clipping": "auto","zero_allow_untested_optimizer": true,"fp16": {"enabled": "auto","loss_scale": 0,"loss_scale_window": 1000,"initial_scale_power": 16,"hysteresis": 2,"min_loss_scale": 1},"bf16": {"enabled": "auto"},"zero_optimization": {"stage": 3,"offload_optimizer": {"device": "cpu","pin_memory": true},"offload_param": {"device": "cpu","pin_memory": true},"overlap_comm": true,"contiguous_gradients": true,"sub_group_size": 1e9,"reduce_bucket_size": "auto","stage3_prefetch_bucket_size": "auto","stage3_param_persistence_threshold": "auto","stage3_max_live_parameters": 1e9,"stage3_max_reuse_distance": 1e9,"stage3_gather_16bit_weights_on_model_save": true}
}

在4卡A100上,各个模式的训练情况如下:

模式batch大小显存占用最大GPU训练时间
Zero-3batch=2, accu=268GB15小时
Zero-3 offloading parambatch=2, accu=221G41小时
Zero-3 offloading optimizer+parambatch=2, accu=217G44小时
Zero-3 offloading optimizer+parambatch=4, accu=421G13小时
Zero-3 offloading optimizer+parambatch=8, accu=435G7小时

尽管使用了更大的batch_size可以更快地训练,但是最后一行需要50G的物理内存和100G的虚拟内存作为支撑。如果硬盘和内存的性能都不高的话,会更差一些。

因此,通过实验,我们可以知道,使用40G的A100也是可以训练的,但是通过offloading的方式可以将优化器和参数都存放到内存上,缓解显存占用情况。《Zero各个stage的状态详解》和《Zero的基础验算》会给出一个理论计算结果。

3. 其他一些训练小Tricks

3.1 使用offloading遇到AttributeError: ‘DeepSpeedCPUAdam‘ object has no attribute ‘ds_opt_adam错误

这是由于cuda和cuda tookit的版本不一致造成的,理论上,nvidia-smi的cuda版本优先级比nvcc -V的cuda版本优先级要高,因此nvidia-smi的cuda是硬约束条件,需要保证nvcc -V的cuda版本<=nvidia-smi的cuda版本。在此基础上,就可以使用《deepspeed使用zero3 + offload报错》提供的方案:

export DS_SKIP_CUDA_CHECK=1

来解决这个错误,将此变为警告。

如果想本质解决这个问题,而又有管理员权限的话,可以考虑映射一下两者,具体参考《nvcc和cuda版本不一致问题怎么解决》。

3.2 使用offloading报错RuntimeError: Expected all tensors to be on the same device, but found at least two devices, cuda:0 and CPU!

这是由于Deepspeed V0.14.1的BUG导致的,回退到V0.14.0即可。也可以参见DeepSpeed的issues。(这是一个好习惯,首先先看项目的Issue里有没有相关问题。)

3.3 训练策略

将batch_size设置为1,通过梯度累积实现任意的有效batch_size
如果OOM则,设置–gradient_checkpointing 1 (HF Trainer),或者 model.gradient_checkpointing_enable()
如果OOM则,尝试ZeRO stage 2
如果OOM则,尝试ZeRO stage 2 + offload_optimizer
如果OOM则,尝试ZeRO stage 3
如果OOM则,尝试offload_param到CPU
如果OOM则,尝试offload_optimizer到CPU
如果OOM则,尝试降低一些默认参数。比如使用generate时,减小beam search的搜索范围
如果OOM则,使用混合精度训练,在Ampere的GPU上使用bf16,在旧版本GPU上使用fp16
如果仍然OOM,则使用ZeRO-Infinity ,使用offload_param和offload_optimizer到NVME
一旦使用batch_size=1时,没有导致OOM,测量此时的有效吞吐量,然后尽可能增大batch_size
开始优化参数,可以关闭offload参数,或者降低ZeRO stage,然后调整batch_size,然后继续测量吞吐量,直到性能比较满意(调参可以增加66%的性能)

3.4 训练速度和显存需求

从左到右,越来越慢
Stage 0 (DDP) > Stage 1 > Stage 2 > Stage 2 + offload > Stage 3 > Stage 3 + offloads
从左到右,所需GPU显存越来越少
Stage 0 (DDP) < Stage 1 < Stage 2 < Stage 2 + offload < Stage 3 < Stage 3 + offloads

关于Zero-0/1/2/3/infinity的配置文件样例,参见《Deepspeed详解》和《分布式训练实践》。


http://www.ppmy.cn/news/1456779.html

相关文章

常见比较实用的Chrome命令/扩展程序

文章目录 一、Chrome命令二、Chrome操作三、Chrome扩展程序 一、Chrome命令 Chrome浏览器提供了一系列实用的内部命令和URL&#xff0c;这些命令可以帮助用户快速访问浏览器的各种功能和设置。以下是一些实用的Chrome命令&#xff1a; 查看所有支持的命令&#xff1a; 直接在…

(✌)粤嵌—2024/5/7—除自身以外数组的乘积

代码实现&#xff1a; /*** Note: The returned array must be malloced, assume caller calls free().*/ int* productExceptSelf(int *nums, int numsSize, int *returnSize) {// 左乘积int l[numsSize];l[0] 1;for (int i 1; i < numsSize; i) {l[i] l[i - 1] * nums[…

使用Simulink Test进行单元测试

本文摘要&#xff1a;主要介绍如何利用Simulink Test工具箱&#xff0c;对模型进行单元测试。内容包括&#xff0c;如何创建Test Harness模型&#xff0c;如何自动生成excel格式的测试用例模板来创建测试用例&#xff0c;如何手动填写excel格式的测试用例模板来手动创建测试用例…

QT creator qt6.0 使用msvc2019 64bit编译报错

qt creator qt6.0报错&#xff1a; D:\Qt6\6.3.0\msvc2019_64\include\QtCore\qglobal.h:123: error: C1189: #error: "Qt requires a C17 compiler, and a suitable value for __cplusplus. On MSVC, you must pass the /Zc:__cplusplus option to the compiler."…

《QT实用小工具·六十》Qt 多列时间轴控件

1、概述 源码放在文章末尾 Qt 多列时间轴控件。 可与多段字符串格式自由转换&#xff0c;也可手动添加列表项。 专门用来以时间轴作为事件线发展顺序的故事大纲。 特点 时间背包功能&#xff1a;记录所有物品或属性发生的变化&#xff0c;随时回溯 时间可输入任意内容&…

深入Django:用户认证与权限控制实战指南

title: 深入Django&#xff1a;用户认证与权限控制实战指南 date: 2024/5/7 18:50:33 updated: 2024/5/7 18:50:33 categories: 后端开发 tags: AuthDecoratorsPermissionsGuardianRESTAuthSessionMgmtMFA 第1章&#xff1a;入门Django与设置 1.1 Django安装与环境配置 在…

【LeetCode题库】1068. 产品销售分析 I —— MySQL 性能提升,using()关键字

文章目录 原题题解解题笔记 —— JOIN USING()关键字对性能的提升 我是一名立志把细节都说清楚的博主&#xff0c;欢迎【关注】&#x1f389; ~ 原创不易&#xff0c; 如果有帮助 &#xff0c;记得【点赞】【收藏】 哦~ ❥(^_-)~ 如有错误、疑惑&#xff0c;欢迎【评论】指正…

四川古力未来科技抖音小店安全:守护您的网购体验

在互联网购物日益普及的今天&#xff0c;四川古力未来科技抖音小店以其独特的魅力和安全保障措施&#xff0c;成为越来越多消费者信赖的购物平台。本文将为您详细解读四川古力未来科技抖音小店的安全保障措施&#xff0c;让您在享受便捷购物的同时&#xff0c;也能安心、放心。…