跳到主要内容

29 可观测性与遥测洞察

  • 章节编号:29
  • 所属层:X 横向(贯穿 09 Driver、12 Runtime、23 Fleet、18 autotune 回写)
  • 关联 ADR:ADR-111(端侧 Profiler 与 HAL trace)、ADR-112(Fleet 遥测 schema)、ADR-113(问题归因:编译/运行时/驱动)、ADR-114(隐私分级与采样)
  • 上游依赖:09(profiler ioctl)、18(telemetry→spec)、23(Fleet)、24(上传边界)、30(Agent 归因)

学习目标

  • 前置知识:读过 12/13 章(运行时与实时调度)与 21 章(具身模型部署形态);知道 π0 类「VLM prefill + 流匹配去噪 chunk」的流水结构、什么是 chunk 延迟;对「分位数(p50/p99)」「trace / span」「时间序列指标(gauge / histogram)」有基本概念。无需机器人操作系统背景——本章从「怎么把一次推理的延迟拆开、上报、归因」而非「怎么写控制器」切入。
  • 学完产出:① 能说清一套具身遥测栈的三层结构——端侧 Profiler(单次推理 trace)端侧指标聚合(chunk_ms / Hz / thermal / power)Fleet 云端聚合(跨机队 SLO 看板)——各自采什么、上报什么、谁消费;② 能把「为什么监控 chunk 延迟的 p99 而非均值」用尾延迟算一遍,理解一个 chunk 卡顿如何击穿实时控制;③ 能解释 tracing(OpenTelemetry / IREE VM trace / ros2_tracing)如何把一次跨节点(感知→VLM→动作头→执行)的延迟拆到具体 span、定位瓶颈在哪一跳;④ 能读懂 §3.2 的归因树,把一次「chunk p99 回归」翻译成「bundle / thermal / driver / runtime / sim2real」五条可执行的排查路径;⑤ 能对照 §3.3 隐私分级(L0–L3)与现场遥测回传设计,说清「失败样本如何回传而不泄露原始视频」的取舍。
  • 阅读姿势:盯住一条主线——「可观测性的价值,全部由『能不能把一个数字拆回到某一层某一跳』决定」。一个笼统的「今天平均延迟 80ms」毫无归因价值;有价值的是「p99 从 90ms 涨到 140ms,trace 显示 DiT 去噪第 3 步的 dispatch 变慢,且发生在 thermal throttle 触发之后」。读表格时不要只看采了哪些字段,要问「这个字段能把问题定位到哪一层」。

1. 范围与目标

定义 Profiler/Debugger、端侧指标、Fleet 遥测、性能回归归因。支撑 27 benchmark CI 与 31 field 闭环。

核心问题

  1. 对标 Nsight Systems、IREE trace、Chrome trace、DCGM Fleet?
  2. 具身须采哪些 SLO 指标(chunk_ms/Hz/thermal/power)?
  3. 如何 归因:compiler vs runtime vs driver?
  4. 隐私(摄像头)与 28/24 如何一致?

2. 需求洞察

角色需要
算子工程师per-op timeline;roofline
RuntimeVM/module fence;RTC 状态
AE/客户Fleet dashboard:Hz/p99/OTA 版本
安全无默认 raw video

2.1 三层遥测栈的职责边界

可观测性不是「多采一点数据」,而是三个数据密度、时效、消费者都不同的层次。把它们混为一谈,是端侧遥测最常见的设计错误——高频 trace 采太多会拖慢推理本身,低频聚合又丢掉了归因所需的细节。

  • 端侧 Profiler(高密度):采单次推理的 per-op / per-dispatch timeline,粒度到「DiT 去噪第 3 步 dispatch 12ms」。开销高(trace 本身会拖慢推理),默认关闭,仅在 debug / CI / 现场排障时按需开启。
  • 端侧指标聚合(中密度):常驻运行,把每次推理的关键数值(chunk_ms、effective_hz、power、thermal)聚合成 histogram / 滑窗统计后周期上报。这是常态化 SLO 监控的主力,开销必须低到不影响实时控制。
  • Fleet 聚合(低密度):云端跨机队汇总,回答「整个机队的 p99 是否达标、哪个 OTA 版本引入了回归」。数据密度最低,但归因维度(bundle_version / spec_hash)最全。

3. 技术现状与趋势(2025–2026)

3.1 TOP 级可观测性方案深度对比

