Hugging Face Accelerate 两个后端的故事:FSDP 与 DeepSpeed

hugging,face,accelerate,fsdp,deepspeed · 浏览次数 : 0

小编点评

本文主要讨论了社区中两个流行的零冗余优化器(Zero Redundancy Optimizer,ZeRO)算法实现:DeepSpeed 和 PyTorch FSDP(Fast Scaleout Data Parallelism)。Hugging Face Accelerate 对这两者都进行了集成,并通过接口暴露出来,以供最终用户在训练/微调模型时自主选择其中之一。本文重点介绍了 Accelerate 对外暴露的这两个后端之间的差异,并提供了一个概念指南来帮助用户在两个框架之间无缝切换。 1. **DeepSpeed 和 FSDP 的差异**: - DeepSpeed 是 DeepSpeed 库中的一个零冗余优化器,它通过分片优化器和参数来提高训练效率。 - FSDP(Fast Scaleout Data Parallelism)是 PyTorch 中的一个零冗余优化器,它通过在每个 GPU 上展平参数来提高训练效率。 - 在 Hugging Face Accelerate 中,DeepSpeed 和 FSDP 可以互换使用,但需要注意 GPU 数量对学习率的影响。 2. **精度相关的问题**: - DeepSpeed 内部执行了精度上转,始终将主权重保持为 fp32 精度。 - FSDP 在把模型和优化器参数分片到各 GPU 上之前,这些参数首先会被“展平”为一维张量。 - 这种精度差异可能导致 DeepSpeed 和 FSDP 在损失函数收敛性上存在差异。 3. **FSDP 的低精度模式**: - FSDP 的 PyTorch 原生实现不会强制上转,而是支持用户以低精度操作 PyTorch 优化器。 - 相比 DeepSpeed,FSDP 提供了更大的灵活性,特别是在内存受限的场景下。 4. **在 Accelerate 中对齐 DeepSpeed 和 FSDP 的行为**: - 通过在 Accelerate 中启用混合精度时自动对 FSDP 执行上转,可以更好地对齐 DeepSpeed 和 FSDP 的行为。 - 提供了一个 PR,使得 FSDP 能够以两种模式运行:与 DeepSpeed 一致的混合精度模式和针对内存受限场景的低精度模式。 5. **吞吐量测试结果**: - 使用 IBM Granite 7B 模型(其架构为 Meta Llama2)进行吞吐量比较。 - FSDP 和 DeepSpeed 在每 GPU 每秒词元数和每步耗时(s)浮点算力利用率(MFU)方面表现类似。 总的来说,DeepSpeed 和 FSDP 都是有效的零冗余优化器,它们在训练效率上有互补之处。用户可以根据自己的需求和硬件环境选择合适的优化器。同时,Hugging Face Accelerate 的概念指南为开发者提供了一个清晰的路径,以便在两个框架之间平滑过渡。

正文

社区中有两个流行的 零冗余优化器(Zero Redundancy Optimizer,ZeRO) 算法实现,一个来自 DeepSpeed,另一个来自 PyTorch。Hugging Face Accelerate 对这两者都进行了集成并通过接口暴露出来,以供最终用户在训练/微调模型时自主选择其中之一。本文重点介绍了 Accelerate 对外暴露的这两个后端之间的差异。为了让用户能够在这两个后端之间无缝切换,我们在 Accelerate 中合并了 一个精度相关的 PR一个新的概念指南

FSDP 和 DeepSpeed 可以互换吗?

最近,我们尝试分别使用 DeepSpeed 和 PyTorch FSDP 进行训练,发现两者表现有所不同。我们使用的是 Mistral-7B 基础模型,并以半精度(bfloat16)加载。可以看到 DeepSpeed(蓝色)损失函数收敛良好,但 FSDP(橙色)损失函数没有收敛,如图 1 所示。

