ICI 交接
ICI(Inter-Chip Interconnect,芯片间互连)是 pod 内连接 TPU 芯片的专用铜缆 / 光纤 fabric。ICI bringup 由 tpunetd 负责;Megascale 的 bootstrap rendezvous 只消费该 bringup 的结果,但从不直接触碰 ICI 本身。本页记录显式的数据流交接, 以及双方各自读取 / 写入的内容。
从 tpunetd → Megascale 流动的三类状态
- 芯片坐标。 pod 中的每颗芯片都会分配一个坐标元组 (x, y, z, …),供 ICI fabric 用于路由。坐标由 tpunetd 的
SessionControl/SetChipCoordinates设置(或通过SetGlobalChipId设置 pod 范围内的唯一标识)。Worker 通过SessionControl/GetChipCoordinates读取分配给自己的坐标,并把它们合入TpuTopologyArgsProto,该 proto 会进入 MegascaleGetMultiSliceTopologyRequest.tpu_topology_args字段。 - 路由表。 tpunetd 的
SetRoutingTable为每颗芯片写入逐链路 next-hop 表;daemon 会把它们编程进 ICI 链路硬件。Megascale 的 bootstrap 不会传输路由表,它们完全是 slice 内部的事项。Megascale 只关心 ICI 已经启动,从而生成的TpuTopologyArgsProto在同一 slice 的各 host 之间保持一致。 - Host 网络绑定。 Megascale 请求中的
HostNetworkAddress条目携带 由 host 的MEGASCALE_PORT派生出的address,以及在 host 的 DCN interface 上解析得到的interface_name(HostNetworkAddress消息恰好有四个字段:address、interface_name、numa_node、host_name_for_debugging)。 这些不是 ICI;它们是 DCN 侧绑定,用于通过普通 TCP/gRPC 承载跨 slice 流量。 ICI fabric 服务 slice 内芯片到芯片的流量;DCN 服务 slice 到 slice 的 host 到 host 流量。
单个 host bringup 内的顺序
host bringup
│
▼
tpunetd_client::TpunetdClient::Init
│ 通过 /var/google/services/tpunetd/user.socket 执行 ConnectToTpunetd
│
▼
tpunetd_client::TpunetdControl::StartSession
│ 传入逐 host 的 DriverInterface ChipLocation vector
│
▼
tpunetd daemon:
│ CreateNetwork(为此 slice 分配 NetworkContextId)
│ ConfigureIci(编程逐芯片 ICI 链路配置)
│ EnableIciDataLink(开启高速链路)
│ WaitForDataLinkUp(阻塞直到每条链路达到 L1 同步)
│ SetChipCoordinates / SetGlobalChipId(逐芯片分配)
│ SetRoutingTable(逐芯片逐链路 next-hop 表)
│ SetGtcConfiguration / WaitForGtcReset(全局时间计数器同步)
│
▼
tpunetd_client::SessionMaster::BroadcastBarrier
│ 在此 slice 的所有 host 间执行 Notify + WaitForReady
│ 确保任何 host 的 runtime 继续之前,每个 host 都完成了 StartSession
│
▼
Local runtime: 从以下内容构建 TpuTopologyArgsProto
- 芯片坐标(GetChipCoordinates 结果)
- ICI 维度(TPU_PROCESS_BOUNDS, TPU_HOST_BOUNDS)
- 逐 host stride(TPU_CHIPS_PER_HOST_BOUNDS)
- twist 因子(TPU_TOPOLOGY_ALT, TPU_TOPOLOGY_WRAP)
│
▼
xla::megascale::runtime::CommunicationBackend::DiscoverTopologyAnd
AddressBindings(slice_id, *that TpuTopologyArgsProto*, host_id,
num_slices)
```text
只有到这个序列的底部,Megascale 的 bootstrap 才会运行。此时 ICI 已经完成 bringup,
芯片坐标已经最终确定,`TpuTopologyArgsProto` 会如实描述本地 slice。
## coordinator 如何使用这次交接
`TopologyCoordinator::ProcessRequest` (`0x1cf524c0`) 会把每个传入的
`topology_args` 与它在同一 `slice_id` 上第一次看到的内容进行比较:
```c
MessageDifferencer diff;
diff.set_message_field_comparison(EQUIVALENT);
if (!diff.Compare(req.topology_args,
*cached_topology_args_for_slice[slice_id])) {
return MakeErrorImpl<3>( // INVALID_ARGUMENT — hard reject, not a log
"Received topology that differs from previously "
"registered topology at same sliceID. ...");
}该比较是一个会返回非 OK Status 的硬性 reject (MakeErrorImpl<3> = INVALID_ARGUMENT),而不是记录日志后继续;字节级推导见 拓扑交换。
该比较起作用的地方:
- 每个 slice 的芯片数。 同一 slice 的两个 host 报告不同的
TpuDimensionsProto(rows × cols × depth)表示 tpunetd 在这些 host 上分配了不同的芯片坐标,通常说明 tpunetd 的WaitForDataLinkUp超时, daemon 随后以一个不完整的 slice 继续执行。 - Host bounds。 如果两个 host 对逐 host 芯片数的看法不一致,runtime 就无法正确调度跨 host 分区的 collective。这仍然会通过上面的同一个
tpu_topology_args比较暴露出来,rodata VA0x9b27486处的 "Received topology that differs..." 错误字符串会作为 INVALID_ARGUMENTStatus返回。 - Twist 因子 / 拓扑模式。 当
MEGASCALE_TOPOLOGY或FLAGS_megascale_force_use_dcn_topology_from_flags注入一个合成拓扑时,它必须与 tpunetd 实际编程的拓扑匹配。
为什么这里的 ICI 是静默的
Megascale rendezvous 从不传输 ICI 链路状态。 GetMultiSliceTopologyResponse.serialized_topology_info 内的 MultiSliceTopologyInfo 消息携带:
slice_info(重复的SliceInfo),其中每个SliceInfo只有slice_id和tpu_topology_args(芯片布局);这是协商得到的内容, 而不是链路状态本身。address_mappings(重复的NetworkAddressMapping),每个(slice_id, host_id)对一个条目;每个条目携带addresses(重复的HostNetworkAddress,即 DCN endpoint)。incarnation_id。
没有 ICI 链路表、没有路由表、没有链路健康位会通过 Megascale 传输。 ICI 的健康状态由 tpunetd 的 SessionMaster::CheckSessionHeartbeat (0x1ffa6180) 监控,它会检测链路故障;失败路径经过 SessionMaster::HandleFailingSession(SessionState),而 SessionState enum 的失败值是 SESSION_STATE_FAILING (见 tpunetd 关系)。此类故障会通过 tpunetd 路径向上 传播到 PJRT,不是通过 Megascale 路径。
这种架构分离意味着:
- 单条坏 ICI 链路会使 slice 失败;tpunetd 会检测到它,并将其暴露为 session 失败。
- 两个 slice 之间的坏 DCN 链路会使 multi-slice job 失败;Megascale 的 HeartBeat 会检测到它,并将其暴露为 heartbeat 失败。
两个检测系统独立运行;二者都可能触发,且互不阻塞。
TpuTopologyArgsProto 怎么看?
这个 proto 是唯一跨越 tpunetd → Megascale 边界的结构化 artefact。它定义在 platforms/deepsea/software/superpod/routing/common/proto/topology.proto (CONFIRMED — 该路径是 rodata 字符串)。二进制中的 reflection metadata 暴露了它的标量字段 variant 和 chip_config_name,以及一个嵌套的 SubSlice 消息 (tpu.TpuTopologyArgsProto.variant、 tpu.TpuTopologyArgsProto.chip_config_name、 tpu.TpuTopologyArgsProto.SubSlice 全部是 CONFIRMED rodata descriptor 字符串)。
INFERRED — 结构几何信息(每个 ICI 轴的芯片数、逐 host bounds、process bounds, 以及 twisted-torus 的 twist / wrap / alt 参数)由 tpunetd 编程的拓扑以及 TPU_PROCESS_BOUNDS、TPU_HOST_BOUNDS、 TPU_CHIPS_PER_HOST_BOUNDS、TPU_TOPOLOGY_ALT、 TPU_TOPOLOGY_WRAP env vars 填充(全部 CONFIRMED 为二进制字符串)。 这些内容驱动编译器用来正确路由 collective route 的芯片布局。
当设置 --megascale_force_use_dcn_topology_from_flags=true 时,runtime 会完全从 MEGASCALE_TOPOLOGY env-var override 构造 TpuTopologyArgsProto,绕过 tpunetd 的贡献。这是测试 / 仿真路径;生产部署会关闭它,让 tpunetd 驱动该 proto。
交接出错时
三个具体场景:
- tpunetd 的
WaitForDataLinkUp部分失败。 daemon 继续执行,并生成一个降级的TpuTopologyArgsProto,反映较小的可工作芯片集合。Megascale coordinator 会在该 slice 的所有 host 间看到一致(但错误)的拓扑。Bootstrap 成功, 但下游 compile 会因为缺失芯片无法调度而失败。 - 同一 slice 的两个 host 发生竞争并获得了不同的芯片坐标。 Megascale 的
MessageDifferencer捕获该不匹配,ProcessRequest返回Received topology that differs...MakeErrorImpl<3>(INVALID_ARGUMENT)Status。第二个 host 的GetMultiSliceTopologyRPC 会以该错误失败; 该 slice 的 rendezvous 不会收敛,因此 bootstrap 会向 runtime 返回一个非 OK Status,而不是静默地用不匹配的芯片集合继续运行。 - 某个 host 在 slice 已经进入稳定状态后重启,并以不同的
incarnation_id重新连接。TopologyCoordinator::ProcessRequest(0x1cf524c0) 返回 "Received incarnation ID that is different from previous incarnation ID..."MakeErrorImpl<3>(INVALID_ARGUMENT)Status(rodata VA0x9c14456)。另外,被 inline 的LogUniqueIdshelper (折叠进0x1cca9aa0处的Communicator::Create)会在unique_id_mutex下跟踪三个last_idsslot,并在任一 slot 的 id 变化时记录日志。tpunetd 的SessionMaster会独立通过 heartbeat 检测重启, 并可能将 session 转换到SESSION_STATE_FAILING。无论哪种情况,operator 都会看到两个信号并可进行关联。
因此,组合后的诊断面是:tpunetd 回答“此 host 上的 ICI 是否健康?”; Megascale 回答“所有 slice 的所有 host 是否就芯片布局达成一致?”; ErrorReporter / RapidEye 链(见 错误聚合器) 回答“整个 fleet 中最坏的故障组合是什么?”。
交叉引用
- tpunetd 关系 — Megascale 启动前拥有 ICI bring-up 的逐 slice daemon
- Bootstrap › 概览 — ICI→DCN 交接在生命周期中的位置
- 故障处理 — 与 tpunetd 路径并行运行的 Megascale 侧故障路径
- 错误聚合器 — 上文引用的 fleet 级根因链
- ICI › 概览 — 本页所交接来源的 slice 内光学 torus 层