Skip to content

bug fix: probe RDMA link rate via sysfs, survive probe failure - #734

Open
Xuan-1998 wants to merge 1 commit into
deepseek-ai:mainfrom
Xuan-1998:envs-sysfs-rdma-probe
Open

bug fix: probe RDMA link rate via sysfs, survive probe failure#734
Xuan-1998 wants to merge 1 commit into
deepseek-ai:mainfrom
Xuan-1998:envs-sysfs-rdma-probe

Conversation

@Xuan-1998

Copy link
Copy Markdown

get_rdma_gbs() only knew how to ask ibstat for a CA named EP_NIC_NAME (default mlx5_0). EFA devices expose no umad CA, so on EFA hosts the probe returned 0 and get_theoretical_num_sms() divided by it -- any multi-node run without an explicit --num-sms crashed with ZeroDivisionError.

Read /sys/class/infiniband//ports/*/rate first, which works for every verbs provider, and fall back to ibstat for setups whose rate only shows there. When EP_NIC_NAME is unset and the default device is absent, pick the fastest device under /sys/class/infiniband instead of failing; an explicitly named NIC still fails loudly rather than guessing.

get_rdma_gbs() only knew how to ask ibstat for a CA named EP_NIC_NAME
(default mlx5_0). EFA devices expose no umad CA, so on EFA hosts the
probe returned 0 and get_theoretical_num_sms() divided by it -- any
multi-node run without an explicit --num-sms crashed with
ZeroDivisionError.