我们猜想可能需要根据 GPU 数量对学习率进行缩放,且由于我们使用了 4 个 GPU,于是我们将学习率提高了 4 倍。然后,损失表现如图 2 所示。

看起来,通过按 GPU 数量缩放 FSDP 学习率,已经达到了预期!然而,当我们在不进行缩放的情况下尝试其他学习率(1e-5)时,我们却又观察到这两个框架的损失和梯度范数特征又是趋近一致的,如图 3 所示。

精度很重要

DeepSpeed 代码库的 DeepSpeedZeroOptimizer_Stage3(顾名思义,处理第 3 阶段优化器分片)实现代码中,我们注意到 trainable_param_groups(可训参数组)被传入一个内部函数 _setup_for_real_optimizer,该函数会调用另一个名为 _create_fp32_partitions 的函数。正如其名称中的 fp32 所示,DeepSpeed 内部执行了精度上转,并在设计上始终将主权重保持为 fp32 精度。而上转至全精度意味着:同一个学习率,上转后的优化器可以收敛,而原始低精度下的优化器则可能不会收敛。前述现象就是这种精度差异的产物。

在 FSDP 中,在把模型和优化器参数分片到各 GPU 上之前,这些参数首先会被“展平”为一维张量。FSDP 和 DeepSpeed 对这些“展平”参数使用了不同的 dtype,这会影响 PyTorch 优化器的表现。表 1 概述了两个框架各自的处理流程,“本地?”列说明了当前步骤是否是由各 GPU 本地执行的,如果是这样的话,那么上转的内存开销就可以分摊到各个 GPU。

