v6:长序列和 MoE:Context Parallel 与 Expert Parallel

v5 用 TP + PP 把大模型放下了,还有两件事没管。视频很容易到几万 token,activation 跟着 s 涨。想多要参数又不多花 compute 就得用 MoE,expert 一多,每张卡各放一份就放不下。这一课加两维,CP 沿 sequence 切,EP 把 expert 分到不同的卡上。

面试会这样问Once the sequence is sharded, how do you compute full attention across GPUs? · Implement an MoE layer and show the dimensions. · How do dispatch and combine work under expert parallelism?

考过NVIDIA SWE("Implement MoE and show the dimensions",Glassdoor RVW105422785,年份未核实;Glassdoor 的另一条摘要里,同一场还问了 CUDA kernel optimization,追问 kernel fusion 和 launch overhead)· 美团("手撕:用python实现moe")· 阿里("ep的dispatch和combine")· 智谱(手撕 MoE 层的 dispatch)· 牛客("推导MoE架构的负载均衡损失函数,如何避免专家坍缩")· 腾讯混元("序列切块后,跨卡如何完成完整的 Attention 计算?")· 牛客("CP 的并行方式和并行思想,ring 和 ulysses 的技术介绍")· Kimi(Ulysses 与 Ring Attention、online softmax 的 LSE 合并,营销号转发,可信度低)

问题:sequence 一长,activation 先爆

还是 Qwen3-VL-8B 的 LLM 部分(h = 4096、36 层、b = 1),按 Korthikanti 公式粗估:

CP:每张卡只管一段 token

Context Parallel(CP)把所有 activation 沿 sequence 切成 cp 份。LayerNorm、MLP 逐 token 算,只有 attention 需要看别人的 token。

另一种做法 Ulysses,以及 CP 和 SP 的区别

DeepSpeed-Ulysses 不让 KV 绕环,先对 Q、K、V 做一次 all-to-all,把“按 sequence 切”换成“按 head 切”,每卡拿到完整序列、a/cp 个 head,本地算普通 attention,再 all-to-all 换回来,所以 cp 不能超过 head 数。Qwen3-8B 有 32 个 query head,但只有 8 个 KV head,K、V 要切成 8 份以上就得复制 KV head。

SP(第 5 课)CP(ring)Ulysses
切什么只切 TP 没切的 LayerNorm、dropout 的 activation全部 activation同 CP
和 TP 的关系依附 TP,份数是 t独立的一维,可叠加 TP + SP同 CP
通信和 TP 一样多能和计算 overlap要等 all-to-all 完才能算
上限t ≤ 8每块要够长,算得比传得久cp ≤ head 数

Megatron 用 --cp-comm-type 选:p2p(ring,默认)、a2a(Ulysses 式)、a2a+p2p(机内 a2a,机间 p2p)。

你的经验视频 VLM 的长序列正是 CP 要解决的场景。去查一下:你 TikTok 任务里最长的样本有多少 token?当时靠什么放下的(截断、少抽帧、gradient checkpointing)?verl 的 FSDP 后端自带 Ulysses(ulysses_sequence_parallel_size),看看 OpenManus-RL 的配置里开没开,这是你的项目接到 CP 的入口。

MoE:参数很多,每个 token 只算一点

NVIDIA 原题:Implement MoE and show the dimensions

设一个 micro-batch 有 T = 4096 个 token,h = 4096,E = 8,k = 2,capacity factor cf = 1.25:

步骤做什么shape
输入把 batch 和 sequence 两维拍平x:[T, h] = [4096, 4096]
routerx 乘 Wr([h, E]),再 softmax[T, E] = [4096, 8]
top-k每个 token 取最大的 k 个 expert 和 gate 值[T, k] = [4096, 2]
dispatch按 expert 分组,每组最多 C 个 token,不满的 pad[E, C, h] = [8, 1280, 4096]
expert每个 expert 跑自己的 FFN:h → 12288 → h[E, C, h]
combine放回原位置,k 份输出按 gate 加权求和y:[T, h] = [4096, 4096]

EP:expert 分到不同的卡上,用 all-to-all 送 token

30 秒英文回答

Long sequences blow up activation memory, so context parallelism shards every activation along the sequence across cp GPUs. Only attention needs other GPUs' tokens: each GPU keeps its query block and passes KV blocks around a ring, merging partial results with online softmax while the transfer hides behind compute. MoE replaces the FFN with E experts and a router that picks the top-k per token, so parameters grow with E but compute only with k. Expert parallelism puts experts on different GPUs; dispatch and combine are all-to-alls, often the bottleneck. A load-balancing loss prevents expert collapse.

自测

MoE 不加 load balancing loss 会怎样?

少数 expert 包揽一切(expert collapse),其余参数白占。有 capacity 时热门 expert 大量 drop token,EP 下它所在的卡成为 straggler。

CP 和 SP 有什么区别?

SP 依附 TP,只切 LayerNorm、dropout 的 activation,进 attention 前要 all-gather 回完整序列。CP 是独立的一维,切全部 activation,attention 靠 KV 绕环完成。两者可以同时开。

EP 为什么用 all-to-all,不用 all-gather 或 all-reduce?

每张卡发给每张卡的 token 不同,去向由 router 决定。all-reduce 是同形状求和,语义不对。all-gather 会把每个 token 发给所有卡,大部分用不上。

某个 expert 收到的 token 超过 capacity 会怎样?

超出的 token 在这个 expert 上被 drop,只经 residual 进下一层(k = 2 时另一个 expert 可能还在算它)。没收满的位置 pad。cf 调大能少 drop,但多算多传。

写出 MoE forward 每一步的 shape。(NVIDIA SWE 原题)

就是上面的表,[T, h] → [T, E] → [T, k] → [E, C, h] → [T, h]。延伸(自拟):launch overhead 大时,先按 expert 给 token 排序,用一个 grouped GEMM 算完。