大模型推理——分布式技术相关

基本概念

  • RANK:使用 os.environ[“RANK”] 获取进程的序号,一般是1个 gpu 对应一个进程。它是一个全局的序号,从 0 开始,最大值为所有 GPU 的数量减 1
  • LOCAL_RANK:使用 os.environ[“LOCAL_RANK”] 获取每个进程在所在主机中的序号。从 0 开始,最大值为当前进程所在主机的 GPU 的数量减 1
  • WORLD_SIZE:使用 os.environ[“WORLD_SIZE”] 获取当前启动的所有的进程的数量(所有机器的进程总和)

为了便于理解,我们举个例子来说明:假设我们使用了 2 台机器,每台机器 4 块 GPU。那么,RANK 取值为 [0, 7];每台机器上的 LOCAL_RANK 的取值为 [0, 3];WORLD_SIZE 的值为 8。

硬件相关

可以用过nvidia-smi topo -m命令查看

GPU0	GPU1	GPU2	GPU3	GPU4	GPU5	GPU6	GPU7	mlx5_0	mlx5_1	mlx5_2	mlx5_3	mlx5_4	mlx5_5	mlx5_6	mlx5_7	mlx5_8	mlx5_9	CPU Affinity	NUMA Affinity
GPU0	 X 	NV12	NV12	NV12	NV12	NV12	NV12	NV12	PXB	PXB	SYS	SYS	SYS	SYS	SYS	SYS	SYS	SYS	48-63,176-191	3
GPU1	NV12	 X 	NV12	NV12	NV12	NV12	NV12	NV12	PXB	PXB	SYS	SYS	SYS	SYS	SYS	SYS	SYS	SYS	48-63,176-191	3
GPU2	NV12	NV12	 X 	NV12	NV12	NV12	NV12	NV12	SYS	SYS	PXB	PXB	SYS	SYS	SYS	SYS	SYS	SYS	16-31,144-159	1
GPU3	NV12	NV12	NV12	 X 	NV12	NV12	NV12	NV12	SYS	SYS	PXB	PXB	SYS	SYS	SYS	SYS	SYS	SYS	16-31,144-159	1
GPU4	NV12	NV12	NV12	NV12	 X 	NV12	NV12	NV12	SYS	SYS	SYS	SYS	PXB	PXB	SYS	SYS	SYS	SYS	112-127,240-255	7
GPU5	NV12	NV12	NV12	NV12	NV12	 X 	NV12	NV12	SYS	SYS	SYS	SYS	PXB	PXB	SYS	SYS	SYS	SYS	112-127,240-255	7
GPU6	NV12	NV12	NV12	NV12	NV12	NV12	 X 	NV12	SYS	SYS	SYS	SYS	SYS	SYS	PXB	PXB	SYS	SYS	80-95,208-223	5
GPU7	NV12	NV12	NV12	NV12	NV12	NV12	NV12	 X 	SYS	SYS	SYS	SYS	SYS	SYS	PXB	PXB	SYS	SYS	80-95,208-223	5

Legend:
  X    = Self
  SYS  = Connection traversing PCIe as well as the SMP interconnect between NUMA nodes (e.g., QPI/UPI)
  NODE = Connection traversing PCIe as well as the interconnect between PCIe Host Bridges within a NUMA node
  PXB  = Connection traversing multiple PCIe bridges (without traversing the PCIe Host Bridge)
  PIX  = Connection traversing at most a single PCIe bridge
  NV#  = Connection traversing a bonded set of # NVLinks

communication primitive

通信方式在并行任务中通常被分为两大类:点对点通信(Point-to-point communication)和集体通信(Collective communication)。在P2P模式中,通信流程只涉及一个发送者和一个接收者,其实现过程相对较为简单。另一方面,集体通信涉及多个发送者和接收者,常见的通信方式包括 broadcast、gather、all-gather、scatter、reduce、all-reduce、reduce-scatter、all-to-all等操作。

Reduce:从多个sender那里接收数据,最终combine到一个节点上。

All-reduce:从多个sender那里接收数据,最终combine到每一个节点上。

常用库

一般用MPI和NCCL这俩库,在编译fastertransformer的时候:

-- Found NCCL (include: /usr/include, library: /usr/lib/x86_64-linux-gnu/libnccl.so.2.15.5)
-- Found MPI (include: , library: /opt/hpcx/ompi/lib/libmpi.so)

MPI只创建通信域,给所有计算进程编号,NCCL负责GPU聚合通信。

有了NCCL,还是要给进程编号,确定进程角色。这不在NCCL这个NVIDIA Collective Commulication Libraries职责范围中,所以要MPI来配合完成。

MPI

MPI,全称为消息传递接口(Message Passing Interface),是一个标准化和便携式的消息传递系统,设计用于并行计算中的进程间通信。MPI 提供了一种在分布式内存系统中进行进程间通信的方法,这是并行计算的一种常见模式。在这种模式中,每个进程都有自己的私有内存,进程之间的通信需要通过消息传递来完成。

NCCL

NVIDIA 的 NCCL(NVIDIA Collective Communications Library)是一种专门为 GPU 提供的集合通信库,它实现了类似于 MPI 的一些基本操作,如 all-gather、all-reduce、broadcast、reduce 和 reduce-scatter 等。这些操作在并行计算中非常常见,尤其是在需要在多个 GPU 或节点之间共享数据的情况下。Nvidia做了很多优化,以在PCIe、Nvlink、InfiniBand上实现较高的通信速度。

并行方式

DP

数据平行

TP

张量并行

值得注意的是, tensor parallel 会进行大量的通信, 不像 DP/PP 通信内容只是 per layer 的 gradient 或者 activation. TP 一个 layer 内部就要进行多次不同算子的 activation 的通信. 所以实践中 tp 一般会在机内进行, tp size 受此限制也不会超过8.

Tensor parallel can reduce the total end2end latency since the gemm size in the model becomes smaller than the full model version, but it need the cost time of communication to be small enough.
For devices which support nvlink,I do think tensor parallel is more efficient than pipeline parallel.

PP

由于模型过大,单机多卡满足模型的体积需求时,会使用多机多卡的方案,但是由于模型并行策略会带来大量网络通信,若在多机间使用模型并行会由于网络开销的增加降低整体的训练效率;因此,这时可以使用流水线的并行策略,将模型的不同Layer放到不同的node上进行训练,这时仅相邻的layer之间存在网络通信,可以大大的降低网络的通信量。

参考