幻方 AI 团队发布了一系列 DeepSeek 大模型,比如 DeepSeek-V2、DeepSeek-Math、DeepSeek-Coder 等。在 DeepSeek V2 中提出的 MLA(Multi-head Latent Attention)也广受好评。此外,DeepSeek V2 在强大性能的情况下还将 API 定价降低到 GPT-4 的百分之一,被称为“价格屠夫”,也由此引发大模型 API 的价格战。
本文中我们介绍一下幻方 AI 训练 DeepSeek 系列模型使用的大规模 GPU 集群以及相应的各种优化手段。
对应的论文为:[2408.14158] Fire-Flyer AI-HPC: A Cost-Effective Software-Hardware Co-Design for Deep Learning
深度学习 (DL) 和大型语言模型 (LLM) 的快速发展对计算能力和带宽的需求呈指数增长。此外,更快的计算芯片和互联的成本也往往很高,这大大增加了高性能计算(HPC)的构建成本。为了应对这些挑战,作者提出了 Fire-Flyer AI-HPC 架构、软硬件协同设计框架及其最佳实践。对于深度学习训练,作者部署了配备 10000 个 PCIe A100 GPU 的 Fire-Flyer2,实现了接近 DGX-A100 的性能,同时将成本降低一半,能耗降低 40%。作者还专门设计了 HFReduce 来加速 AllReduce 通信,并采用许多措施来保证计算-存储网络无阻塞。其软件栈包括 HaiScale、3FS 和 HAI-Platform,作者通过重叠计算和通信实现了更好的可扩展性。
本文中涉及的关键技术点为:
-
Network Co-Design:集成了计算-存储网络的两层 Fat-Tree 网络。
-
HFReduce:为了适配器 PCIe 架构的集合通信库。
-
HaiScale:基于 PCIe 架构优化的分布式并行方案。
-
3FS Distributed File System:解决 AI 任务下大数据的 I/O 瓶颈问题。
-
HAI Platform:提供任务调度,容错等能力,以便增加利用率,降低成本。
PS:
-
本文中提到的 10000 卡 A100 集群最开始应该不是为了大规模 LLM 训练搭建,可能没有太大的网络通信需求;而随着大模型的发展,向这个方向转换时为了解决网络问题进而提供了一系列的解决方案,比如增加 NVlink Bridge。实际上针对大规模 LLM 推理场景,采用 PCIe GPU + NVlink Bridge 也是个不错的方案。
-
本文中的各种实验都是针对 PCIe 架构展开,也并没有提供业内比较常见的 MFU 指标,虽然其相比 baseline 确实提升很多,但依然没有一个明确的对比。比如当前在 DGX A100 上的大规模训练通常能达到 50%-60% 的 MFU。
3.1 PCIe A100 GPU 架构
在 NVIDIA 官方 DGX 方案中,通常会采用 SXM GPU,有 NVlink 和 NVSwitch 实现高速互联,而且通常也会为每个 GPU 配备一个高速 IB 网卡(A100 通常是 200 Gbps)。而本文中作者采用的是 A100 PCIe GPU,无法使用 NVlink 和 NVSwitch 高速互联。此外 PCIe A100 和 SXM A100 在性能上也会略有差异,如下图 Table 2 所示。当然,PCIe GPU 服务器的成本和功耗也会更低一些。
实际上 A100 的各个版本中(甚至 A800 系列),理论算力都是相同的,比如 FP16 Tensor Core 算力都是 312 TFLOPS。作者上图中 A100 PCIe 是 A100 SXM 的 83% 应该是实测性能:
成本低的另一个原因是服务器中只配备一个 200Gbps 的 Mellanox CX6 IB 网卡,并且直连到 CPU,没有经过 PCIe Switch,类似于下图红框 NIC 和绿框 NIC 的区别。当然,这里其实还会引入一个问题,不同 NUMA(CPU)下的 GPU 通信,或者 CPU1 下的 GPU 要通过 NIC 通信则都需要通过 UPI,这也额外增加了一些开销。
上面提到,作者采用的 PCIe A100,没有使用 NVlink + NVSwitch 实现全互联。为了缓解 GPU 间数据交互的瓶颈,作者采用折衷的方案,每两个 GPU 通过 NVlink Bridge 实现高速互联,如下图所示,8 个 GPU 共分为 4 组,每组 2 个 GPU 通过 NVlink Bridge 连接。(PS:需要说明的是,作者早期的服务器没有 NVlink Bridge,而是后期为了适应 LLM 的需求新增加的)
3.2 网络拓扑
如下图所示为本文作者提出的两层 Fat-Tree 网络拓扑:
-
共包含两个 Zone。两个 Zone 的 Leaf Switch 直接通过 2 个 40-Port 的 Switch 互联(我们这里称作 Zone Switch),而不用经过 Zone 内的 Spine Switch。也就是 2 个 40-Port 的 Switch 共连接了 80 个 Leaf Switch。
-
每个 Zone 大概包含:
-
20 个 Spine Switch 和 40 个 Leaf Switch,Spine 和 Leaf 之间 Full Mesh 连接。
-
800 个 Node(包含 GPU Node 和 Storage Node,还有一些管理 Node)。
-
每个 Leaf Switch 40 个 Port:
-
20 个 Port 连接 Spine Switch。
-
1 个 Port 连接中间的 Zone Switch。
-
15 或 16 个 Port 连接 GPU Node,也就是每个 Zone 有 [40*15=600, 40*16=640] 个 GPU Node。(PS:论文中只说总共大约 1250 GPU Node,每个 Zone 大约 600 GPU Node,因此这里只能推测)
-
2 或 4 个 Port 连接 Storage Node。(PS:论文中提到两个 Zone 总共大约 200 个 Storage Node,但又介绍每个 Zone 800 个 Node。后文还提到包含 180 个 Storage Node,平均来看每个 Leaf Switch 会连接 2-3 个 Storage Node,Storage Node 包含 2 个 200 Gbps 的 NIC,不确定是否会将一个 Storage Node 连接到不同的 Leaf Switch)
3.3 成本
作者对比了本文的方案与其他方案需要的 Switch 数量以及成本,具体如下图 Table 3 所示:
-
本文:122 个 Switch:(40+20)*2+2。
-
PCIe 架构 + 3 层 Fat-Tree:每个 Node 1 个 NIC,则共需要 1600/20=80 Leaf Switch,80 Spine Switch 和 40 Core Switch,共 200 Switch。
-
DGX-A100 GPU + 3 层 Fat-Tree:每个 Node 包含 8 个 GPU,有 8 个后向网络 NIC,因此 10000 个 GPU(NIC) 至少需要 10000/(40/2)=500 个 40-Port 的 Leaf Switch,500 个 40-Port 的 Spine Switch 和 320 个 Core Switch(PS:考虑 Full Mesh,这里不是 250),所以总共需要 1320 个 Switch。
从上也可以看出,作者方案可以以 11600/23000=50.4% 的成本获得 83% 的 GPU性能。
3.4 下一代网络拓扑
作者也在准备构建下一代的 PCIe 架构集群来支持 MoE LLM 的训练,其包含大量的 All2All 通信,因此下一代架构中 GPU 和 NIC 会采用 1:1 配比,也就是每个 GPU 都有一个对应的 NIC,也考虑采用多平面网络。此外,会使用 RoCE 替代 IB Switch 以降低成本。使用 128 Port 的 400 Gbps RoCE Switch,4 平面的 2 层 Fat-Tree 网络可以支持 32,768 个 GPU。
4.1 HFReduce 算法
在大规模分布式训练中,AllReduce 是一种非常常见的集合通信操作,比如不同 Data Parallelism 之间的梯度聚合操作。而 NCCL 通常是针对节点内有 NVlink 高速互联或者都通过 NIC 方式通信的范式进行优化的。针对本文这种网络拓扑不一定能发挥最优的性能。如下图 Figure 6 所示为作者优化之后的 HFReduce 概览,其包含几步:
-
第一步:节点内 Reduce 操作。
-
第二步:节点间在 CPU 上进行 Reduce 操作。
-
第三步:将 CPU 上 Reduce 后的数据传输会 GPU。
节点内的 Reduce 操作算法如下图 Algorithm 1 所示:
-
将数据分成多个 Chunk 分别处理,这样可以将 IO 和 Compute 充分 Overlap。
-
每个 Chunk 的数据都通过异步的方式传输到 CPU 内存,拷贝操作也可以使用 GPUDirect 来拷贝小数据(可以参考 NVIDIA 的 GitHub - NVIDIA/gdrcopy: A fast GPU memory copy library based on NVIDIA GPUDirect RDMA technology),或者使用 cudaMemcpyAsync 来拷贝大数据。
-
已经拷贝到 CPU 内存上的 Chunk 可以执行 Reduce 操作,最终的结果也都是在 CPU 内存中。
节点间的 Reduce 操作算法如下图 Algorithm 2 所示:
-
使用 Double Binary Tree Algorithm 算法实现节点间的 AllReduce 操作,节点间传输通过 RDMA 实现。
-
最后将计算完的数据通过 PCIe 传输到 GPU 显存中。此处的 Host to Device 操作也可以通过 GPUDirect 操作来同时写到同一个 NUMA 下的 4 个 GPU,而减少对 Host Memory 的读取(利用 CPU Cache)。
4.2 HFReduce 对比 NCCL
针对本文的网络拓扑,作者提出的方案相比 NCCL 有 2 个优势:
-
减少了 PCIe 带宽开销:假设有 n 个 GPU 参与通信,在 NCCL 的 Ring 拓扑中每个数据单元需要 2n-1 次传输,对 PCIe 通信要求比较高。而 HFReduce 中,每个数据单元只需一次 D2H 和一次 H2D,这对于本文这种 PCIe 受限场景更加友好。
-
没有 GPU Kernel 开销:HFReduce 使用 GPU 的 Copy Engine(CE) 来执行异步的数据传输,而 NCCL 的 AllReduce 操作是使用 GPU Kernel 来完成。
如下图(a) 所示,本文的方案在执行 186MiB 数据的 AllReduce 时相比 NCCL获得了更高的带宽。
4.3 HFReduce with NVlink
我们前面提到过,作者在每两个 GPU 上添加了 NVlink Bridge,可以达到 600 GB/s 的高速通信带宽。而上述标准 HFReduce 并没有利用上 NVlink,因此作者也进一步探索了带有 NVlink 的 HFReduce。具体来说,在数据传输到 CPU Memory 之前,先在 2 个 GPU 上执行 Reduce;然后在结果返回时再将结果切分到对应的 2 个 GPU。
作者进一步测试了相应的通信带宽,如下图(b)所示,基本可以达到上述(a)中不带 NVlink 的 2x。其中蓝色为跨 Zone 的情况,因为一个 Leaf Switch 下有 15 或16个 Node,也就是 128 GPU,因此也只考虑超过 128 GPU 的情况:
4.4 深入分析 HFReduce
实现中的关键技术决策:
-
GPUDirect:使用 GPUDirect 加速 D2H 中的小数据拷贝,同时使用 GPUDirect 减少 3 倍的 H2D 开销。
-
节点内规约:使用 SIMD 指令完成 CPU 上的规约操作,支持 FP32、FP16、BF16 和 FP8。
-
NUMA 感知:D2H 的目标内存会分配到 2 个 NUMA 对应的内存,以实现最大带宽。CPU Reduce 和网络传输的数据内存绑定在 IB NIC 对应的 NUMA,以尽量减少通过 UPI。
-
节点间规约:使用 Double Binary Tree 实现 AllReduce,避免额外的开销。
克服 EPYC Rome CPU 的限制:作者找 AMD 和 NVIDIA 的工程师帮忙定位了 PCIe 架构下通信的次优问题。最终发现 EPYC Rome CPU 不支持 chained write 功能,这个功能可以大幅提升 GPU 和 IB 之间的 PCIe P2P 带宽。作者测试发现,Rome CPU 上 IB NIC 和 GPU 的极限带宽在 9GiB/s,这也就可以解释上述 NCCL 的 AllReduce 带宽不超过 4GB/s。而 HFReduce 通过在 CPU 上进行 Reduce,在 CPU 和 IB 之间传输数据来规避这一问题。
HFReduce 的瓶颈:作者统计了一个 Node 上的所有内存操作:
-
D2H 需要 8 次写操作(8 个 GPU)。
-
节点内 Reduce 涉及 8 次读操作和 1 次写操作。
-
节点间 Reduce 涉及 IB send 2 次读操作,IB receive 2 次写操作,以及 1 次 add 操作。
-
H2D 利用 GPUDirect 执行 2 次读操作(8 次降低到 2 次)。
整体来说,上述内存操作相比 GPU 上的数据大小涉及 24x 的放大。一个 16 Channel 的 DDR4-3200MHz 内存,理论最大内存带宽为 320GB/s,对应理论最大 HFReduce 带宽为 320/24=13.3GB/s,而作者实测只有 8GB/s。
上述问题的主要原因是 EPYC CPU 的另一个限制,本文中作者的 GPU5 和 GPU6 直接通过相同的 PCIe Host Bridge 连接到 CPU。而 AMD EPYC Rome 和 Milan CPU 中 PCIe Host Bridge 的最大带宽为 37.5GB/s,即使 PCIe 4.0x16 从 GPU 到 CPU 可以实现 27GB/s。但是当 2 个 GPU 同时传输数据时将受到上述 37GB/s 的限制,也就是说平均最大只能达到 19GB/s。如果考虑双向传输,带宽瓶颈会更加明显。而作者加装的 NVlink Bridge (GPU5 和 GPU6 通过 NVlink Bridge 互联)可以提供一种有效的方案来缓解这个问题。此外,即使 AMD EPYC Genoa 也同样面对这个问题。
5.1 HaiScale DDP
Pytorch DDP 会使用 NCCL 用于梯度聚合时的 AllReduce 操作,而本文中,作者使用 HFReduce 替换 NCCL。如下图(a)所示,训练 VGG 模型时,基于 HFReduce 的时延几乎是 Pytorch DDP(NCCL)的一半。同时,从 32 GPU 扩展到 512 GPU 时可以获得 88% 的线性加速。
5.2 LLM 训练优化
针对 LLM 训练,作者同样优化了 DP、PP、TP 和 EP。
将 NVlink Bridge 连接的 2 个 GPU 用于 TP,实现高速互联。(PS:通常使用 NVlink + NVSwitch 的方案可以更好的是指 8 GPU 的 TP)
针对 PCIe 架构优化 PP。一台机器只有 1 个 NIC,使用 PP 时可能存在瓶颈,为此,作者在调度时将不同的 DP Rank 调度到同一个 Node 上,这样可以交错 DP 和 PP。如下图 Figure 9(a)所示,训练 LLaMA 13B 时,GPU 数从 32 扩展到 512,每一个 Step 的 Latency 从 64.118s 减少到 9.717s,获得了理论加速 91% 的加速效果。如下图 Figure 9(b)所示,DeepSeek-MoE 16B 训练时同样获得了理论加速的 92.92%。
HaiScale FSDP:此外,作者也对 FSDP 进行了适配和优化,如下图(b)所示,从 16 GPU 到 128 GPU,HaiScale 可以获得 95% 的加速。
6.1 计算-存储网络拥塞最小
如前所述,作者的网络方案中计算和存储在一个网络中,相较而言,之前的方案中往往是计算网络是高速后向网络,而存储网络是前向网络。因此,为了实现最大带宽,必须隔离不同类型的流量,避免相互干扰并造成网络拥塞。具体来说,作者实施了以下几个措施。
不同流量区分:在典型的训练任务中,有 4 种不同类型的流量:HFReduce 通信,NCCL 通信,3FS 存储流量和其他流量。作者利用 IB 的 Service Level(SL)技术,在节点之间建立连接时为其分配不同的 SL 值,并将 SL 映射到 IB 物理队列虚拟通道(VL),使用虚拟通道可以确保不同通道中的流量不会相互干扰。最终,通过配置它们的比例实现流量隔离,从而防止 Head-of-Line(HOL)阻塞和不同的流量冲突引起的网络阻塞。
拓扑调整和路由优化:在高吞吐存储场景中,存在许多 incast 通信模式,导致拥塞。针对这种情况,作者采用静态路由策略,将存储流量均匀分散在不同 Leaf -> Spine 连接,并将各种节点(存储、计算、管理)均匀分配到 Leaf -> Spine 连接。
NCCL 优化:调整了 NCCL 拓扑,以便调整同一个 Node 内的 IB NIC 和 GPU 的路由。可以减少 CPU chiplet 互联导致的 PCIe 拥塞。此外,通过使用 PCIe Relaxed Ording 进一步减少拥塞并增加带宽。
3FS 网络调优:3FS 实现了一个请求到发送的控制机制来缓解拥塞。
6.2 3FS 高吞吐分布式存储
如下图 Table IV 为本文的 Storage Node 配置,可以看出,其包含 1 个 CPU,2 个 200 Gbps NIC 和 16 个 15.36TB 的 SSD。
-
总共 2880 NVMe SSD,可以提供 20 PiB 的存储(有1个额外的存储副本)。
-
总共可以提供 180*2*200 Gbps = 72 Gbps = 9 TB/s 的理论带宽,实测可以达到 8 TB/s。
3FS 系统包含 4 个角色:Cluster Manager、meta Service、Storage Service 和 Client。其中 Storage Service 会部署在每个 Storage Node 上,每个 Storage Service 都能提供等分的带宽。根据这个设计,每个 Client 都可以访问每个 Storage Service。峰值负载时,作者在 Client 观察到 Incast 拥塞,为了缓解这个拥塞,作者在 Storage Service 和 Client 之间实现了一种请求发送控制机制(request-to-send),这种机制会增加端到端 IO 延迟,但又是实现可持续高吞吐的必要手段。
除此之外,还基于 3FS 实现了 3FS-KV,是 DeepSeek LLM Inference 中实现分布式 Context Caching 的关键所在。
6.3 HAI Platform
作者很早就开源了其对应的分布式训练平台,具体可以参考源码(GitHub - HFAiLab/hai-platform: 一种任务级GPU算力分时调度的高性能深度学习训练平台)和文档(欢迎来到HAI Platform 官方文档)。这里不再介绍。
7.1 Checkpoint 管理
在超大规模训练中,各种异常是在所难免的,为了减少异常导致的计算浪费,通常都会采用 Checkpointing 机制,定期保存 Checkpoint。本文中 Checkpoint 的保存同样依赖上述的 3FS,每个 Node 可以提供 10 GiB 的带宽,所以通常可以在几秒时间完成 Checkpoint 的保存。在作者的训练过程中,通常是每 5 分钟保存一次,也就是每次异常最多浪费 5 分钟的训练。
7.2 验证
增强设备稳定性最好的手段就是在发生异常之前检测到异常。因此作者开发了一系列的验证工具来识别是否存在硬件故障,然后平台可以自动进行一些运维工作。比如从集群中屏蔽异常机器,不允许调度。验证主要包括下述部分:
-
经常检测硬件,比如连接速度,状态。
-
CPU 压测及内存带宽压测。
-
GPU Memory 测试。
-
GPU 运行 GEMM 测试。
-
节点内 AllReduce 测试。
-
存储带宽压测。
7.2 硬件故障
最常见的硬件问题包含两种:GPU Xid Error 和网络抖动。
如下图 Table V 所示,作者展示了常见的 Xid Error 和对应的原因:
如下图 Table VI 所示,作者也展示了不同 Xid Error 的数量和比例,可以看出,NVlink Error 占比 42.57%,这可能和作者使用的 NVlink Bridge 有关。而 Xid 31 和 Xid 43 的软件错误总共超过了 50%,这种情况大部分是程序问题,如果排除程序问题那也基本可以确定是硬件故障。
如下图 Figure 11 所示,作者同样频繁受到网络抖动的影响:
由于新岗位的生产效率,要优于被取代岗位的生产效率,所以实际上整个社会的生产效率是提升的。
但是具体到个人,只能说是:
“最先掌握AI的人,将会比较晚掌握AI的人有竞争优势”。
这句话,放在计算机、互联网、移动互联网的开局时期,都是一样的道理。
我在一线互联网企业工作十余年里,指导过不少同行后辈。帮助很多人得到了学习和成长。
我意识到有很多经验和知识值得分享给大家,也可以通过我们的能力和经验解答大家在人工智能学习中的很多困惑,所以在工作繁忙的情况下还是坚持各种整理和分享。但苦于知识传播途径有限,很多互联网行业朋友无法获得正确的资料得到学习提升,故此将并将重要的AI大模型资料包括AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频免费分享出来。
该阶段让大家对大模型 AI有一个最前沿的认识,对大模型 AI 的理解超过 95% 的人,可以在相关讨论时发表高级、不跟风、又接地气的见解,别人只会和 AI 聊天,而你能调教 AI,并能用代码将大模型和业务衔接。
- 大模型 AI 能干什么?
- 大模型是怎样获得「智能」的?
- 用好 AI 的核心心法
- 大模型应用业务架构
- 大模型应用技术架构
- 代码示例:向 GPT-3.5 灌入新知识
- 提示工程的意义和核心思想
- prompt 典型构成
- 指令调优方法论
- 思维链和思维树
- prompt 攻击和防范
- …
该阶段我们正式进入大模型 AI 进阶实战学习,学会构造私有知识库,扩展 AI 的能力。快速开发一个完整的基于 agent 对话机器人。掌握功能最强的大模型开发框架,抓住最新的技术进展,适合 Python 和 Javascript 程序员。
- 为什么要做 RAG
- 搭建一个简单的 ChatPDF
- 检索的基础概念
- 什么是向量表示(Embeddings)
- 向量数据库与向量检索
- 基于向量检索的 RAG
- 搭建 RAG 系统的扩展知识
- 混合检索与 RAG-Fusion 简介
- 向量模型本地部署
- …
恭喜你,如果学到这里,你基本可以找到一份大模型 AI相关的工作,自己也能训练 GPT 了!通过微调,训练自己的垂直大模型,能独立训练开源多模态大模型,掌握更多技术方案。
到此为止,大概2个月的时间。你已经成为了一名“AI小子”。那么你还想往下探索吗?
- 为什么要做 RAG
- 什么是模型
- 什么是模型训练
- 求解器 & 损失函数简介
- 小实验2:手写一个简单的神经网络并训练它
- 什么是训练/预训练/微调/轻量化微调
- Transformer结构简介
- 轻量化微调
- 实验数据集的构建
- …
对全球大模型从性能、吞吐量、成本等方面有一定的认知,可以在云端和本地等多种环境下部署大模型,找到适合自己的项目/创业方向,做一名被 AI 武装的产品经理。
- 硬件选型
- 带你了解全球大模型
- 使用国产大模型服务
- 搭建 OpenAI 代理
- 热身:基于阿里云 PAI 部署 Stable Diffusion
- 在本地计算机运行大模型
- 大模型的私有化部署
- 基于 vLLM 部署大模型
- 案例:如何优雅地在阿里云私有部署开源大模型
- 部署一套开源 LLM 项目
- 内容安全
- 互联网信息服务算法备案
- …
学习是一个过程,只要学习就会有挑战。天道酬勤,你越努力,就会成为越优秀的自己。