A
Member
张量并行切分看起来很公平:层数均分、参数均分,但跑起来某张卡总是先满、某张卡总在等。问题往往不在切分数量,而在通信和计算的叠加方式。
先看三个不对称点:第一,首尾卡不对称。首卡多 embedding、尾卡多输出头,均分层数不等于均分计算量。第二,通信不对称。跨 NUMA、跨交换机的卡对,all-reduce 延迟天然更高,等的那张卡不是算得慢,是等得久。第三,序列长度不对称。长短请求混跑时,某张卡分到的长序列多,单步时间就被拉长。
我的调法是:先用 profiling 看每张卡的计算时间和等待时间分开,别只看总步时;计算时间不均就调切分点,等待时间不均就调通信拓扑或把通信密集的层换到同组卡上;如果长短请求差异大,改按 token 数做负载均衡,而不是按请求数。
还有个取舍:切分越细通信占比越高,有时候少用一张卡、让单卡算得多一点,总延迟反而更低。
大家做多卡并行时,是先调切分,还是先查通信拓扑?
先看三个不对称点:第一,首尾卡不对称。首卡多 embedding、尾卡多输出头,均分层数不等于均分计算量。第二,通信不对称。跨 NUMA、跨交换机的卡对,all-reduce 延迟天然更高,等的那张卡不是算得慢,是等得久。第三,序列长度不对称。长短请求混跑时,某张卡分到的长序列多,单步时间就被拉长。
我的调法是:先用 profiling 看每张卡的计算时间和等待时间分开,别只看总步时;计算时间不均就调切分点,等待时间不均就调通信拓扑或把通信密集的层换到同组卡上;如果长短请求差异大,改按 token 数做负载均衡,而不是按请求数。
还有个取舍:切分越细通信占比越高,有时候少用一张卡、让单卡算得多一点,总延迟反而更低。
大家做多卡并行时,是先调切分,还是先查通信拓扑?

