RAS
可靠性、可用性和可服务性(RAS)子系统可以用来查询 MCCL 作业在执行期间的健康状况。 这有助于诊断和调试崩溃和挂起的问题。RAS 是一个低开销的基础设施,MCCL 用户和开发者可以在应用程序运行时使用。 它提供了运行中应用程序状态的全局视图,并可以帮助检测异常情况,如无响应的进程。 有了这些信息,用户随后可以通过其他技术,如交互式调试、系统日志分析等,缩小怀疑的根本原因。
工作原理
RAS 内置于 MCCL 中,并在 MCCL 初始化时启动。 它由一组线程组成(每个进程一个),这些线程相互建立连接,形成一个网络,RAS 线程随后使用这个网络交换信息并监控彼此的健康状况。 在典型配置中,RAS 网络流量(在初始化期间使用的引导/带外网络接口上使用普通的 TCP/IP 套接字)不应与主要的 MCCL 流量(使用 RDMA 网络)竞争。 RAS 是轻量级的,不应干扰主要的 MCCL 作业;因此,它默认是启用的(但请参见 MCCL_RAS_ENABLE)。
RAS 线程相互通信,告知作业配置的任何变化;它们还交换定期的保持活动消息。 如果 MCCL 进程崩溃或挂起,其他 MCCL 进程上运行的 RAS 线程会通过 RAS 网络连接到该进程被关闭或变得无响应来了解情况。
RAS 查询
RAS 线程还在 localhost 上监听客户端连接,端口为 28028(这些默认值可以使用 MCCL_RAS_ADDR 进行更改)。
可以使用 mcclras 二进制客户端连接到该套接字,并查询 RAS 子系统以获取当前作业状态,然后将其打印到标准输出。
客户端接受 -h 和 -p 参数来指定主机名和端口,-v 以在遇到问题时产生更详细的输出,以及 -t 来指定不同的超时时间(默认为 5 秒;0 禁用超时)。
由于客户端通信协议完全是基于文本的,可以使用 telnet 或 netcat 等标准网络工具代替 mcclras 二进制文件。
相关命令包括 STATUS、VERBOSE STATUS(等同于 mcclras 客户端的 -v 参数)和 TIMEOUT <seconds>(等同于 -t);例如,echo verbose status | nc localhost 28028。
无论查询是如何提交的,接收到的 RAS 线程都会返回作业摘要信息以及所有 MCCL 通信器的摘要信息; 后者是从作业的所有进程中收集的,因此,对于遇到问题或特别大的作业,响应可能需要几秒钟才能生成。 如果遇到任何问题,还会提供额外的信息。
示例输出
这一节包含了 RAS 状态输出的摘录。请注意,提供的信息的确切格式和范围预计将发展; 摘录仅用于说明目的。
这是一个正常进行中的作业的示例输出:
作业摘要
===========
节点 进程数 GPU 数 进程数 GPU 数
(总数) 每节点 每个进程 (总数) (总数)
4 8 1 32 32
我们有一个由 4 个节点组成的作业,运行着 32 个 GPU(每个进程 1 个 GPU)。
通信器... (0.00s)
=============
组 通信器数 节点数 秩数 秩数 秩数 状态 错误
# 组内 每通信器 每节点 每通信器 组内
0 8 4 1 4 32 RUNNING OK
GPU 被分成 8 个通信器,每个节点 1 个 GPU。RAS 试图通过将具有相同大小和其他重要属性的对象分组在一起,使摘要输出尽可能短。
对于在 RAS 查询期间积极通信的作业,有时可能会观察到以下输出:
组 通信器数 节点数 秩数 秩数 秩数 状态 错误
# 组内 每通信器 每节点 每通信器 组内
0 1 4 8 32 32 RUNNING MISMATCH
输出表明不同通信器秩提供的信息存在不一致性。 下面打印了额外的信息(在这种情况下,它在警告部分,表示可能较低的严重性):
警告
========
#0-0 (27a079b828ff1a75) MISMATCH
通信器秩有不同的集体操作计数
26 个秩已启动到操作 6650
6 个秩已启动到操作 6649
秩 0 -- GPU 0 由节点 172.16.64.210 上的进程 483072 管理
秩 2 -- GPU 2 由节点 172.16.64.210 上的进程 483074 管理
秩 3 -- GPU 3 由节点 172.16.64.210 上的进程 483075 管理
秩 4 -- GPU 4 由节点 172.16.64.210 上的进程 483076 管理
秩 5 -- GPU 5 由节点 172.16.64.210 上的进程 483077 管理
秩 7 -- GPU 7 由节点 172.16.64.210 上的进程 483079 管理
通信器使用 #<x>-<y> 标识符进行引用,其中 <x> 是摘要输出中的组号,<y> 是组内的通信器号,两者都从 0 开始(在这个例子中,只有一个(32-GPU)通信器,所以不出所料,标识符是 #0-0)。
标识符后面跟着一个通信器哈希值,这个值也可以在 MCCL 的常规调试输出中找到,以及秩信息。
RAS 将具有相同相关属性的秩分组在一起(在这种情况下是发出的集体操作的数量)。
如果一个组是一个异常值,RAS 会打印有关每个组成员的额外信息。
默认情况下,如果组的大小最多是总数的 25% 并且组内成员不超过 10 个,则会这样做;
启用详细输出会将其放宽到总数的 50% 以下,并取消组大小限制。
上述特殊情况只要在重复查询中计数增加,就不应引起关注。 MCCL 集体操作,为了优化速度,可以轻松地超越 RAS 集体查询,特别是如果集体操作的大小相当小的话。 应用程序也可能表现出工作不平衡,某些秩通常会比其他秩晚到达集体操作——需要对特定工作负载的经验来确定什么是正常什么是不正常。 然而,如果输出在随后的 RAS 查询中没有变化,可能表明通信器由于某种原因"卡住"了,这可能需要进行调查。
有时在通信器初始化或拆除期间可能会观察到类似的效果:
组 通信器数 节点数 秩数 秩数 秩数 状态 错误
# 组内通信器数 每通信器 每节点 组内通信器 组内
0 1 4 1-2 32 32 FINALIZE MISMATCH
1 7 4 1 4 28 RUNNING OK
2 1 4 1 4 4 INIT OK
[...]
#0-0 (9e17999afaa87dbb) MISMATCH
通信器秩有不同的状态
26 个秩有状态 UNKNOWN
4 个秩有状态 RUNNING
秩 0 -- GPU 0 由节点 172.16.64.210 上的进程 507285 管理
秩 8 -- GPU 0 由节点 172.16.64.212 上的进程 1598388 管理
秩 16 -- GPU 0 由节点 172.16.64.213 上的进程 3500071 管理
秩 24 -- GPU 0 由节点 172.16.64.222 上的进程 2405067 管理
2 个秩有状态 FINALIZE
秩 4 -- GPU 4 由节点 172.16.64.210 上的进程 507289 管理
秩 20 -- GPU 4 由节点 172.16.64.213 上的进程 3500075 管理
上述快照显示了一个过渡情况,最初的 32-GPU 通信器正在被八个 4-GPU 通信器取代(其中一个仍在初始化中,因此它被单独列出(组 #2)与已经初始化的七个(组 #1))。
32-GPU 通信器(#0-0)正在被拆除,有两个秩正在进行 mcclCommFinalize,四个秩尚未调用 mcclCommFinalize,其余 26 个秩"未知"——意味着当 RAS 收集数据时,它们没有提供有关该通信器的任何信息,仅仅因为它们对 mcclCommFinalize 的调用已经完成,所以它们实际上不再是该通信器的成员。
同样,只要在重复查询时情况得到解决,就可以忽略。
以下是在人为制造了一个作业进程的问题后立即调用的摘录:
通信器... (2.05s)
=============
组 通信器数 节点数 秩数 秩数 秩数 状态 错误
# 组内通信器数 每通信器 每节点 每通信器 组内
0 1 4 7-8 32 32 RUNNING INCOMPLETE
错误
======
INCOMPLETE
缺少 1 个作业进程的通信器数据
进程 3487984 在节点 172.16.64.213 上管理 GPU 5
#0-0 (cf264af53edbe986) INCOMPLETE
缺少 1 个秩的通信器数据
缺失的秩:21
警告
========
TIMEOUT
在收集通信器数据时遇到了 2 个通信超时
在这种情况下,摘要需要几秒钟才能生成,因为 RAS 等待来自遇到问题的进程的数据(该进程无响应——它被停止了——但 RAS 还不知道)。 重复查询应该会快得多,因为一旦 RAS 确定一个进程无响应,它会重新配置 RAS 网络以绕过它。
RAS 将尝试重新与无响应的进程建立通信;如果它在 60 秒内无法这样做,它将宣布该进程死亡(永久):
错误
======
DEAD
1 个作业进程被认为是死亡的(通过 RAS 网络无法到达)
进程 3487984 在节点 172.16.64.213 上管理 GPU 5
#0-0 (cf264af53edbe986) INCOMPLETE
缺少 1 个秩的通信器数据
缺失的秩:21
RAS 将不再尝试通过 RAS 网络与这些进程通信,由用户决定是否需要采取任何额外行动。