端侧 ProfilerFleet/云机器人优势劣势
NVIDIA Nsight SystemsCUDA+CPU system traceNsight Cloud K8s(以官方命名为准)Jetson/Thor成熟;JetPack 集成GPU 中心;闭源
NVIDIA Nsight Computekernel 级GPU kernel深度非 VLA E2E
IREE runtime traceVM/HAL timeline我们主线与编译同源DSA 待扩展
Chrome/Perfetto trace通用Android 常用开放格式无 NPU 语义
DCGM / Fleet IntelligenceGPU 健康数据中心 Fleet少端侧规模运维非具身 SLO
AWS CloudWatch IoTagent托管通用 IoT托管无 chunk_ms 语义
ROS2 ros2_tracingDDS timelineROS 通用开源不含 NPU
Weave/W&B(ML)训练实验训练为主实验管理非端侧 RT
我们 dsa-telemetryHAL+VM+power23 Fleet APImanifest 绑定VLA 原生指标待建

3.1a 方案深度对比

Nsight + Nsight Cloud(2025–2026)

产品名以 NVIDIA 官方命名为准;下表能力描述为公开资料整理。

优势劣势我们借鉴
K8s Operator 无侵入注入;Streamer 浏览器 UICUDA 专用Fleet 远程 trace 拉取
Thor JetPack 文档齐全难映射 IREE VM导出 Perfetto 兼容

IREE trace

优势劣势我们借鉴
compile+run 同源;dispatch region 可见默认 CPU/GPU 后端DSA HAL trace 扩展

我们的 VLA 原生 telemetry

字段用途
chunk_ms_p50/p9927 SLO
effective_hzRTC
power_w/thermal_c11
bundle_version/spec_hashOTA 归因
npu_throttle11/09

ROS2 ros2_tracing + dsa 扩展(ADR-111)

维度ros2_tracingdsa-telemetry 扩展
覆盖DDS pub/sub;executor+ IREE VM/HAL;chunk 边界
格式LTTng → Perfetto统一 Perfetto 导出
Fleet本地29→23 聚合 chunk_ms_p99
隐私可关默认 L0 无图像

OpenTelemetry 映射(ADR-112)

OTel 概念dsa 字段示例
trace.spaniree.dispatchDiT step 12ms
metric.gaugeeffective_hzRTC 瞬时频率
metric.histogramchunk_ms 分桶27 SLO(p99 从分桶算)
resource.attrbundle_versionsemver
log.recordthermal_throttle11 联动

指标类型选型要点:分位数(p99)必须走 histogram 而非 gauge。gauge 只存「当前瞬时值」,跨机队 / 跨时窗聚合时无法还原分位数——把 100 台机器的 p99 gauge 再求平均,得到的不是机队 p99,而是一个没有统计意义的数。正确做法是端侧上报 chunk_ms 的 histogram 分桶(bucket 计数),云端合并各机分桶后再从合并直方图里算真实分位数。effective_hz 这类「当前值即语义」的量才适合 gauge。

3.1b OpenTelemetry span 树:一次跨节点推理的拆解

具身推理是一条跨节点、跨设备的流水:相机采图 → 前处理 → VLM prefill(NPU)→ 动作头多步去噪(NPU / DiT)→ 动作输出 → ROS2 发布 → 执行器。任一跳变慢都会推高 chunk 延迟,而单看一个总延迟数字无法知道慢在哪。OpenTelemetry 的 trace / span 模型正是为此设计:每一跳是一个 span,span 之间的父子 / 因果关系还原出完整调用链。

怎么用这棵树定位跨节点延迟:root span(chunk_e2e)记录总延迟 140ms,子 span 把它拆成感知 / 前处理 / prefill / 去噪 / 发布五段。一眼看出瓶颈在 action_denoise(74ms,异常);再下钻到步级 span,发现是 denoise_step_3 单步膨胀到 38ms(其余步只有 12ms);该 span 上挂了一条 thermal_throttlelog.record——归因链闭合:热节流在第 3 步触发,NPU 降频,拖慢了这一步的 dispatch。没有 span 树,你只能看到「总延迟 140ms」这个孤立的数字,根本不知道该去查感知、查模型、还是查散热。

跨节点的关键在 trace context 传播:感知节点、推理节点、ROS2 执行节点可能是不同进程甚至不同设备。OpenTelemetry 用 trace_id + span_id 在节点间透传上下文(ros2_tracing 侧走 DDS 消息头,NPU 侧走 IREE VM trace),使一次物理推理的所有 span 挂在同一个 trace_id 下——这是把「跨节点延迟」拼成一条完整链路的前提。

