跳转至

ray_backend.py — 这个文件实现了基于 Ray 的 NCCL 通信器汇合(Rendezvous) 机制

模块路径: verl.utils.rendezvous.ray_backend

文件概述

这个文件实现了基于 Ray 的 NCCL 通信器汇合(Rendezvous) 机制。在分布式 GPU 训练中,NCCL(NVIDIA Collective Communications Library)是 GPU 间通信的核心库。创建 NCCL 通信组需要所有参与者共享一个唯一 ID,这个文件使用 Ray Actor 来实现这个 ID 的分发。

关键代码讲解

1. NCCL ID 存储 Actor

@ray.remote
class NCCLIDStore:
    """Ray Actor: 存储和分发 NCCL 唯一 ID"""
    def __init__(self, nccl_id):
        self._nccl_id = nccl_id

    def get(self):
        return self._nccl_id

这是一个非常简单的 Ray Actor,只做一件事:存储 NCCL ID 并允许其他进程获取。

2. 按名称查找 Actor

def get_nccl_id_store_by_name(name):
    """在 Ray 集群中按名称查找 NCCLIDStore Actor"""
    all_actors = list_named_actors(all_namespaces=True)
    matched_actors = [actor for actor in all_actors if actor.get("name", None) == name]
    if len(matched_actors) == 1:
        return ray.get_actor(**actor)
    return None

3. 创建 NCCL 通信器

def create_nccl_communicator_in_ray(rank, world_size, group_name, max_retries=100, interval_s=5):
    if rank == 0:
        # Rank 0:生成唯一 ID,创建存储 Actor,创建通信器
        nccl_id = get_unique_id()
        nccl_id_store = NCCLIDStore.options(name=group_name).remote(nccl_id)
        communicator = NcclCommunicator(ndev=world_size, commId=nccl_id, rank=0)
        return communicator
    else:
        # 其他 Rank:轮询获取 ID,然后创建通信器
        for i in range(max_retries):
            nccl_id_store = get_nccl_id_store_by_name(group_name)
            if nccl_id_store is not None:
                nccl_id = ray.get(nccl_id_store.get.remote())
                communicator = NcclCommunicator(ndev=world_size, commId=nccl_id, rank=rank)
                return communicator
            time.sleep(interval_s)  # 等待 rank 0 创建 ID

汇合流程: 1. Rank 0 生成唯一的 NCCL ID,创建命名 Actor 存储它 2. 其他 Rank 通过名称查找该 Actor,获取 NCCL ID 3. 所有 Rank 使用同一个 NCCL ID 创建通信器

轮询机制(max_retries * interval_s = 500秒)确保即使 Rank 0 启动较慢也能成功汇合。

核心类/函数列表

类/函数名 作用
NCCLIDStore Ray Actor,存储 NCCL ID
create_nccl_communicator_in_ray 创建 NCCL 通信器
get_nccl_id_store_by_name 按名称查找 Actor

与其他模块的关系

  • 使用 cupy.cuda.nccl 的 NCCL 绑定
  • 使用 Ray 的 Actor 和 list_named_actors API
  • 用于在 Ray 集群中建立 GPU 直连通信

小结

这个文件解决了一个分布式系统的经典问题:汇合(Rendezvous)。在 Ray 集群中,各 worker 可能在不同时间启动,需要一种机制让它们协调并建立通信。使用 Ray 的命名 Actor 作为"公告板",Rank 0 发布 NCCL ID,其他 Rank 查询并加入。这种设计简洁且可靠。