tpu_telemetry.proto
本页中的所有名称、字段编号和符号均适用于
libtpu-0.0.40-cp314wheel(build-id89edbbe81c5b328a958fe628a9f2207d)中的libtpu.so。字段编号是稳定的 proto2 线格式标识符;其他版本可能会添加字段,但不会重新编号。
摘要
tpu_telemetry.proto 是 libtpu 的设备状态 schema:一个很小的 proto2 文件(package platforms_deepsea.jellyfish.xdb.tpu_telemetry,6 个 message,2 个 enum,无 import),它按 TPU core 捕获某一瞬间每个硬件 sequencer 的实时执行状态,包括 program counter、硬件 tag、tracemark、绑定的 program、待启动队列,以及可选的已解析 HLO 源位置。它由主机上的 xdb(TPU debugger)状态服务器生成,并按需通过 gRPC 拉取。它不是 xprof trace 流水线的一部分:它是某一时刻的状态快照(AllCoreStateSummaries,即 int32 global_core_id → CurrentCoreStateSummary 的 map),在结构上与 trace 侧发出的 XSpace/XPlane/XLine/XEvent/XStat 事件流相反。两者从不共享同一个线格式 blob;它们唯一的交汇点是 TpuProfilerControlListener 的 PC→HLO 元数据,profiler(用于给 XEvent 标记源位置)和 xdb server(用于填充 SequencerInfo.hlo_location)都会读取它。
整个 schema 与代际无关。唯一感知代际的表面是 TpuCoreTypeProto / TpuSequencerTypeProto enum 对,它编码了 SparseCore 的演进:较旧的 SPARSE_CORE_V0(一个 sequencer + 一个 address handler)与当前的 SPARSE_CORE(一个 scalar sequencer,加上 Tile-Access-Core 和 Tile-Execute-Core sequencer)。读者可能以为这里会有但实际上没有的所有内容,例如 HBM 字节数、die 温度、瓦特数、ICI 链路健康状态、ECC 计数、时钟频率,都位于此文件之外专门构建的配套 proto 中;本页会划清这条边界,避免重新实现者在这里寻找这些字段却只找到空洞。
本页负责逐字段 schema(每个 message、字段编号 → 名称 → 类型 → label,按 message 分组并按字段编号排序)、两个 enum 的完整定义、身份与粒度模型(per-host → per-chip → per-core → per-sequencer)、生产者/消费者 RPC 图,以及配套 proto 边界目录。xprof trace 模型由 XPlane / XStat / TraceMe 负责;周边的 xprof task/session 描述符由 Task Proto 负责。这里不重复它们。
对于重新实现,契约是:
- 六个 message 的形状及其嵌套关系 —
AllCoreStateSummaries⊃CoreStatesEntry(合成 map entry)⊃CurrentCoreStateSummary⊃{TpuCoreIdentifier, repeated SequencerInfo, repeated QueuedProgramInfo},其中TpuCoreIdentifier⊃TpuCoreOnChipProto。 - 每个字段的精确字段编号 → 名称 → 类型,因为这些是兼容生产者或消费者必须逐字节复现的线格式标识符。
- 两个 enum 的完整定义,包括区分每种 core type 的 sequencer 集合的 SparseCore-v0 与当前 SparseCore 拆分。
- 粒度和身份模型 —
global_core_id、chip_id以及片上(type, index)三元组如何定位一个 core,以及哪个 message 是每一层级的单位。
| Proto 文件 | platforms/deepsea/jellyfish/xdb/tpu_telemetry/tpu_telemetry.proto |
| Package | platforms_deepsea.jellyfish.xdb.tpu_telemetry |
| Syntax | proto2 — 除非标记为 repeated,否则每个字段都是 optional;descriptor 中没有字段级默认值 |
| Descriptor VA | protodesc pool 中的 0xc198170(1,905 字节),无 import |
| 形状 | 6 个 message,2 个 enum,0 个 service,0 个 import |
| Schema 根 | AllCoreStateSummaries (map<int32 global_core_id, CurrentCoreStateSummary>) |
| Per-core 单位 | CurrentCoreStateSummary |
| 最细粒度 | SequencerInfo(每个硬件 sequencer 一个;当前 SparseCore 最多 3 个) |
| 生产者 | xdb per-host 状态服务器 — TpuTelemetryHarvester (…tpu_telemetry::TpuTelemetryHarvester) |
| 消费者 | TpuDebugService.GetCurrentTpuStateSummary · RuntimeMetricService.GetTpuRuntimeStatus · Megascale hang-detector |
| 通道 | gRPC 拉取(请求开关 include_hlo_info)— 从不走 PJRT C-ABI |
注意 — 本页中的每个 message 名称、合成 map-entry 名称
CoreStatesEntry、所有字段名字符串和 enum 值字符串,都逐字出现在二进制的.rodata和 descriptor pool 中;每个 message 另外都有完整生成的 proto2 runtime class(SequencerInfo::_table_、CurrentCoreStateSummary::Clear、AllCoreStateSummaries::MergeImpl、arena constructors 等),因此这六个都是真实实例化的 message,而不是仅存在于 descriptor 的条目。因此 schema 的可信度全程为 CERTAIN;少数推断(生产者 wiring 细节、默认值)会在原处标明。
概览:每个 Message 的字段数
| Message | 字段 | Repeated | 嵌套于 | 作用 |
|---|---|---|---|---|
TpuCoreOnChipProto | 2 | 0 | — | 片上 core 定位器:(type, index) |
TpuCoreIdentifier | 3 | 0 | — | 全局 core 身份:(global_core_id, chip_id, core_on_chip) |
QueuedProgramInfo | 3 | 0 | — | 一个待启动队列条目 |
SequencerInfo | 9 | 0 | CurrentCoreStateSummary | 一个硬件 sequencer 的实时状态 |
CurrentCoreStateSummary | 7 | 2 | CoreStatesEntry | 一个 core 的完整执行快照 |
AllCoreStateSummaries | 1 | 1 | —(根) | 主机范围内所有 core 快照的 map |
AllCoreStateSummaries.CoreStatesEntry | 2 | 0 | AllCoreStateSummaries | 合成 proto2 map entry |
message 旁边有两个 enum:TpuCoreTypeProto(4 个值)和 TpuSequencerTypeProto(7 个值),详见两个 Enum。
易错点 —
CoreStatesEntry是 proto2map<K,V>脱糖生成的合成嵌套 message,而不是手写类型。它的key(1) 和value(2) 字段是标准 map-entry 布局。手写 schema 的重新实现者应声明map<int32, CurrentCoreStateSummary> core_states = 1;,并让编译器合成 entry;但解析线格式字节的重新实现者必须把它作为字段编号 1 的CoreStatesEntry记录的repeatedmessage 字段处理,这也正是它在二进制 descriptor 中出现的方式。
Message: TpuCoreOnChipProto
片上定位器。命名单个 chip 内 core 的种类以及该种类中的序号,例如 “TensorCore #1” 或 “SparseCore #3”。它是身份链的叶子,嵌入在 TpuCoreIdentifier 中。
| # | 名称 | 类型 | Label | 含义 |
|---|---|---|---|---|
| 1 | type | TpuCoreTypeProto (enum) | optional | Core 种类:TensorCore / SparseCore-v0 / SparseCore |
| 2 | index | int32 | optional | chip 上此 core 在该类型内的序号(从 0 开始) |
特性 —
index是按类型划分的序号,而不是扁平的 per-chip core 索引。在一个包含一个 TensorCore 和多个 SparseCore 的 chip 上,TensorCore 是(TENSOR_CORE, 0),SparseCore 是(SPARSE_CORE, 0)、(SPARSE_CORE, 1)、……。把index与 chip-global core 编号混淆,会错误寻址 multi-SC chip 上的每个 SparseCore。扁平的 host-wide 身份是单独字段TpuCoreIdentifier.global_core_id。
Message: TpuCoreIdentifier
主机上某个 core 的全局唯一身份:一个扁平 id,加上 chip 和片上定位器。该 message 也会在快照路径之外复用 — TpuDebugService.GetMachineInfo 返回 repeated TpuCoreIdentifier 作为主机的 core inventory,因此此类型也兼作主机拓扑描述符。
| # | 名称 | 类型 | Label | 含义 |
|---|---|---|---|---|
| 1 | global_core_id | int32 | optional | 主机所有 core 范围内的扁平 id;AllCoreStateSummaries 的 map key |
| 2 | chip_id | int32 | optional | 此 core 属于主机上的哪个 chip |
| 3 | core_on_chip | TpuCoreOnChipProto (message) | optional | 该 chip 内的 (type, index) 定位器 |
二进制中带有一个生产者侧 helper …tpu_telemetry::GetUniversalCoreId(tpu::TpuCoreLocation)(mangled …13tpu_telemetry18GetUniversalCoreIdERKN3tpu15TpuCoreLocationE),它从 runtime 的 TpuCoreLocation 派生 global_core_id,也就是说扁平 id 是从硬件位置计算出来的,而不是独立存储的(HIGH confidence — 符号存在;未追踪派生算术)。
Message: QueuedProgramInfo
core 待启动队列中的一个条目:已经提交但尚未成为绑定/执行中 program 的 program。CurrentCoreStateSummary 携带 repeated QueuedProgramInfo,用于在快照瞬间暴露队列深度和内容,也就是 hang-detector 用来判断“此 core 有 work 排队但没有前进”的信号。
| # | 名称 | 类型 | Label | 含义 |
|---|---|---|---|---|
| 1 | run_id | int64 | optional | 排队 program 的 runtime run id |
| 2 | launch_id | int64 | optional | 每次 execute 的 launch id |
| 3 | program_fingerprint | bytes | optional | 排队 program 的 executable fingerprint |
注意 — 这里的
run_id/launch_id与SequencerInfo.run_id(正在执行的 run)和CurrentCoreStateSummary.launch_id(当前执行中的 launch)使用同一个标识符空间。将队列的(run_id, launch_id)与执行中的 pair 做 diff,可以告诉消费者 core 的 sequencer 比队列落后多少。这些 id 也是与 xprof trace 侧唯一的语义重叠,后者会在其主机TraceMe事件中引用同样的run_id/launch_id。
Message: SequencerInfo
最细粒度的 message,也是 schema 的核心:一个硬件 sequencer 的实时寄存器快照。TensorCore 报告一个 SequencerInfo;SparseCore-v0 报告两个(sequencer + address handler);当前 SparseCore 最多报告三个(scalar sequencer + Tile-Access-Core + Tile-Execute-Core)— 见两个 Enum。PC/tag/tracemark 三元组是 hang-detector 跨两个快照比较的对象:如果 PC 没有前进且 tag 没有变化,则 sequencer 停滞。
| # | 名称 | 类型 | Label | 含义 |
|---|---|---|---|---|
| 1 | sequencer_type | TpuSequencerTypeProto (enum) | optional | 此记录描述哪个 sequencer(见 enum) |
| 2 | sequencer_index | int32 | optional | core 上该类型 sequencer 内的序号 |
| 3 | pc | int64 | optional | 当前 program counter |
| 4 | tag | int64 | optional | 硬件 tag register — sync / epoch 标记 |
| 5 | tracemark | int64 | optional | 当前 tracemark — 编译器发出的进度标记 |
| 6 | program_id | int64 | optional | 当前绑定 program 的 id |
| 7 | run_id | int64 | optional | sequencer 正在执行的 run id |
| 8 | hlo_location | string | optional | 在 PC 处解析得到的源 HLO 位置(仅按请求填充) |
| 9 | hlo_detailed_info | string | optional | 扩展 HLO 上下文字符串(仅按请求填充) |
易错点 — 字段 8 和 9(
hlo_location、hlo_detailed_info)为空,除非 gRPC request 设置了include_hlo_info = true。将 PC 解析到 HLO 位置需要由TpuProfilerControlListener注册的 compiler-side 元数据(profiler 用来给XEvent标记源位置的同一份 PC→HLO map)。总是填充它们的重新实现会在每次轮询中支付 PC→HLO 解析延迟;从不填充则会失去从停滞 PC 回到源代码的唯一人类可读链接。这个开关属于请求时,而不是 schema 时 —tpu_telemetry.proto内部没有对应字段。特性 —
tracemark(字段 5)不同于tag(字段 4)。tag是 sequencer 管理的硬件 sync/epoch register;tracemark是编译器发出的、烘焙在 program 中的进度标记。两个快照中tag相同但tracemark前进,意味着 program 在一个 epoch 内继续推进;跨快照tracemark相同才是停滞信号。二进制中大量引用tracemark字符串(它也是一个 trace-point 概念),因此不要假设它只属于 telemetry。
Message: CurrentCoreStateSummary
一个可寻址 core 的完整执行快照,也就是 AllCoreStateSummaries 中的 map value,以及每个消费者 RPC 原样返回的线格式类型。它打包 core 身份、per-sequencer 状态、绑定 program、启动队列和一个自由文本错误字符串。
| # | 名称 | 类型 | Label | 含义 |
|---|---|---|---|---|
| 1 | core_id | TpuCoreIdentifier (message) | optional | 此快照对应谁 |
| 2 | sequencer_info | SequencerInfo (message) | repeated | core 上每个硬件 sequencer 一个条目 |
| 3 | xdb_server_running | bool | optional | 此 core 的 xdb 状态服务器是否存活 |
| 4 | program_fingerprint | bytes | optional | 当前绑定 program 的 fingerprint |
| 5 | launch_id | int32 | optional | 当前执行中的 launch id |
| 6 | queued_program_info | QueuedProgramInfo (message) | repeated | 待启动队列内容 |
| 7 | error_message | string | optional | per-core 错误 / 故障描述(如有) |
注意 — 这里的
launch_id是int32,而QueuedProgramInfo.launch_id(以及run_id)是int64。这种收窄来自 descriptor,不是转写错误:执行中的 launch id 是 32 位字段,排队的 id 是 64 位。将排队的launch_id复制到执行中槽位的重新实现者必须做范围检查。两个 message 中的program_fingerprint都是bytes(不透明 executable hash,不是字符串)。易错点 —
error_message(字段 7)是自由文本,不是 enum。schema 不包含 status-code、link-state 或 error-type enum。读者可能期待的类型化错误分类(ECC、thermal、PCIe、ICI-fatal 等)位于配套的error_report.proto中,已在配套 Proto 边界编目。不要尝试把error_message解析为编码字段。
Message: AllCoreStateSummaries
schema 根:主机范围内每个可寻址 core 的快照 map,以 global_core_id 为 key。此文件中没有 multi-host 聚合 — 单个 AllCoreStateSummaries 是一台主机的视图;跨主机拼接是 Megascale 的职责(见生产者和消费者)。
| # | 名称 | 类型 | Label | 含义 |
|---|---|---|---|---|
| 1 | core_states | CoreStatesEntry (message) | repeated | 主机上的每个可寻址 core(proto2 map 编码) |
合成 map entry:AllCoreStateSummaries.CoreStatesEntry
| # | 名称 | 类型 | Label | 含义 |
|---|---|---|---|---|
| 1 | key | int32 | optional | == TpuCoreIdentifier.global_core_id |
| 2 | value | CurrentCoreStateSummary (message) | optional | per-core 快照 |
这是标准 proto2 map<int32, CurrentCoreStateSummary> 脱糖;map 声明是字段 1 的 core_states,合成 entry 携带常规的 key=1、value=2 布局。两个消费者 RPC 会把同一个 CurrentCoreStateSummary value 类型包在各自的顶层 response 中(每个都添加一个 host_name 字符串),而不是返回裸的 AllCoreStateSummaries — 见下文。
两个 Enum
文件中唯一感知代际的表面。TpuCoreTypeProto 命名快照描述的 core 种类;TpuSequencerTypeProto 命名 SequencerInfo 描述的 sequencer 种类。它们共同编码 SparseCore 的演进:较旧的 v0 设计暴露一个 sequencer 和一个独立 address handler;当前 SparseCore 将工作拆分到一个 scalar sequencer 和两个 tile engine。
TpuCoreTypeProto(4 个值)
| 值 | 名称 | 含义 |
|---|---|---|
| 0 | TPU_CORE_TYPE_INVALID | 未设置 / sentinel |
| 1 | TPU_CORE_TYPE_TENSOR_CORE | TensorCore(在此粒度上跨代一致) |
| 2 | TPU_CORE_TYPE_SPARSE_CORE_V0 | 较旧的 SparseCore(sequencer + address handler) |
| 3 | TPU_CORE_TYPE_SPARSE_CORE | 当前 SparseCore(scalar sequencer + TAC + TEC) |
TpuSequencerTypeProto(7 个值)
| 值 | 名称 | 属于 core type | 含义 |
|---|---|---|---|
| 0 | TPU_SEQUENCER_TYPE_INVALID | — | 未设置 / sentinel |
| 1 | TPU_SEQUENCER_TYPE_TENSOR_CORE_SEQUENCER | TensorCore | 单个 TensorCore sequencer |
| 2 | TPU_SEQUENCER_TYPE_SPARSE_CORE_V0_SEQUENCER | SparseCore-v0 | v0 main sequencer |
| 3 | TPU_SEQUENCER_TYPE_SPARSE_CORE_V0_ADDRESS_HANDLER | SparseCore-v0 | v0 address handler |
| 4 | TPU_SEQUENCER_TYPE_SPARSE_CORE_SEQUENCER | SparseCore(当前) | Scalar sequencer |
| 5 | TPU_SEQUENCER_TYPE_SPARSE_CORE_TILE_ACCESS_CORE_SEQUENCER | SparseCore(当前) | Tile-Access-Core (TAC) sequencer |
| 6 | TPU_SEQUENCER_TYPE_SPARSE_CORE_TILE_EXECUTE_CORE_SEQUENCER | SparseCore(当前) | Tile-Execute-Core (TEC) sequencer |
特性 — 每个 core 的 sequencer 数量由 enum 隐含,而不是存储。TensorCore 产生一个
SequencerInfo(type 1);SparseCore-v0 产生两个(types 2, 3);当前 SparseCore 最多产生三个(types 4, 5, 6)。硬编码“每个 core 一个 sequencer”的消费者会静默丢弃当前 SparseCore 上的 TAC/TEC 状态。应从repeated sequencer_info列表长度驱动 sequencer 枚举,绝不要从假定的 core 布局驱动。注意 — 二进制中带有生产者侧 mapper
…tpu_telemetry::ToLocalProto(tpu::TpuSequencerType)(mangled…12ToLocalProtoEN3tpu16TpuSequencerTypeE),用于把 runtime 内部的tpu::TpuSequencerType转换为此处的TpuSequencerTypeProto。对称的 core-type mapper(tpu::TpuCoreType → TpuCoreTypeProto)是预期存在的,但符号表中未单独确认它的独立ToLocalProtooverload(对其存在性的置信度为 LOW;runtime 可能内联 core-type 映射)。这个 mapper 存在的确切原因是两个 enum 差一位:此 proto 编号为{SCS=4, TAC=5, TEC=6}(跟在 2/3 的SPARSE_CORE_V0_*pair 之后),而 trace 侧使用的 runtimetpu::TpuSequencerType编号为{SCS=3, TAC=4, TEC=5}(字节级确认:TpuCoreDebugInterfaceVxcDriverImpl::GetSequencerType@0x1d1195e0对kSparseCore返回3)。两者不共享编号 — 重新实现必须运行ToLocalProto,不能把 runtime 值复制进 proto 字段。见 Payload: SparseCore Band。
身份与粒度模型
schema 在四层嵌套粒度上寻址状态。重新实现者必须保持这些概念分离,因为同一个概念上的 “core” 有两种命名方式(扁平 global_core_id 和结构化 (chip_id, type, index)),且快照 map 以扁平值为 key。
host AllCoreStateSummaries (one per host; root)
└─ core (global_core_id) → CurrentCoreStateSummary (map value; the per-core unit)
├─ TpuCoreIdentifier (global_core_id, chip_id,
│ core_on_chip:(type,index)) (who this snapshot is for)
├─ sequencer_info[] → SequencerInfo (finest grain: PC/tag/tracemark
│ per HARDWARE sequencer)
└─ queued_program_info[] → QueuedProgramInfo (pending launch queue)| 粒度 | Message | Key / selector | 基数 |
|---|---|---|---|
| Per-host | AllCoreStateSummaries | —(每台主机一个) | 1 |
| Per-chip | (隐式) | TpuCoreIdentifier.chip_id | N chips |
| Per-core | CurrentCoreStateSummary | TpuCoreIdentifier.global_core_id(map key) | N×M cores |
| Per-sequencer | SequencerInfo | (sequencer_type, sequencer_index) | 每个 core 1–3 个 |
没有 chip message — per-chip 粒度完全隐含在 chip_id 中。一台包含 N 个 chip × 每 chip M 个 core 的主机会产生 N×M 个 core_states 条目;按 chip_id 分组即可重建 per-chip 视图。此文件中不存在跨主机聚合;它由 Megascale 执行,Megascale 会把 per-host 快照收集成 slice-wide 图景(下一节)。
生产者和消费者
一个生产者、三个消费者,全都共享单一的 CurrentCoreStateSummary 线格式类型。schema 不携带任何 sampling-interval、timestamp 或 cadence 字段 — 它严格按需拉取;cadence 完全由调用方设置。
生产者 — xdb 状态服务器
per-host xdb(TPU debugger)状态服务器按需采样每个 core 的 sequencer register(PC、tag、tracemark、绑定 program、启动队列),并将其打包进 CurrentCoreStateSummary。二进制中将生产者对象命名为 …tpu_telemetry::TpuTelemetryHarvester(mangled …13tpu_telemetry21TpuTelemetryHarvester),由 …tpu_debugger::TpuDebugServiceImpl 持有(constructor 接收一个 unique_ptr<TpuTelemetryHarvester>)。harvester 通过 internal-type→proto mapper ToLocalProto(tpu::TpuSequencerType) 和 GetUniversalCoreId(tpu::TpuCoreLocation),从实时 register 填充 SequencerInfo;xdb_server_running 反映该 server 是否在每个 core 上运行。
注意 — 这里未反编译 harvester 内部的 register-read 主体(对确切读取序列的置信度为 MEDIUM;
TpuTelemetryHarvester是生产者并由TpuDebugServiceImpl实例化和持有这一点为 CERTAIN)。
消费者
CurrentCoreStateSummary (one wire type, three callers)
├─ TpuDebugService.GetCurrentTpuStateSummary (xdb debugger; imports tpu_telemetry.proto)
│ Request : GetCurrentTpuStateSummaryRequest { bool include_hlo_info = 1; }
│ Response: GetCurrentTpuStateSummaryResponse { string host_name = 1;
│ map<int32, CurrentCoreStateSummary> core_states = 2; }
│ (also: GetMachineInfo → repeated TpuCoreIdentifier, the host core inventory)
├─ RuntimeMetricService.GetTpuRuntimeStatus (PUBLIC Cloud TPU monitoring gRPC)
│ Request : GetTpuRuntimeStatusRequest { bool include_hlo_info = 1; }
│ Response: GetTpuRuntimeStatusResponse { string host_name = 1;
│ map<int32, CurrentCoreStateSummary> core_states = 2; }
└─ Megascale hang-detector (cross-host stitching)
MegaScaleRuntimeError ⊃ RuntimeStateSummary ⊃ RapidEyeInfo
RapidEye's on-device TpuCoreHLO {chip_id, core_idx, hlo, pc, tag, …} mirrors CurrentCoreStateSummary| 消费者 | 表面 | 作用 |
|---|---|---|
TpuDebugService.GetCurrentTpuStateSummary | xdb debugger gRPC(live + post-mortem) | 返回主机的 per-core 状态;GetMachineInfo 返回 core inventory |
RuntimeMetricService.GetTpuRuntimeStatus | Public Cloud TPU monitoring gRPC | 供给 Google Cloud Monitoring;同一 service 还携带通用 TPUMetric streamz envelope(MetricType ∈ {UNKNOWN, LIBTPU}) |
| Megascale hang-detector | MegaScaleTransport.ReportError | 将 per-host 状态嵌入 slice-wide RapidEyeInfo hang 报告;RapidEyeInfo 添加 tpu_version/chip_config_name(代际身份) |
注意 — 本地 profiler(PJRT Profiler extension →
XSpace)不是tpu_telemetry的消费者。PLUGIN_Profiler_CollectData只服务序列化的XSpace字节,并明确不发出TpuCoreStateSummary/AllCoreStateSummaries;反过来,两个 state-summary RPC 从不发出XSpace。这条边界在线格式层面强制执行,而不是约定。见 TpuProfiler ABI 和 overview。
Cadence 和时间相关
tpu_telemetry 按设计不带 timestamp — 它是纯快照。唯一的请求时开关是 include_hlo_info(每个 request 上的 bool,用 PC→HLO 解析延迟换取更丰富输出)。需要时间相关时,时间来自外层 envelope:RuntimeMetricService 的通用 Metric 携带 google.protobuf.Timestamp;Megascale/RapidEye 路径携带 timestamp_ns 和 incarnation_id。需要“这个快照是什么时候采集的”的重新实现者必须在调用点打时间戳 — schema 不会提供。
tpu_telemetry 与 xprof(正交对比)
这两种 profiling 格式回答相反的问题,并且从不共享一个 blob。本页负责 telemetry 侧;xprof 侧由 XPlane / XStat / TraceMe 负责,并由 overview 映射。
| 维度 | tpu_telemetry.proto(本页) | xprof XSpace (xplane-xstat-traceme) |
|---|---|---|
| 问题 | “每个 core 此刻在做什么?” | “这个区间内发生了什么?” |
| 形状 | 状态快照 — map<core → state> | 时间序列树 — Space ⊃ Plane ⊃ Line ⊃ Event ⊃ Stat |
| 根 | AllCoreStateSummaries | XSpace |
| 时间模型 | 某一时刻;没有内置 timestamp | session 内的 span(offset_ps + duration_ps) |
| 生产者 | xdb per-host 状态服务器(TpuTelemetryHarvester) | tsl::profiler::ProfilerCollection(host + chip tracer) |
| 通道 | gRPC 拉取(TpuDebugService / RuntimeMetricService) | PJRT Profiler C-ABI(+ legacy TpuProfiler_*) |
| 消费者 | xdb debugger、Cloud TPU monitoring、Megascale hang-detect | xprof / TensorBoard、JAX / PT-XLA / TF |
| 语义重叠 | run_id / launch_id、已解析 HLO 位置 | 主机 TraceMe 事件上的相同 run_id / launch_id |
| 实现重叠 | TpuProfilerControlListener PC→HLO 元数据 | 同一 listener 给 XEvent 标记源位置 |
特性 — 两种格式之间唯一的实现耦合是
TpuProfilerControlListener的 PC→HLO 元数据:profiler 读取它来给XEvent标记源位置,xdb harvester 读取它来填充SequencerInfo.hlo_location。重新实现者可以完全不带 profiler 地构建 telemetry 路径 — 除了 HLO-location 解析,这需要共享的 compiler-metadata registry。没有它时,hlo_location/hlo_detailed_info只会保持为空;快照的其余部分不受影响。
配套 Proto 边界
最大的重新实现风险是期待这里并不存在的字段。tpu_telemetry.proto 只携带 core 执行状态 — PC、tag、tracemark、program、queue、HLO location。读者可能期待的每个硬件环境指标都位于单独的专用 proto 中。此目录划清边界,让重新实现者将每个类别路由到正确文件。
| 读者期待的类别 | 实际所在位置 | 字段 / enum |
|---|---|---|
| Core 执行状态(PC/tag/tracemark/program/queue) | tpu_telemetry.proto — CurrentCoreStateSummary, SequencerInfo | pc, tag, tracemark, program_id, run_id, queued_program_info |
| Utilization(TensorCore / HBM / ICI / SparseCore) | utilization_metrics.proto / UtilizationMetricData.UtilizationMetric | metric_type ∈ UtilizationMetricType, utilization, usage, duty_cycle (float) |
| HBM usage | utilization_metrics.proto | UtilizationMetricType.HBM_UTILIZATION (=2) + usage float |
| Temperature(proxy) | utilization_metrics.proto / ChipThrottlingMetric | tray_id, chip_id, throttling_score (int64) |
| ICI link state / health | utilization_metrics.proto / IciLinkMetric | port_id (string), link_health (int64) |
| ICI link topology | ici_link_map.proto / IciLinkMapEntry, IciLinkMap | local_chip, ici_connector ∈ IciConnector(ICI0..ICI15), orientation, polarity, remote_chip |
| Power | power_metrics.proto (xprof) / PowerMetrics, PowerComponentMetrics | component_name, max_power, avg_power, max_moving_avg_power_{100us,1ms,10ms,1s} |
| ECC / thermal / power / PCIe / ICI-fatal errors | error_report.proto / Error | 12 个类型化 sub-message:ecc_correctable, ecc_uncorrectable, thermal, power, pcie, ici_link_fatal, firmware, network, system_{software,hardware}, user, internal |
| Error / anomaly aggregation | anomalies.proto / Anomaly, EccErrorAnomaly, Anomalies | ECC + 通用 error anomaly carrier |
| Generic numeric runtime metric envelope | tpu_metric_service.proto / TPUMetric, Metric | gauge / counter / distribution / summary + Attribute;MetricType ∈ {UNKNOWN, LIBTPU} |
| Per-chip throttling rollup | utilization_metrics.proto / TpuHealthMetrics | chip_throttling_metric + repeated ici_link_metrics |
| Per-event device trace(完全不是 telemetry) | xplane.proto + per-family trace_entries.proto | XEvent + TracePointId enums |
二进制中确认的配套 proto 字符串锚点:HBM_UTILIZATION、TENSORCORE_UTILIZATION、SPARSECORE_UTILIZATION、throttling_score、TpuHealthMetrics、ChipThrottlingMetric、IciLinkMetric、PowerComponentMetrics。配套 proto 的内部细节不属于本页范围 — 这里只负责路由边界。
配套栈的 enum 要点(用于定位,不提供字段级深度):
UtilizationMetricType(5):UNSPECIFIED_UTILIZATION=0,TENSORCORE_UTILIZATION=1,HBM_UTILIZATION=2,ICI_UTILIZATION=3,SPARSECORE_UTILIZATION=4.IciConnector(16):ICI0..ICI15— 当前 chip 最多暴露 16 个 ICI port。MetricType(2):UNKNOWN=0,LIBTPU=1(tpu_metric_service.proto)。
易错点 — 不同于
tpu_telemetry,硬件利用率流(UtilizationMetricData)确实携带自己的google.protobuf.Timestamp,并设计为周期性 push,而不是 pull。构建统一 monitoring agent 的重新实现者不能假设两者有同一种 cadence 模型:core-state 是按需拉取且无 timestamp;utilization 是带 timestamp 的 push。
按代际的行为
schema 在字段层面与代际无关;只有 enum 表面感知代际,而且即便如此也是加法式的(跨代不重新编号字段)。
tpu_telemetry.proto本身: 与代际无关。唯一对代际敏感的表面是 core/sequencer type enum,它已经覆盖 TensorCore + SparseCore-v0 + 当前 SparseCore。在此粒度上 TensorCore 跨代一致(总是一个 sequencer,type 1)。- 每个 core 的 sequencer 数量是代际线索: TensorCore → 1 个
SequencerInfo;SparseCore-v0 → 2 个(sequencer + address handler);当前 SparseCore → 3 个(scalar + TAC + TEC)。区分快照中 SparseCore 代际的是SequencerInfo条目数量,而不是任何版本字段。 - 代际身份记录在此文件之外: Megascale
RapidEyeInfo携带tpu_version(int32)和chip_config_name(string)。独立的tpu_telemetry快照不会命名其 TPU 代际 — 消费者必须从周边上下文学习代际(通过GetMachineInfo获取的 host inventory,或 Megascale envelope)。
未追踪的内容
给需要决定重新推导哪些内容的重新实现者的坦诚缺口:
- Harvester register-read 主体。
TpuTelemetryHarvester已确认是生产者(符号存在,由TpuDebugServiceImpl持有),但未追踪反编译主体如何从硬件 sequencer register 读取 PC/tag/tracemark 并写入SequencerInfo(对读取序列的置信度为 MEDIUM)。 - Core-type
ToLocalProto。 已确认ToLocalProto(tpu::TpuSequencerType)mapper;未在符号表中单独找到对称的 core-type mapper(LOW confidence — 可能已内联)。 - 字段默认值。 proto2 支持字段级默认值;此文件的 descriptor 没有携带任何默认值。尚未从反编译 writer 中确认 harvester 是否无条件设置任何字段(例如 server down 时的
xdb_server_running = false)(LOW confidence)。 GetMachineInfo与GetCurrentTpuStateSummary的快照共享。 尚未确定两个 RPC 是否共享一次 register-sampling pass,还是各自采集独立快照(core inventory 与 per-core state 之间可能存在一致性窗口)。RuntimeMetricServicenumeric-metric name 目录。 未枚举 libtpu 在MetricType.LIBTPU下发布的TPUMetric.name值集合(与快照并行承载的 streamz metrics)。
交叉引用
- Profiling and Telemetry overview — 本页所在的双格式拆分;xprof 流水线和
TpuProfilerControlListener边界 - XPlane / XStat / TraceMe — 与此 schema 对照的正交 xprof 事件 trace 模型(
XSpace⊃XPlane⊃XLine⊃XEvent⊃XStat) - Task Proto — 周边 xprof task/session 描述符
- TpuProfiler ABI — legacy
TpuProfiler_*C-ABI;确认CollectData只服务XSpace,从不服务AllCoreStateSummaries - Payload: SparseCore Band — trace 侧 SparseCore sequencer 编号(runtime
tpu::TpuSequencerType{SCS=3, TAC=4, TEC=5}),比此 proto 的{SCS=4, TAC=5, TEC=6}小一,并由ToLocalProto桥接 - v7x Perf-Counters — v7x performance-counter trace lines,是 trace 侧一个与 utilization 相邻但独立的表面