抱歉,您的浏览器无法访问本站

本页面需要浏览器支持(启用)JavaScript


了解详情 >

大模型训练优化

大模型现状

处理大模型的主要办法是数据切分,然后做数据并行, 模型并行和张量并行。原理略

总结一下数据并行和模型并行存在的资源利用率问题:

  • 数据并行
    • 多个GPU上需要存储相同的模型,导致模型资源占用放大
    • 每次迭代最后都有不小的模型同步开销
  • 模型并行: 流水线并行 + 张量并行
    • 大模型训练的流水线需要等待执行结果,无法多发射,导致资源闲置和利用率低
    • 流水线各个阶段的负载不均匀会导致整体性能直接受到最慢任务影响
  • 张量并行
    • 可以利用线性代数进行分块矩阵乘法,但是每次计算都会引入合并操作,带来额外”通信”开销
  • 计算过程分得越细,通信开销越大
    • 考虑到不同细分粒度对通信的的影响,结合异构网络,可以想到通信频率高的(张量划分)尽量本地执行。
    • 多级影响范围:张量并行可以在卡内做, 模型并行可以在卡间做

思路

通用的解决思路

  • 数据并行问题1: 大模型存不下。所以可以结合模型并行的思路将模型的计算任务细分,实现某种混合模式
    • 代表:ZeRO
  • 数据并行问题2: 最后的模型同步开销。可以利用局部等待的方式实现局部规约从而达到全局的收敛
    • 代表:河图
  • 数据并行问题3: 重复的模型副本
    • 模型复用: 如GPU0算前一半, GPU1算后一半, 算完结果交互合并得到完整数据
  • 模型并行问题1:需要等待反馈结果,流水线阻塞。可以通过局部等待的方式让流水线提前结束等待。
  • 模型并行问题2:计算负载不均匀。
  • 混合模式1:以数据并行为主,并行执行的是细分后的模型
  • 混合模式2:数据并行 + 模型并行 + 张量并行

其他考虑

  • 单卡处理
    • 根据模型并行的思路,每个GPU执行一部分子模型,那么完全可以子模型轮流在单卡上加载执行
  • GPU对不同数据的处理能力不同,如处理float16性能要强于float32,因此可以通过设计数据类型做优化
  • 数据的随机切分不好,想办法人为制造局部性
    • 比如Personal Page Rank中, source这种”关注点”的机制即可以做内存管理的依据,也可以做切分的依据
  • 异构感知
    • GPU CPU SSD间换入换出的异构存储感知,采用LRU等策略管理换入换出
    • 大小核,执行能力不同,尽量调度集群中的大核执行。或者对任务重排序,让大核先执行,这样在等小核瓶颈时大核就有更多空闲时间可供调度
    • 本地通信,远端通信,高性能通信,普通通信。想办法让数据通路也可调度,让高速的通路优先级更高。
    • 显存感知。显存不足将引入跨设备通信,所以可以尽可能在显存充足的计算件上执行
  • 通信瓶颈主要源于模型同步时的等待
  • GPU无虚拟内存,内存碎片问题
    • 手动做内存管理,以Page为单位,代表: Angle-PTM
  • 任务代理: 一个任务有模型和数据两部分组成
    • 模型大时可以拷贝数据到其他节点执行,而不是拷贝模型
    • 数据大时可以拷贝模型到其他节点执行,而不是拷贝数据
  • 高频通信优先在本地
    • 张量并行, 数据并行, 模型并行的通信频率不同,且主要开销在于通信。所以可让需要高频通信的集中在本地执行,如张量并行
  • 好数据集

图计算考虑

感觉图计算主要是做数据并行,那么就要做图分割。如果分割后的子图大于GPU数,那就需要换入换出,用到上述的考虑。不过一个GPU不一定执行一个任务,一个GPU也是可以多任务执行的,所以需要显存感知然后做调度。

  • 对于不同图计算场景调度策略不同,如Personal Page Rank场景似乎会有更明显的局部性
  • 如果说图计算算力过剩而显存不足,那可不可以使用计算换空间的策略。比如编码或者数据重算。
  • 任务代理:调度一个任务时数据和模型分离,数据和模型只需要传输开销小的到其他节点之前,另一半就复用

评论