Hugging Face 介绍了基于 Snowflake/DeepSpeed 的 Ulysses 序列并行(Sequence Parallelism,SP),通过在序列和注意力头上分片并用 all-to-all 通信交换 KV,实现对百万级 token 上下文的训练,从而突破单卡显存限制并降低通信延迟。该方案已集成到 Accelerate、Transformers Trainer 与 TRL 的 SFTTrainer,并提供配置要点、最佳实践与基准诊断方法。
背景与挑战
– Transformer 注意力计算随序列长度呈二次放大,长序列(数万到百万 token)训练在单 GPU 上受显存和计算限制。
– FlashAttention 等优化能降低内存开销但无法改变计算量,仍难以支持超长上下文训练。
Ulysses 核心思路
– 同时沿序列维度分片(sequence sharding)和按注意力头分割计算(head parallelism)。
– 流程要点:
– 序列切分到 P 个 GPU 的本地片段并计算本地 Q/K/V 投影;
– 第一次 all-to-all,把每个位置的投影按头分配到对应 GPU(每卡持有所有位置但仅部分头);
– 各卡对分配到的头执行本地注意力(可用 FlashAttention/SDPA);
– 第二次 all-to-all 将结果返还到序列分片格式,完成输出投影。
– 关键结论:注意力头之间独立,利用头局部性以交换序列局部性,通信量与延迟可控。
通信复杂度对比
– Ulysses 每层需两次 all-to-all,每卡通信量约 O(n·d / P)。
– Ring Attention 则每卡近似 O(n·d),并通过 P-1 次点对点串行传输,延迟更高。
Accelerate 与生态集成
– Accelerate 提供 ParallelismConfig 与 DeepSpeed 集成接口,示例参数包括 sp_size、sp_attn_implementation(flash_attention_2/3 或 sdpa)等。
– accelerator.prepare() 会自动:
– 注册模型到 DeepSpeed 的 UlyssesSPAttentionHF;
– 包装 dataloader 为 UlyssesSPDataLoaderAdapter 以处理序列分片;
– 注入 shift_labels 以正确汇总损失。
损失与训练器集成
– 每卡计算不同序列片段上的 token 损失,必须按每卡有效 token 数加权汇总。
– Hugging Face 的 Transformers Trainer 与 TRL 的 SFTTrainer 都提供了与 Ulysses 的集成配置示例与关键参数说明。
最佳实践(摘要)
– 确保序列长度对并行度整除以减少碎片和对齐开销。
– 优先使用 FlashAttention 实现以降低内存和加速本地注意力。
– 可与 DeepSpeed ZeRO 结合以进一步降低显存峰值。
– 使用对内存碎片友好的 PyTorch allocator、2D 并行配置与 Liger kernel 等优化。
– 注意合理分配 token 到各 rank,避免热点不均。
基准与诊断
– 文中给出 4 GPU 等多种实验设置,展示了内存降低、吞吐与损失曲线对齐的结果,并提供调试/诊断建议与资源链接。
资源
– 文中链接到 DeepSpeed Ulysses 论文、Snowflake 工程博客与 Hugging Face 文档和示例代码,便于在 Accelerate/Trainer/TR L 中复现部署。
Ulysses 在实战中是可行且高效的长序列训练路径,但对通信拓扑和数据分片策略要求较高。