3.2 归因树(ADR-113)

chunk p99 回归
├─ bundle/spec 差异? → 18 diff
├─ thermal throttle? → 11
├─ driver regression? → 09 CI
├─ runtime scheduling? → 14 VM 争用
└─ sim2real? → 31 field

3.3 隐私(ADR-114)

级别内容默认
L0聚合 ms/Hz/W
L1失败 episode metadata✅ opt-in
L2缩略图/关键帧客户 opt-in
L3原始视频禁止默认

3.3a 现场失败样本回传:隐私分级下的取舍

现场遥测最有价值的不是「一切正常」的数据,而是失败样本——机器人抓空、动作卡顿、rollout 中断的那几帧。这些样本直接喂给 31 章 field 闭环与 18 章 autotune 回写。但摄像头原始视频是隐私红线,直接回传既违规又占带宽。工程解法是分级回传:优先回传能定位问题的最小信息,逐级 opt-in 才升级到图像

回传优先级的核心逻辑:多数现场失败(延迟抖动、热节流、调度争用)靠 L0 聚合遥测 + 失败时刻的 span 树就能定位,根本不需要图像——这正是 §3.1b span 树的价值延伸到现场。只有当问题疑似「感知看错了 / 语义理解失败」时,才逐级 opt-in 到 L1(动作 / 状态元数据,仍无像素)乃至 L2(脱敏缩略图)。L3 原始视频默认禁止,需 28 章合规单独审批。带宽与隐私双约束下,「回传能定位问题的最小信息」是第一原则,而非「把现场画面都拉回来慢慢看」。


6. 结论与 ADR

  1. 端侧:IREE trace + HAL counters + power;导出 Perfetto。
  2. Fleet:chunk_ms/Hz/W + version;对接 23。
  3. 18 autotune 回写:硅后 telemetry 触发 L2(30)。
  • ADR-111 端侧 Profiler:IREE trace flags;HAL trace ioctl;与 Demo 集成。
  • ADR-112 Fleet schema:OpenTelemetry 式;manifest/bundle 字段 mandatory;p99 走 histogram 分桶,非 gauge
  • ADR-113 归因:分层归因树;CI 自动 bisect spec。
  • ADR-114 隐私:L0–L3;默认 L0;28 合规;失败样本分级回传,优先无图像

深入思考

每题先给题干,再折叠一份图文并茂的参考答案。建议先合上答案自己想 3 分钟,再展开对照。

思考题 1:为何监控 chunk 延迟的 p99 而非均值

具身控制里,遥测栈上报 chunk_ms 时既可以报均值(mean),也可以报 p99。业界(含我们 §3.1c 的 dsa-telemetry)坚持采 p99 且用 histogram 存储。结合 §2.1 三层栈与 21 章「chunk 延迟必须小于执行时长」的实时性口径,把尾延迟算一遍,论证为什么均值会「骗过」你,以及为什么 p99 必须走 histogram 而非 gauge。

展开参考答案(含尾延迟击穿实时性图 + 算一遍)

结论:实时控制的成败由最慢的那几次推理决定,而不是平均水平;均值会把偶发的致命卡顿稀释到看不见,p99 才暴露「有百分之一的 chunk 赶不上执行、机器人会断供停顿」。而 p99 只能从延迟分布(histogram)里算,gauge 存的瞬时值跨机队 / 跨时窗一聚合就失真。

用具体数字算一遍(以 π0 类 @端侧 chunk 生成为参考,H=50 / 50Hz 控制,数量级估算,以官方为准):

  1. 执行时长基准:一个 chunk 覆盖 H=50 个动作,50Hz 每动作 20ms → 一个 chunk 覆盖 50 × 20ms = 1000ms 的执行。只要下一个 chunk 在 1000ms 内生成好,流水就不断供(21 章口径)。
  2. 正常主体:99 次推理延迟在 58~66ms,远小于 1000ms,绰绰有余。
  3. 偶发尖峰:第 100 次因热节流叠加 VM 争用,延迟飙到 1050ms
  4. 算均值:(99 × 62 + 1050) / 100 = (6138 + 1050) / 100 ≈ 71.9ms。均值只从 62 涨到 72,看起来依旧健康 —— 均值把 1050ms 的尖峰稀释掉了。
  5. 算 p99:第 99 百分位落在那次尖峰上,p99 = 1050ms。1050ms > 1000ms 执行时长 → 这个 chunk 没赶上,机器人在这一拍断供、停顿
  6. 结论:均值 72ms「达标」,p99 1050ms「击穿」。实时控制里,1% 的卡顿就是 1% 的动作停顿,用户能直接看到机器人「顿一下」。所以 SLO 必须盯 p99(甚至 p999),而非均值。

