veScale-FSDP:面向大规模训练的灵活高性能全分片数据并行系统 veScale-FSDP: Flexible and High-Performance FSDP at Scale
提出RaggedShard格式和结构感知规划算法,实现灵活高效的大规模FSDP训练
前置知识
FSDP (Fully Sharded Data Parallel)
全分片数据并行是一种分布式训练技术,将模型的参数、梯度和优化器状态分片存储在多个GPU上,每个GPU只保存一部分状态。在前向和反向传播时,通过AllGather操作临时收集完整参数,计算完成后通过ReduceScatter分散梯度。这种方式的核心优势是显存效率高,每个GPU只需存储1/N的模型状态(N为GPU数量),使得在有限显存下训练超大模型成为可能。FSDP也被称为DeepSpeed ZeRO(Zero Redundancy Optimizer),是当前大模型训练的主流并行策略之一。
本文的核心贡献是对FSDP系统的改进,理解FSDP的基本工作原理是理解本文动机和方法的前提
DTensor (Distributed Tensor)
分布式张量是PyTorch中的原语,用于表示分布在多个设备上的逻辑全局张量。DTensor支持三种分片格式(placements):Shard(dim)沿张量维度均匀分片,Replicate在每个设备上复制完整张量,Partial表示每个设备持有需要跨设备归约的部分值。DTensor提供了redistribute API,可在不同placement之间转换并隐式执行集合通信。DTensor是PyTorch分布式训练的基础抽象,被广泛用于表达张量并行(TP)和专家并行(EP)等并行策略中的张量分区。
本文提出的RaggedShard是DTensor的一种新placement,理解DTensor的分片机制是理解RaggedShard如何与现有系统集成的关键
结构感知训练 (Structure-Aware Training)
结构感知训练是指训练方法需要保持张量的结构完整性,不能将张量随意拆分为任意元素。典型例子包括:(1) 矩阵优化器如Shampoo和Muon,其更新操作需要在原始2D矩阵上进行,要求在选定设备上收集完整矩阵后执行矩阵级更新;(2) 分块量化如DeepSeek-V3使用的块级FP8量化和8-bit Adam,每个量化块必须完整驻留在单个设备上,否则需要交换缩放因子元数据。这类训练方法对分片边界有严格要求,是现有FSDP系统的主要瓶颈。
本文的核心动机就是解决现有FSDP无法支持结构感知训练的问题,理解这一概念对理解论文价值至关重要
AllGather与ReduceScatter
这是FSDP中最核心的两种集合通信操作。AllGather在前向和反向传播前执行,将所有设备上的分片参数收集到每个设备上,形成完整参数用于计算。ReduceScatter在反向传播后执行,将梯度分散到各设备上,同时完成梯度归约。这两种操作的效率直接影响FSDP的训练性能,通信缓冲区的对齐、大小和布局都会影响NCCL等通信库的实际带宽利用率。论文中提到FSDP2的分片设计会导致通信缓冲区地址不对齐,从而显著降低通信性能。
本文的核心优化目标就是减少AllGather和ReduceScatter的开销,理解这些通信操作是理解性能优化的基础
集合通信 (Collective Communication)
集合通信是分布式计算中多个设备协同完成的通信操作,包括AllGather(收集所有设备数据)、ReduceScatter(归约并分散数据)、AllReduce(归约并广播)等。在大规模分布式训练中,集合通信的效率至关重要,通常需要通过张量分桶(bucketing)来最大化网络利用率。NCCL(NVIDIA Collective Communications Library)是GPU集群上最常用的集合通信库,对缓冲区地址对齐有特定要求。论文指出,未对齐的通信缓冲区会导致通信性能显著下降。
本文的DBuffer和规划算法都是为了优化集合通信效率,理解集合通信机制对理解这些优化的重要性
研究动机
现有FSDP系统在支持现代结构感知训练方法方面存在严重不足。具体而言,DeepSpeed ZeRO、PyTorch FSDP1和FSDP2都采用固定的元素级或行级均匀分片格式,这种设计与块结构计算存在根本性冲突。以分块量化为例,DeepSeek-V3使用的块级FP8量化要求每个量化块(如128×128的块)完整驻留在单个设备上,但现有FSDP的分片边界是按元素或均匀行切分的,无法保证与量化块边界对齐。在性能方面,FSDP2引入了显著的拷贝开销:在AllGather路径上,Shard(0)格式的Copy-Out耗时5.22ms(相对于43.71ms的AllGather),Shard(1)格式更高达13.72ms;在ReduceScatter路径上,Copy-In开销分别为12.37ms和23.14ms,这些拷贝操作可消耗高达14%的训练迭代时间。Megatron-FSDP虽然采用零拷贝设计,但其固定的Shard(0)分片粒度导致MoE模型中出现33%的缓冲区填充膨胀,既降低了通信效率又增加了显存占用。此外,FSDP1和FSDP2都不强制NCCL缓冲区地址对齐,在某些情况下会导致通信性能显著下降。
本文的目标是本文旨在设计一个兼具灵活性和高性能的新一代FSDP系统veScale-FSDP,具体目标包括:第一,支持任意分片粒度和自定义块大小的灵活分片格式,使FSDP能原生支持块级量化(如8-bit Adam的32×32块)和非元素级优化器(如Shampoo和Muon);第二,通过零拷贝通信路径和优化的缓冲区管理,实现比现有FSDP系统更高的训练吞吐量和更低的显存占用;第三,系统能够高效扩展到数万GPU的规模,在字节跳动Seed的实际生产环境中部署运行。这些目标需要在保持PyTorch原生fully_shard API兼容性的前提下实现,不侵入性地修改模型或优化器代码。
与已有工作不同的是,本文的独特切入角度是从分片格式的根本抽象层面进行创新,而不是在现有分片格式上打补丁。现有工作要么采用元素级分片(DeepSpeed、FSDP1)损失张量结构信息,要么采用均匀行级分片(FSDP2)无法适配任意块大小,要么通过固定行级分片(Megatron-FSDP)牺牲灵活性换取性能。veScale-FSDP提出的RaggedShard是一种全新的DTensor placement,支持任意分片粒度(从元素级到任意形状的块级)和任意分片分布(不同设备可持有不同数量的块),这在概念上统一了所有现有分片格式作为特例。同时,本文将分片规划问题形式化为NP难优化问题,并设计了多项式时间启发式算法,这在理论上和实践上都是新颖的。此外,Distributed Buffer(DBuffer)原语的设计实现了从通信缓冲区到计算的零拷贝路径,这是对现有FSDP内存管理方式的根本性改进。
核心方法
veScale-FSDP的方法设计遵循灵活性与性能并重的整体思路。从直觉上讲,现有FSDP的瓶颈在于分片格式过于僵化——要么按元素切分丢失结构信息,要么按固定行切分无法适配任意块大小。本文的核心洞察是:如果我们允许分片边界落在任意位置(而不仅仅是元素边界或行边界),就能同时支持结构感知训练和高效通信。技术路线分为三个层次:首先,RaggedShard作为新的DTensor placement,定义了任意粒度的分片抽象,支持从元素级到任意形状块级的分片,并能与现有的Shard(dim)、Replicate等placement组合使用;其次,规划算法将多个RaggedShard张量的通信布局优化形式化为约束优化问题,通过动态规划和排列启发式在多项式时间内找到接近最优的缓冲区布局;最后,Distributed Buffer(DBuffer)作为底层原语,通过持久化地址映射和批量化内存管理,实现零拷贝的集合通信路径。这三个组件协同工作,使得veScale-FSDP在保持PyTorch原生API兼容性的同时,实现了显著的性能提升。
veScale-FSDP的核心创新在于RaggedShard分片格式及其配套的优化机制。与现有方法的本质区别体现在:第一,RaggedShard支持任意分片粒度,用户可以为每个张量指定自定义的块大小(如32×32、128×128),分片边界保证与这些块边界对齐,这使得分块量化和矩阵优化器可以无侵入地使用FSDP;而现有方法的分片粒度是固定的(元素级或行级),无法适配任意块大小。第二,RaggedShard支持不均匀分片分布,不同设备可以持有不同数量的分片块,这对于矩阵优化器的分布式Muon算法至关重要——它需要将完整2D参数矩阵收集到单个设备上执行Newton-Schulz迭代;而现有方法要求每个设备持有相同大小的分片,无法实现这种不均匀分布。第三,规划算法将通信缓冲区布局优化形式化为NP-hard问题,通过动态规划在$O(|T|^2 m \log(E) \log(|T|m))$时间内求解,最小化填充开销的同时保证三个约束:非分片块完整性、张量内存连续性和负载均衡;而现有方法要么不考虑块边界(导致分片块被切断),要么采用简单填充(导致显著的内存和通信开销)。第四,DBuffer通过持久化地址映射实现零拷贝通信,消除了FSDP2中高达14%迭代时间的拷贝开销。
方法步骤详情
veScale-FSDP的方法执行分为以下步骤:第一步,用户通过PyTorch原生的fully_shard API定义FSDP分片,为每个参数指定RaggedShard placement和自定义块大小(如使用orig_param_policy接口为8-bit Adam设置32×32块大小)。第二步,规划算法收集所有RaggedShard张量的元信息(块大小$g_t$、张量大小$e_t$、块数量$u_t = e_t/g_t$),执行结构感知规划:首先对张量进行排列(默认使用原始顺序,也可按块大小或张量形状排序),然后通过动态规划确定每个张量在全局通信缓冲区中的位置$[\ell_t, r_t)$,使得满足三个约束——分片边界不切断任何块($kS - \ell_t \equiv 0 \pmod{g_t}$)、张量内存连续($r_t - \ell_t = e_t$)、各设备缓冲区大小相等(统一为$S$)。第三步,规划结果通过DBuffer实现:DBuffer分配一个全局缓冲区(总大小$mS$,分为$m$个设备本地缓冲区),为每个张量提供持久化的地址映射,使得张量数据指针直接指向缓冲区中的位置,实现零拷贝访问。第四步,通信执行时,DBuffer将相同操作的CUDA kernel融合执行(如多个张量的add、scale、zero操作),减少阻塞时间;然后通过原地(inplace)集合通信完成AllGather或ReduceScatter,通信结果直接就位,无需额外拷贝。第五步,计算完成后,DBuffer通过显式的流依赖管理实现可预测的内存释放,批量化分配减少内存碎片。
技术新颖性
veScale-FSDP的技术新颖性体现在多个层面。首先,RaggedShard作为一种新的DTensor placement,在概念上是对现有分片格式的泛化:元素级分片对应块大小为1的RaggedShard,行级分片对应块大小为行数的RaggedShard,而RaggedShard还支持任意形状的块级分片和不均匀分布。这种统一抽象使得RaggedShard可以与现有的Shard(dim)、Replicate等placement无缝组合,通过引入StridedRaggedShard处理Shard(0)的重排/步幅元数据,通过调整分片粒度避免切入Shard(dim>0)的维度。其次,将分片规划形式化为NP-hard优化问题是新颖的理论贡献:论文证明该问题可以从经典的Partition问题归约得到,因此不存在多项式时间精确算法。提出的动态规划启发式算法具有$O(|T|^2 m \log(E) \log(|T|m))$的时间复杂度,通过利用张量大小的单调性将DP状态空间压缩到每个张量最多$m$个不同值,实现了高效的求解。第三,DBuffer的设计借鉴了DTensor的全局缓冲区语义,但将其扩展到支持分组操作和零拷贝访问,通过持久化地址映射消除了FSDP2的Copy-In/Copy-Out开销。最后,整个系统在保持PyTorch原生API兼容性的同时,实现了7.6K行Python代码的紧凑实现,这是一个重要的工程创新。
实验结果
veScale-FSDP的实验结果全面验证了其设计目标。在端到端性能方面,使用1024个GPU的实验显示:在MoE模型上,veScale-FSDP比所有基线系统快11%至66%;在LLaMA-3-70B上,比DeepSpeed、FSDP1和FSDP2快5%,与Megatron-FSDP基本持平。在显存使用方面,veScale-FSDP将峰值保留显存降低了16%至30%,这得益于DBuffer的确定性批量化内存管理。在可扩展性方面,弱扩展实验显示从1K到8K GPU的近线性扩展;强扩展实验在120M token全局批量大小下实现了到10K GPU的线性扩展,在16M token批量大小下从1K到8K GPU仍获得3.4倍吞吐量提升;模型扩展实验在1K GPU上成功训练2.4T参数模型,MFU(模型FLOPS利用率)甚至略有提升。在结构感知训练支持方面,8-bit Adam和分布式Muon优化器都以极少代码量实现,损失曲线与基线系统一致。规划算法的填充开销在1×和16×行粒度下保持在3%以下,算法运行时间小于0.3秒。消融实验表明,禁用DBuffer使吞吐量降至92.8%,禁用规划算法使吞吐量降至65.4%,而禁用RaggedShard则使系统无法运行。
查看结构化数据
| 任务 | 指标 | 本文 | 基线 | 提升 |
|---|---|---|---|---|
| MoE模型端到端训练吞吐量 | 归一化吞吐量(相对最优基线) | veScale-FSDP: 1.0(最优) | DeepSpeed/FSDP1/FSDP2/Megatron-FSDP: 0.60-0.90 | 比所有基线快11%至66% |
| LLaMA-3-70B端到端训练吞吐量 | 归一化吞吐量 | veScale-FSDP: 1.0(最优) | DeepSpeed/FSDP1/FSDP2: 0.95, Megatron-FSDP: 0.99 | 比DeepSpeed/FSDP1/FSDP2快5% |
| GPT-OSS-120B显存使用 | 峰值保留显存(GB) | veScale-FSDP: 显著低于基线 | DeepSpeed/FSDP1/FSDP2/Megatron-FSDP: 更高显存 | 峰值显存降低16%至30% |
| 弱扩展性(800B MoE模型) | 归一化吞吐量随GPU数量变化 | 1K到8K GPU近线性扩展 | N/A | 验证了近线性扩展能力 |
| 强扩展性(120M token批量) | 吞吐量随GPU数量变化 | 1K到10K GPU线性扩展 | N/A | 验证了万卡规模线性扩展 |
| 模型扩展性(1K GPU) | MFU随模型大小变化 | 400B到2.4T参数,MFU略有提升 | N/A | 在1K GPU上成功训练2.4T参数模型 |
| 8-bit Adam训练收敛性 | 训练损失曲线 | veScale-FSDP 8-bit Adam: 损失曲线与DDP一致 | DDP 8-bit Adam | 收敛性一致,少量代码实现 |
| 分布式Muon优化器 | 训练损失曲线和MFU | veScale-FSDP Muon: 47.3% MFU @ 256 GPU | DDP Muon、AdamW | 比AdamW收敛更快,稳定后损失低约0.01 |
局限与改进
本文存在以下局限性:第一,规划算法的NP-hard本质意味着提出的启发式算法只能保证2-近似,虽然在实际Transformer模型上表现良好,但对于非Transformer架构或其他高度不规则的张量形状,近似比可能更大。第二,RaggedShard的规划算法假设张量顺序是固定的(默认使用原始顺序),虽然论文测试了三种排序策略,但最优排序可能依赖于具体模型和硬件配置,缺乏自适应选择机制。第三,填充开销在128×行粒度下可能出现高达18%的峰值(如GPT-OSS模型),这表明在某些极端分片粒度和FSDP组大小组合下,性能可能显著退化。第四,论文的强扩展实验在非常大的GPU数量下(如10K GPU)观察到性能下降,这表明FSDP通信在极端规模下仍可能成为瓶颈。第五,DBuffer的持久化地址映射增加了实现复杂性,可能引入新的调试难度。第六,论文主要在NVIDIA H800和Hopper GPU上验证,对于其他硬件平台(如AMD GPU、Google TPU)的适用性未被讨论。第七,虽然论文声称veScale-FSDP是字节跳动Seed的主要训练系统,但缺乏与其他工业界系统的直接比较。
独立分析的弱点
本文存在以下可改进的弱点:第一,规划算法的排列策略相对简单,只测试了三种固定排序,缺乏根据模型结构自适应选择最优排序的机制。改进方向是开发基于学习的排序策略,利用历史训练数据预测最优排列。第二,RaggedShard的块大小需要用户手动指定,缺乏自动选择机制。可以开发自动分析模型结构和优化器需求的工具,推荐最优块大小配置。第三,DBuffer的批量化内存管理虽然减少了碎片,但在动态形状模型(如变长序列)中可能效率不高。改进方向是支持动态缓冲区调整策略。第四,规划算法的时间复杂度为$O(|T|^2 m \log(E) \log(|T|m))$,对于参数组数量$|T|$很大的模型,初始化时间可能成为瓶颈。可以探索近似算法或增量规划策略。第五,论文缺乏对RaggedShard与梯度检查点(gradient checkpointing)交互的分析,这在训练超大模型时是常见需求。第六,虽然RaggedShard支持分布式检查点,但缺乏对检查点恢复性能的评估。
未来方向
基于本文成果可延伸的研究方向包括:第一,将RaggedShard推广到更多并行策略的组合,如与流水线并行(Pipeline Parallelism)和序列并行(Sequence Parallelism)的深度集成,实现更灵活的多维并行策略。第二,开发自适应分片策略,根据训练阶段(如预训练vs微调)和硬件配置(如GPU型号、网络拓扑)自动调整分片粒度和布局。第三,探索RaggedShard在推理场景的应用,特别是在模型并行推理和动态批处理中,不均匀分片可能有独特优势。第四,将规划算法与通信调度算法结合,在更细粒度上优化通信与计算的重叠。第五,研究RaggedShard在异构计算环境中的应用,如CPU-GPU混合训练或不同型号GPU的集群。第六,开发RaggedShard的自动微分支持,使其能更无缝地集成到PyTorch的自动微分系统中。第七,探索RaggedShard在联邦学习等分布式训练变体中的应用,其中数据分布的不均匀性可能与不均匀分片有天然契合。
复现评估
本文的复现条件相对较好。开源方面,RaggedShard代码已在GitHub开源(https://github.com/volcengine/veScale),这大大降低了复现门槛。系统实现方面,veScale-FSDP用7.6K行Python代码实现,透明替换FSDP2后端,使用标准PyTorch分布式运行时,兼容多个PyTorch版本,这使得复现不需要特殊依赖。数据方面,论文使用的模型(LLaMA-3-70B、GPT-OSS-120B)都是公开可用的模型,训练数据配置也已描述。算力方面,实验在NVIDIA H800(8×H800/节点,979 BF16 TFLOPS,80 GB HBM)和Hopper集群上进行,万卡规模的实验需要大量GPU资源,但64-128 GPU的小规模实验可以验证核心功能。复现难度中等:核心算法(规划算法)有详细的伪代码(Algorithm 1),但完整系统的工程实现细节(如DBuffer的CUDA kernel融合、内存管理策略)可能需要深入阅读源代码。论文的消融实验(Table 2)为理解各组件贡献提供了清晰指引。
论文图表
展示了DTensor在分布式计算中的工作原理。图中显示了一个设备上执行分片矩阵乘法的过程:行分片(Shard(0))的DTensor首先通过redistribute操作转换为复制(Replicate)DTensor,然后与列分片(Shard(1))的DTensor相乘,产生列分片的结果。蓝色部分表示每个设备上物化的本地张量。
这张图直观展示了DTensor的通信和计算机制,是理解RaggedShard如何扩展DTensor抽象的基础。它说明了DTensor如何通过redistribute API在不同分片格式之间转换,以及如何直接从分片DTensor执行计算操作。
展示了FSDP2设计中的拷贝开销问题。每个参数被表示为Shard(0) DTensor并均匀分片。在AllGather之前,输入通信缓冲区需要拷入所有参数的本地分片。AllGather之后,输出通信缓冲区中各参数存储在交错的内存地址而非连续地址,因此FSDP2必须将每个参数从输出缓冲区拷出以获得计算所需的连续地址。ReduceScatter路径是反向过程,产生交错的Copy-In开销。
这张图是理解现有FSDP系统性能瓶颈的关键,清晰展示了FSDP2中高达14%迭代时间的拷贝开销的来源,为veScale-FSDP的DBuffer零拷贝设计提供了直接动机。
展示了RaggedShard与现有DTensor分片格式的组合能力。图中显示了一个DTensor具有(RaggedShard, Shard(0))的placement列表,在2D并行策略(如FSDP×专家并行)中的使用方式。RaggedShard作为FSDP的分片格式,与Shard(0)作为专家并行的分片格式组合使用。
这张图说明了RaggedShard如何与现有的张量并行和专家并行策略无缝集成,展示了veScale-FSDP在复杂并行策略中的适用性。
展示了veScale-FSDP的可扩展性,包含四个子图:(a)弱扩展到8K GPU,800B MoE模型,输入大小2K-16K tokens/GPU;(b)强扩展到8K GPU,固定全局批量16M-128M tokens;(c)强扩展的归一化视图;(d)模型扩展,1K GPU上从400B到2.4T参数。关键发现:弱扩展近线性;强扩展在120M token批量下到10K GPU线性扩展;模型扩展在1K GPU上成功训练2.4T参数模型,MFU略有提升。
这张图验证了veScale-FSDP在万卡规模的可扩展性,是系统工业部署价值的关键证明,特别是模型扩展实验展示了在有限GPU上训练超大模型的能力。
展示了8-bit Adam和分布式Muon优化器在veScale-FSDP上的训练收敛性。(a)8-bit Adam比较veScale-FSDP和DDP实现,损失曲线一致,少量差异来自梯度归约调度(DDP使用分桶AllReduce,veScale-FSDP使用逐层ReduceScatter)。(b)分布式Muon比较veScale-FSDP、DDP和AdamW,Muon比AdamW收敛更快,训练约80B tokens后稳定在低约0.01的损失。
这张图验证了veScale-FSDP对结构感知训练方法的支持能力,证明RaggedShard可以在不损失训练质量的前提下支持块级量化和矩阵优化器。
展示了RaggedShard通信的填充开销(额外填充字节/总参数大小)。比较了DeepSeek-V3-671B和GPT-OSS-120B在不同分片粒度(1×/16×/128×参数行大小)和不同FSDP分片大小(GPU数量)下的填充比例。关键发现:1×和16×行粒度下填充开销低于3%;128×行粒度下DeepSeek-V3保持在3%以下,但GPT-OSS出现阶梯状波动,峰值达18%。
这张图量化评估了规划算法的优化质量,展示了不同分片粒度和模型配置下的填充开销,为实际部署提供了配置指导。