流程 本地? 框架 详情
模型加载(如 AutoModel.from_pretrained(..., torch_dtype=torch_dtype)
准备,如创建“展平参数” FSDP
DeepSpeed
使用 torch_dtype
不管 torch_dtype,直接创建为 float32
优化器初始化 FSDP
DeepSpeed
torch_dtype 创建参数
float32 创建参数
训练步(前向、后向、归约) FSDP
DeepSpeed
遵循 fsdp.MixedPrecision
遵循 deepspeed_config_file 中的混合精度设置
优化器(准备阶段) FSDP
DeepSpeed
按需上转至 torch_dtype
所有均上转至 float32
优化器(实际执行阶段) FSDP
DeepSpeed
torch_dtype 精度进行
float32 精度进行

表 1: FSDP 与 DeepSpeed 混合精度处理异同

几个要点:

  • 正如 🤗 Accelerate 上的这一问题所述,混合精度训练的经验法则是将可训参数精度保持为 float32
  • 当在大量 GPU 上进行分片时,上转(如 DeepSpeed 中所做的那样)对内存消耗的影响可能可以忽略不计。然而,当在少量 GPU 上使用 DeepSpeed 时,内存消耗会显著增加,高达 2 倍。
  • FSDP 的 PyTorch 原生实现不会强制上转,其支持用户以低精度操作 PyTorch 优化器,因此相比 DeepSpeed 提供了更大的灵活性。

在 🤗 Accelerate 中对齐 DeepSpeed 和 FSDP 的行为

为了在🤗 Accelerate 中更好地对齐 DeepSpeed 和 FSDP 的行为,我们可以在启用混合精度时自动对 FSDP 执行上转。我们为此做了一个 PR,该 PR 现已包含在 0.30.0 版本中了。

有了这个 PR,FSDP 就能以两种模式运行:

  • 与 DeepSpeed 一致的混合精度模式
  • 针对内存受限场景的低精度模式,如图 4 所示。

表 2 总结了两种新的 FSDP 模式,并与 DeepSpeed 进行了比较。

框架 模型加载 (torch_dtype) 混合精度 准备(本地) 训练 优化器(本地)
FSDP(低精度模式) bf16 缺省(无) bf16 bf16 bf16
FSDP(混合精度模式) bf16 bf16 fp32 bf16 fp32
DeepSpeed bf16 bf16 fp32 bf16 fp32

表 2:两种新 FSDP 模式总结及与 DeepSpeed 的对比

吞吐量测试结果

我们使用 IBM Granite 7B 模型(其架构为 Meta Llama2)进行吞吐量比较。我们比较了模型的浮点算力利用率 (Model Flops Utilization,MFU) 和每 GPU 每秒词元数这两个指标,并针对 FSDP(完全分片)和 DeepSpeed(ZeRO3)两个场景进行了测量。

如上文,我们使用 4 张 A100 GPU,超参如下:

  • batch size 为 8
  • 模型加载为 torch.bfloat16
  • 使用 torch.bfloat16 混合精度

表 3 表明 FSDP 和 DeepSpeed 的表现类似,这与我们的预期相符。

随着大规模对齐技术(如 InstructLabGLAN)的流行,我们计划对结合各种提高吞吐量的方法(如,序列组装 + 4D 掩码、torch.compile、选择性 checkpointing)进行全面的吞吐量对比基准测试。

框架 每 GPU 每秒词元数 每步耗时(s) 浮点算力利用率(MFU)
FSDP(混合精度模式) 3158.7 10.4 0.41
DeepSpeed 3094.5 10.6 0.40

表 3:四张 A100 GPU 上 FSDP 和 DeepSpeed 之间的大致吞吐量比较。

最后的话

我们提供了新的 概念指南 以帮助用户在两个框架之间迁移。该指南可以帮助用户厘清以下问题:

  • 如何实现等效的分片策略?
  • 如何进行高效的模型加载?
  • FSDP 和 DeepSpeed 中如何管理权重预取?
  • 与 DeepSpeed 对等的 FSDP 封装是什么?

我们在 🤗 Accelerate 中考虑了配置这些框架的各种方式:

  • 使用 accelerate launch 从命令行配置
  • 从🤗 Accelerate 提供给 DeepSpeedFSDP 的各种 Plugin 类中配置

🤗 Accelerate 使得在 FSDP 和 DeepSpeed 之间切换非常丝滑,大部分工作都只涉及更改 Accelerate 配置文件(有关这方面的说明,请参阅新的概念指南)。

除了配置变更之外,还有一些如检查点处理方式的差异等,我们一并在指南中进行了说明。

本文中的所有实验都可以使用 原始 🤗 Accelerate 问题 中的代码重现。

我们计划后续在更大规模 GPU 上进行吞吐量比较,并对各种不同技术进行比较,以在保持模型质量的前提下更好地利用更多的 GPU 进行微调和对齐。

致谢

本工作凝聚了来自多个组织的多个团队的共同努力。始于 IBM 研究中心,特别是发现该问题的 Aldo Pareja 和发现精度差距并解决该问题的 Fabian Lim。Zach Mueller 和 Stas Bekman 在提供反馈和修复 accelerate 的问题上表现出色。Meta PyTorch 团队的 Less Wright 对有关 FSDP 参数的问题非常有帮助。最后,我们还要感谢 DeepSpeed 团队对本文提供的反馈。


英文原文: https://hf.co/blog/deepspeed-to-fsdp-and-back

原文作者: Yu Chin Fabian, aldo pareja, Zachary Mueller, Stas Bekman

译者: Matrix Yao (姚伟峰),英特尔深度学习工程师,工作方向为 transformer-family 模型在各模态数据上的应用及大规模模型的训练推理。

与Hugging Face Accelerate 两个后端的故事:FSDP 与 DeepSpeed相似的内容:

Hugging Face Accelerate 两个后端的故事:FSDP 与 DeepSpeed

社区中有两个流行的 零冗余优化器(Zero Redundancy Optimizer,ZeRO) 算法实现,一个来自 DeepSpeed,另一个来自 PyTorch。Hugging Face Accelerate 对这两者都进行了集成并通过接口暴露出来,以供最终用户在训练/微调模型时自主选择其中之一

使用 Hugging Face 推理终端搭建强大的“语音识别 + 说话人分割 + 投机解码”工作流

Whisper 是当前最先进的开源语音识别模型之一,毫无疑问,也是应用最广泛的模型。如果你想部署 Whisper 模型,Hugging Face 推理终端 能够让你开箱即用地轻松部署任何 Whisper 模型。但是,如果你还想叠加其它功能,如用于分辨不同说话人的说话人分割,或用于投机解码的辅助生成,

Hugging Face 全球政策负责人首次参加WAIC 2024 前沿 AI 安全和治理论坛

Hugging Face 全球政策负责人艾琳-索莱曼 ( Irene Solaiman )将参加7月5日在上海举办的WAIC-前沿人工智能安全和治理论坛,并在现场进行主旨演讲和参加圆桌讨论。具体时间信息如下: 主旨演讲:开源治理的国际影响 时间 | 7月5日下午15:35 - 15:50 圆桌讨论:

Hugging Face x LangChain: 全新 LangChain 合作伙伴包

我们很高兴官宣发布 langchain_huggingface ,这是一个由 Hugging Face 和 LangChain 共同维护的 LangChain 合作伙伴包。这个新的 Python 包旨在将 Hugging Face 最新功能引入 LangChain 并保持同步。 源自社区,服务社区

Hugging Face ZeroGPU 计划正式发布—提供价值一千万美元的免费共享 GPU

在人工智能技术领域,GPU 资源一直是推动研究和应用的关键因素。然而,GPU 的成本和可用性对于许多研究人员和开发者来说却是一个显著的障碍。 在 Hugging Face,我们希望人工智能技术可以更加普惠化,更多开发者可以参与其中共同探索,在人工智能技术浪潮中创造出让更多人受益的产品。 为此,我们计

Hugging Face 与 Wiz Research 合作提高人工智能安全性

我们很高兴地宣布,我们正在与 Wiz 合作,目标是提高我们平台和整个 AI/ML 生态系统的安全性。 Wiz 研究人员 与 Hugging Face 就我们平台的安全性进行合作并分享了他们的发现。 Wiz 是一家云安全公司,帮助客户以安全的方式构建和维护软件。 随着这项研究的发布,我们将借此机会重点

Ryght 在 Hugging Face 专家助力下赋能医疗保健和生命科学之旅

本文是 Ryght 团队的客座博文。 Ryght 是何方神圣? Ryght 的使命是构建一个专为医疗保健和生命科学领域量身定制的企业级生成式人工智能平台。最近,公司正式公开了 Ryght 预览版 平台。 当前,生命科学公司不断地从各种不同来源 (实验室数据、电子病历、基因组学、保险索赔、药学、临床等

聊聊Hugging Face

## 概述 HuggingFace是一个开源社区,提供了开源的AI研发框架、工具集、可在线加载的数据集仓库和预训练模型仓库。HuggingFace提出了一套可以依照的标准研发流程,按照该框架实施工程,能够在一定程度上规避开发混乱、开发人员水平不一致的问题,降低了项目实施的风险及项目和研发人员的耦合度

Google 发布最新开放大语言模型 Gemma 2,现已登陆 Hugging Face Hub

Google 发布了最新的开放大语言模型 Gemma 2,我们非常高兴与 Google 合作,确保其在 Hugging Face 生态系统中的最佳集成。你可以在 Hub 上找到 4 个开源模型(2 个基础模型和 2 个微调模型)。发布的功能和集成包括: Hub 上的模型 Hugging Face T

用 KV 缓存量化解锁长文本生成

很高兴和大家分享 Hugging Face 的一项新功能: KV 缓存量化 ,它能够把你的语言模型的速度提升到一个新水平。 太长不看版: KV 缓存量化可在最小化对生成质量的影响的条件下,减少 LLM 在长文本生成场景下的内存使用量,从而在内存效率和生成速度之间提供可定制的权衡。 你是否曾尝试过用语