为什么 p99 必须走 histogram:p99 是「分布的第 99 百分位」,需要延迟分布才能算。若端侧只上报一个 p99 gauge(瞬时快照),云端把 100 台机器的 p99 gauge 再平均,得到的不是机队 p99——分位数不能这样合并。正确做法:端侧把 chunk_ms 落进 histogram 分桶(如 [0,50)、[50,60)、[60,80)、[80,200)、[200,+∞) 各自计数),云端合并各机的分桶计数后,再从合并直方图里算真实分位数(§3.1a OTel 映射把 chunk_ms 明确归为 metric.histogram)。

回链:详见 §2.1 三层栈(端侧指标聚合层做 histogram 分桶)、§3.1a OpenTelemetry 映射(metric.histogram 行)、§3.1c dsa-telemetry chunk_ms_p50/p99 字段,以及 21 章「chunk 延迟 < 执行时长」实时性口径。

思考题 2:tracing 如何定位跨节点延迟

一次具身推理横跨感知节点、VLM 推理节点、动作头、ROS2 执行节点,可能分布在不同进程 / 设备上。当 chunk p99 回归时,只有「总延迟变大」这个数字远远不够。结合 §3.1b 的 OpenTelemetry span 树与 §3.2 归因树,分析 tracing(trace_id / span / context 传播)如何把一个总延迟拆回到具体某一跳,以及它如何与 §3.2 的五条归因路径衔接。

展开参考答案(含跨节点 trace 拆解与归因衔接图)

结论:tracing 的本质是给一次物理推理分配一个全局 trace_id,让跨进程 / 跨设备的每一跳都记成挂在同一 trace_id 下的 span;拆开 span 树就能看出总延迟里哪一段膨胀,再顺着膨胀 span 上挂的 log / attribute 关联到具体成因,最后落进 §3.2 归因树的某一条分支——这就是从「总延迟变大」到「driver 第几号提交回归」的完整链路。

用一次排查走一遍:

  1. 总延迟报警:Fleet 看板显示某批机器 chunk p99 从 90ms 涨到 140ms。
  2. 按 trace_id 拉出一条完整 trace:感知 8ms、prefill 46ms、去噪 74ms、发布 6ms —— 一眼定位膨胀在 action_denoise(去噪本应 ~30ms)。跨节点能拼成一条链,靠的是 trace_id 通过 DDS 消息头(ros2_tracing 侧)与 IREE VM trace(NPU 侧)在节点间透传(§3.1b context 传播)。
  3. 下钻步级 span:去噪 5 步里 denoise_step_3 单步 38ms(其余 12ms)—— 精确到「第几步」。
  4. 看膨胀 span 上的线索:该 span 挂了 thermal_throttlelog.record,且 bundle_version 未变、无 VM 争用重叠。
  5. 落进归因树:线索指向 §3.2 的 thermal throttle? → 11 分支——根因是热节流触发 NPU 降频,而非 driver / bundle / 调度回归。若线索是 bundle_version 变化,则走 bundle/spec → 18 diff;若是 HAL dispatch 普遍变慢,则走 driver regression → 09 CI

为什么单靠指标(metric)不够、必须要 trace:metric(如 chunk_ms histogram)告诉你**「有问题、多严重」,但它是聚合后的标量,丢掉了因果结构;trace 保留了「一次具体推理的完整调用链」,能回答「问题在哪一跳、为什么」**。两者互补:metric 触发报警(p99 超阈),trace 完成归因(定位到 denoise_step_3 + thermal)。这正是 §3.2 归因树能「自动 bisect」的数据基础——没有跨节点 trace,归因树的每一个分支都无从判断。

回链:详见 §3.1b OpenTelemetry span 树(trace_id / context 传播)、§3.2 归因树五分支、§3.1a OTel 映射(trace.spaniree.dispatch),以及 ADR-113「分层归因树 + CI 自动 bisect spec」。

思考题 3:现场遥测如何回传失败样本

31 章 field 闭环与 18 章 autotune 回写都渴求现场失败样本,但摄像头原始视频是隐私红线(§3.3 L3 默认禁止)、且回传带宽有限。结合 §3.3 隐私分级(L0–L3)与 §3.3a 分级回传流程,论证「优先回传能定位问题的最小信息」这一原则,并说明什么情况下才应逐级 opt-in 到图像。

展开参考答案(含失败样本分级回传决策 + 对比表)

结论:现场失败样本的回传要在「归因价值」「隐私红线」「带宽成本」三者间权衡;绝大多数失败(延迟 / 热 / 调度)靠 L0 聚合遥测加失败时刻的 span 树就能定位,根本不需要图像;只有当问题疑似「感知看错 / 语义失败」这类必须视觉证据的场景,才逐级 opt-in 到 L1 元数据、L2 脱敏缩略图,L3 原始视频始终需单独合规审批。

四级回传的成本 / 价值 / 隐私对比:

级别回传内容归因能力带宽隐私风险默认
L0聚合 ms/Hz/W + 失败时刻 span 树定位延迟 / 热 / 调度 / driver 类(§3.2 归因树多数分支)极低✅ 常开
L1失败 episode metadata:动作序列 / 状态向量 / 时间戳+ 定位动作 / 状态异常(仍无像素)低(无原始感知)✅ opt-in
L2脱敏缩略图 / 关键帧(降分辨率)+ 视觉证据(看错了什么)中(需脱敏)客户 opt-in
L3原始视频完整场景复现❌ 禁止默认

为什么「最小信息优先」是对的:

  1. 归因效率:§3.2 归因树的五条分支里,bundle / thermal / driver / runtime 四条完全不需要图像——L0 的 span 树 + 聚合指标就能定位(见思考题 2)。只有 sim2real / 感知失败这一类才需要视觉。既然多数失败 L0 就能闭合,默认拉图像是浪费带宽 + 徒增隐私风险。
  2. 隐私红线不可逆:一旦原始视频回传上云,泄露风险与合规责任就已发生;而 L0/L1 从设计上就不含原始像素,风险从源头消除(§3.3 L3「禁止默认」、ADR-114「默认 L0」)。
  3. 带宽约束:现场机队规模大,若每个失败都回传视频,上行带宽与存储成本不可承受;分级回传让「昂贵的图像」只在真正必要时(客户显式授权)才动用。

什么时候才升级到图像:当且仅当 L0/L1 无法归因、且问题本质是视觉 / 语义的(如「机器人把红色积木当成番茄抓了」——这只能从图像看出),才在客户 opt-in 下升级到 L2 脱敏缩略图。L3 原始视频即便到这一步也需 28 章单独合规审批,不因排障需要就自动放行。这与 §5.3 类推理里「在能覆盖需求的前提下选择成本 / 风险最低的那个子集」是同一取舍哲学。

回链:详见 §3.3 隐私分级表(L0–L3)、§3.3a 分级回传流程图、§3.2 归因树(判断哪些分支需要图像),以及 ADR-114「L0–L3;默认 L0;失败样本分级回传,优先无图像」。


附:信息来源

区分公开/估计;参考时间 2026-06。产品名(Nsight Systems / Nsight Cloud / DCGM 等)以厂商官方命名为准。

  • NVIDIA Nsight Systems / Nsight Cloud(K8s Operator + Streamer 浏览器 UI):NVIDIA developer docs;命名与能力以官方为准。[公开]
  • IREE profiling / tracing(Tracy / VM+HAL timeline;compile+run 同源):iree.dev profiling docs。[公开]
  • OpenTelemetry(trace / span / metric.gauge / metric.histogram / resource / log 数据模型):opentelemetry.io specification。[公开]
  • ROS2 ros2_tracing(LTTng → Perfetto;DDS pub/sub + executor trace):github.com/ros2/ros2_tracing;design.ros2.org。[公开]
  • Perfetto(开放 trace 格式与 UI):perfetto.dev。[公开]
  • NVIDIA DCGM / Fleet Intelligence(数据中心 GPU 健康与机队运维):developer.nvidia.com DCGM docs;定位为数据中心,非具身端侧 SLO。[公开]
  • p99 / histogram 聚合口径、chunk 尾延迟算例:基于 21 章 π0 chunk 实时性口径的工程估算;具体 ms 以官方 / 实测为准。[估计]
  • 失败样本分级回传(L0–L3)与隐私边界:对齐 28/24 章合规;为本项目内部设计。[内部]