Read /sys/class/infiniband/<nic>/ports/*/rate first, which works for
every verbs provider, and fall back to ibstat for setups whose rate
only shows there. When EP_NIC_NAME is unset and the default device is
absent, pick the fastest device under /sys/class/infiniband instead of
failing; an explicitly named NIC still fails loudly rather than
guessing.
Comment thread deep_ep/utils/envs.py

# The un-overridden default may simply not exist on this fabric; an explicitly named NIC
# must not fall back silently
if 'EP_NIC_NAME' not in os.environ:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 warning: 不要把显式 nic_name 回退到其他设备: 当调用方显式传入 get_rdma_gbs("missing-or-down-nic") 且未设置 EP_NIC_NAME 时,此条件仍会扫描全部设备并返回另一块 NIC 的速率。这违背了显式指定 NIC 不应猜测回退的约定,并可能使用错误带宽进行调优;应依据参数是否被省略来决定是否自动发现设备。

🤖 v6

Comment thread deep_ep/utils/envs.py
ports_dir = os.path.join('/sys/class/infiniband', nic_name, 'ports')
try:
for port in os.listdir(ports_dir):
with open(os.path.join(ports_dir, port, 'rate')) as f:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 suggestion: 正则 r'\s*(\d+)\sGb/sec' 无法匹配带小数的速率(如老式 SDR 1X 的 "2.5 Gb/sec"),此类设备会被解析为 0。可考虑改用 r'\s(\d+(?:.\d+)?)\s*Gb/sec' 并用 float 解析。对现代 HPC 网卡影响可忽略,仅作健壮性建议。

🤖 v5

Comment thread deep_ep/utils/envs.py
gbs: the device's link rate in GB/s (0 if the device or its rate is unavailable).
"""
rate = 0
ports_dir = os.path.join('/sys/class/infiniband', nic_name, 'ports')

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 suggestion: sysfs 的 ports//rate 在端口 state 为 DOWN 时也可能报告一个速率。在 EP_NIC_NAME 未设置的『选最快设备』分支里,可能选中一个链路未激活的设备。可选改进:同时读取 ports//state,仅统计 ACTIVE("4: ACTIVE")端口。

🤖 v5

Comment thread deep_ep/utils/envs.py
if gbs > 0:
return gbs

# The un-overridden default may simply not exist on this fabric; an explicitly named NIC

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 suggestion: 当所有探测(sysfs、最快设备扫描、ibstat)都失败时函数仍返回 0,调用方 get_theoretical_num_sms()(deep_ep/buffers/elastic.py:761 附近)在 num_rdma_ranks > 1 时仍可能触发 ZeroDivisionError。本 MR 已消除 EFA 场景的主要触发路径,但如果想彻底『survive probe failure』,建议在调用方对 rdma_gbs == 0 给出明确报错(提示设置 EP_NIC_NAME 或显式传入 --num-sms)。

🤖 v5

Comment thread deep_ep/utils/envs.py
devices = sorted(os.listdir('/sys/class/infiniband'))
except OSError:
devices = []
gbs = max((_get_sysfs_rdma_gbs(device) for device in devices), default=0)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 warning: 当 /sys/class/infiniband 下没有任何设备(或所有设备的 rate 都读不到)且后续 ibstat 也失败时,get_rdma_gbs() 仍会返回 0;而 deep_ep/buffers/elastic.py 的 get_theoretical_num_sms() 在 num_rdma_ranks > 1 时会执行 rdma_traffic / rdma_gbs,仍会触发 ZeroDivisionError。既然目标是 survive probe failure,建议在调用处对探测结果为 0 的情况做兜底(例如回退到保守默认带宽或给出明确报错),而不是继续除以 0。

🤖 v4p

Comment thread deep_ep/utils/envs.py

# The un-overridden default may simply not exist on this fabric; an explicitly named NIC
# must not fall back silently
if 'EP_NIC_NAME' not in os.environ:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 suggestion: 自动猜测逻辑用 'EP_NIC_NAME' not in os.environ 判断“是否显式指定了网卡”,但函数参数 nic_name 也可以由调用方显式传入。例如未设置 EP_NIC_NAME 时调用 get_rdma_gbs('mlx5_0'),若 mlx5_0 不存在,代码仍会静默选择其他最快设备,与“显式指定网卡应 loudly fail”的说明不一致。建议用 sentinel 默认值(如 nic_name=None 时再取环境变量默认值)来区分默认值与显式传参。

🤖 v4p

@ds-review-bot

Copy link
Copy Markdown
Collaborator

🤖 ds-review-bot Code Review

v6

自动发现条件无法区分默认调用与显式函数参数,导致显式指定失败时静默使用无关设备的速率。

v5

该 MR 修复了 EFA 主机上 get_rdma_gbs() 探测失败导致 get_theoretical_num_sms() 除零崩溃的问题。改动仅涉及 deep_ep/utils/envs.py(与描述一致,变更文件数为 1):新增 _get_sysfs_rdma_gbs() 优先从 /sys/class/infiniband/<nic>/ports//rate 读取链路速率(对所有 verbs provider 通用,包括 EFA 的 rdmap 设备);保留 ibstat 作为最终回退;当 EP_NIC_NAME 未显式设置且默认设备(mlx5_0)不存在时,扫描 /sys/class/infiniband 选取最快设备,而显式指定的 NIC 不会静默回退、仍会明确失败。已核对的行为要点:多端口 CA 取各端口速率的 max,与旧 ibstat 路径(只取第一个 Port 的 Rate)语义一致;『不静默回退』通过 'EP_NIC_NAME' in os.environ 判断实现,显式传参 nic_name 时同样不回退,符合描述;lru_cache 以 nic_name 为键、行为依赖进程内稳定的环境变量,无问题;OSError 均被捕获,防御性良好;文件头新增的 MIT/Amazon 版权声明为合规性改动,与功能无关。整体实现正确、与提交说明完全吻合,建议合并。以下评论均为非阻塞的改进建议。

v4p

该 MR 旨在修复 RDMA 带宽探测在 EFA 等无 umad CA 设备上返回 0、进而导致 get_theoretical_num_sms 自动计算 SM 数时除零崩溃的问题:新增从 /sys/class/infiniband/<nic>/ports/*/rate 读取速率,保留 ibstat 作为回退,并在未设置 EP_NIC_NAME 且默认网卡缺失时自动选择 sysfs 下最快的 RDMA 设备。整体方向正确、实现简洁,但探测完全失败时仍会返回 0,且显式传入 nic_name 参数时仍可能被自动猜测,建议补齐这两个边界。

Files reviewed: 1
Issues found: 🟡 2 warning | 🔵 4 suggestion
Inline comments posted: 6

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants