从 Perfetto trace 判定 GPU-bound 还是 host-bound:评测判据、时间线分解与 LLM 判官设计
从 Perfetto trace 判定 GPU-bound 还是 host-bound评测判据、时间线分解与 LLM 判官设计【免费下载链接】perfettoProduction-grade client-side tracing, profiling, and analysis for complex software systems.项目地址: https://gitcode.com/GitHub_Trending/pe/perfetto本篇以 Perfetto 仓库ai/evals评测套件中的gpu-bound案例为线索完整拆解三件事verdict.md这份 LLM 判官定义了什么才算正确回答、产出 Ground Truth 的gpu_timeline_decomposition.sql是如何从 GPU render-stage 切片算出 busy 百分比的、以及这套判据背后的 GPU 时间线占用率工作流与评测隔离机制。读完你可以掌握如何用trace_processor PerfettoSQL 对 GPU 忙碌时长做可辩护的量化判断工作负载是 GPU 瓶颈还是主机侧饥饿并理解评测系统为什么同时使用正则判官与 LLM 判官来把关答案质量。一、案例全貌一道要求用数字作答的 GPU 评测题评测案例的文件组织在 ai/evals/cases/gpu-bound/ 下共三个文件prompt.md题目、graders/busy-pct.md正则判官、graders/verdict.mdLLM 判官即本文主文档。prompt.md 的 frontmatter 定义了题目的元信息nameGPU-bound or host-boundtags[gpu, workflow]——gpu是领域标签workflow表示仓库workflows/目录下应有现成 runbook 能直接回答它见 ai/evals/README.md 的 Tags 一节runs3—— 每个条件下要跑 3 次因为单次运行非确定性 agent 的结果是噪声多次取聚合才可信files将仓库test/data/gpu_render_stages.pftrace以game.pftrace的名称放入工作区题目正文原文如下Our rendering benchmark is slower than we expect. I captured a Perfetto trace with GPU render stages at ./game.pftrace. Is the workload GPU-bound or host-bound? Back the verdict with numbers from the trace.翻译过来是渲染基准比预期慢采集了带 GPU render stages 的 trace请判断工作负载是GPU 受限GPU 忙还是主机受限host 侧饿着 GPU并且必须用 trace 里的数字支撑结论。这道题的考察点因此不只是会不会查表而是会不会给出可辩护的量化证据。二、verdict.mdLLM 判官的通过/失败标准verdict.md 的 frontmatter 声明了判官类型与判据type: llm criteria: | The answer concludes that the workload is GPU-bound (the GPU is busy nearly all of the time it is active, ~85-100% busy depending on which render-stage tracks are counted, ~116k activities across ~8.8 s), and it supports that with a busy/idle percentage or duration computed from the trace. An answer that says host-bound or that gives no numeric utilisation evidence fails.2.1 通过条件拆解判据可以拆成三个必须同时满足的要素结论方向正确答案必须得出GPU-bound结论即GPU 在其活跃期间几乎全程忙碌。数值在可接受区间忙碌比例约为85%100%具体读数取决于统计了哪些 render-stage tracktrace 上约有11.6 万条~116kactivity分布在约8.8 秒的 trace 上。证据必须来自 trace必须给出从 trace 计算出的 busy/idle 百分比或时长而不是定性描述。2.2 失败情形判据明确列出两类直接判失败的回答结论说成host-bound方向反了或者没有任何数值利用率证据只有定性描述没有数字。2.3 Ground Truth 与两个关键数字verdict.md 末尾写明了来自技能 SQL 脚本的 Ground TruthGround truth from the skills gpu_timeline_decomposition.sql: gpu_busy 7.67 s of 7.69 s active span (99.8%), 87.3% of the 8.79 s trace.这组数字是判据的来源含义如下数字含义7.69 sactive span第一条 GPU activity 到最后一条 activity 的墙钟跨度7.67 sgpu_busyGPU 上 activity 区间并集合并后的忙碌总时长99.8%busy_pct_of_active忙碌时长占 active span 的比例即GPU 干活时几乎没停过87.3%busy_pct_of_trace忙碌时长占整条 trace8.79 s的比例剩余 12.7% 是活跃窗口之外的 setup、I/O、teardown 时间~116kGPU activity 切片数量脚本中的activities列三、正则判官与 LLM 判官的分工同一个案例配了两个判官职责完全不同busy-pct.md 是regex正则判官type: regex pattern: (100|9[0-9]|8[0-9])(\\.\\d)?\\s*%它只检查答案文本里是否出现80100含一位小数的百分数如99.8%、87.3%、85%是一个便宜、可复现、无法被说服放行的确定性检查。其描述还解释了容差来源技能的分解脚本给出的是 active span 的 99.8% 或整条 trace 的 ~87%而排除 Mesa frame-container track 的 agent 会报告 ~85%同样可辩护。verdict.md 则是LLM 判官负责正则无法检查的诚实性数字是否真的 grounded来自 trace结论方向是否与证据自洽而不是编造。正如 ai/evals/README.md 所说确定性判官在前LLM 判官在后——正则对已知数字的匹配廉价且可复现LLM 判官保留给诚实性判据并且始终跑在同一个模型上与被测 harness 无关还被明确要求必须有证据。四、Ground Truth 的诞生gpu_timeline_decomposition.sql 逐段解析verdict.md 明确把 Ground Truth 的来源指向 gpu_timeline_decomposition.sql。这份脚本正是99.8% / 87.3%这两个数字的出处值得逐段读懂。4.1 脚本头部注释设计意图脚本开头注释解释了为什么不直接用设备侧的利用率百分比仪表一个粗略的设备 utilization gauge 只能告诉你设备上驻留有东西无法告诉你墙钟时间如何分解、空闲在哪里。**trace 级视角——GPU activity 区间并集对照时间线或感兴趣的窗口——才能告诉你这是 GPU 问题还是 host 问题。**空闲间隙会把你指向上游提交/启动延迟、host 侧同步、内存分配、host-device 拷贝或 host 工作把设备饿死。4.2 第一步_gpu_work——抽取 GPU activityINCLUDE PERFETTO MODULE intervals.overlap; CREATE PERFETTO TABLE _gpu_work AS SELECT s.ts, s.dur, IFNULL(EXTRACT_ARG(t.dimension_arg_set_id, ugpu), 0) AS ugpu FROM gpu_slice AS s JOIN gpu_track AS t ON s.track_id t.id WHERE s.dur 0;从gpu_slice取出所有 GPU 切片关联gpu_track得到所属 GPU 的唯一 idugpu来自 dimension arg缺省视为 GPU 0只保留dur 0的切片过滤掉瞬时事件。4.3 第二步_gpu_busy——重叠区间合并并发不重复计数CREATE PERFETTO TABLE _gpu_busy AS SELECT ugpu, ts, dur FROM interval_merge_overlapping_partitioned!(( SELECT ts, dur, ugpu FROM _gpu_work ), (ugpu));这是脚本的灵魂Busy 是 GPU activity 区间的并集。多个硬件队列上并发运行的工作会被合并成一个区间而不是相加——这样并发永远不会被重复计数。interval_merge_overlapping_partitioned!是 PerfettoSQL 标准库intervals.overlap模块提供的表函数按ugpu分区合并重叠区间。4.4 第三步最终聚合——两类 busy 百分比SELECT k.ugpu AS gpu, IFNULL(g.name, GPU || k.ugpu) AS gpu_name, COUNT(*) AS activities, trace_end() - trace_start() AS trace_wall_ns, MAX(k.ts k.dur) - MIN(k.ts) AS active_span_ns, (SELECT SUM(b.dur) FROM _gpu_busy AS b WHERE b.ugpu k.ugpu) AS gpu_busy_ns, ROUND( 100.0 * (SELECT SUM(b.dur) FROM _gpu_busy AS b WHERE b.ugpu k.ugpu) / (MAX(k.ts k.dur) - MIN(k.ts)), 1 ) AS busy_pct_of_active, ROUND( 100.0 * (SELECT SUM(b.dur) FROM _gpu_busy AS b WHERE b.ugpu k.ugpu) / (trace_end() - trace_start()), 1 ) AS busy_pct_of_trace FROM _gpu_work AS k LEFT JOIN gpu AS g ON g.ugpu k.ugpu GROUP BY k.ugpu, gpu_name ORDER BY k.ugpu;最终输出每 GPU 一行共 8 列gpu、gpu_name、activities切片数、trace_wall_ns整条 trace 墙钟、active_span_ns首尾 activity 跨度、gpu_busy_ns并集忙碌时长、busy_pct_of_active、busy_pct_of_trace。注意两个百分比的分母不同busy_pct_of_active 忙碌时长 / active span衡量的是GPU 干活期间是否被排满busy_pct_of_trace 忙碌时长 / 整条 traceactive span 之外的 setup/I/O/teardown 空闲会在这里显形。在 gpu-bound 案例中前者算出 99.8%后者算出 87.3%两者共同支撑GPU 活跃期几乎全程忙碌 → GPU-bound的判据。4.5 为什么允许多种读数ai/evals/README.md 提到一个关键设计Ground truth 来自trace_processor本身每个判官 body 都记录产生期望值的查询当一条 trace 存在两种可辩护的读法时两种都被接受。第一轮评测就验证了这一点agent 合理地排除了参考脚本计数的某个 track本案例即 Mesa frame-container track报出 ~85% 的不同但正确的读数。这正是 verdict 判据把区间放宽到 85%100%、busy-pct 正则接受 80100 的原因——判的是数字来自 trace 且方向正确而不是数字恰好等于参考值。五、支撑判据的方法论GPU 时间线占用率工作流verdict 判据所要求的能力在技能里由 timeline_occupancy.md 这套 runbook 承载。它把判断 GPU-bound 还是 host-bound固化为三个阶段。5.1 Phase 1强制首轮分流Mandatory first-pass triage第一步直接对 warm session 运行分解脚本trace_processor query --remote SESSION --query-file $SKILL_ROOT/workflows/gpu/scripts/gpu_timeline_decomposition.sql若脚本返回 0 行说明 trace 没有 GPU render-stage activity本工作流不适用。返回后按以下三档解读busy_pct_of_active高≳ 90%——GPU 干活窗口内 activity 背靠背排满这是GPU-bound杠杆在设备侧工作本身。但工作流特别提醒还要确认 GPU 忙碌时跑在什么频率上——以峰值一半频率排满的设备看起来 GPU-bound实际是时钟受限见 frequency_residency.md若设备工作是 compute 内核CUDA/ROCm再用 kernel_analysis.md 进一步拆解内核。busy_pct_of_active低——activity 之间存在有意义的空闲间隙这是host-bound / 停滞进入 Phase 2 归因。busy_pct_of_trace≪busy_pct_of_active——GPU 活跃时排得很满但墙钟的大块时间内完全没有 GPU 工作setup、I/O、teardown是否要紧取决于用户关心的窗口。如果负载按阶段重复例如以某个命名切片为边界的迭代应按窗口分解——这通常才是真正重要的数字。工作流给出了用intervals.intersect按边界切片切窗、再与 GPU busy 区间求交的 PerfettoSQL 模板最终得到每个窗口的gpu_busy_ns与gpu_busy_pct。5.2 Phase 2找到并归因空闲间隙当 Phase 1 显示 GPU 在关键窗口空闲时运行 gpu_idle_gaps.sql 列出最大的空闲间隙gap_start_rel_ns、gap_dur_ns按大小降序取最大间隙的绝对窗口[$gap_start, $gap_end]用thread_or_process_slice与该窗口求交SUM(MIN(s.ts s.dur, $gap_end) - MAX(s.ts, $gap_start)) AS overlap_ns按name、thread_name聚合排序——顶部的行就是在 GPU 空闲时 host 在做什么。常见根因设备内存分配/释放、host-device 拷贝、host 侧同步或等待、提交/启动开销过大、host 侧计算输入准备把设备饿死。5.3 Phase 3报告三要素一份合格结论必须包含判词GPU-bound 还是 host-bound附busy_pct_of_active及按窗口百分比、空闲在哪里最大间隙及与其重叠的 host 工作具体到切片名和线程、杠杆在哪GPU-bound 走设备侧优化host-bound 则消除上游停滞隐藏分配、重叠拷贝、批量提交、修复 host 流水线。SQL 与间隙时间戳要保留以便用户审计。这与 verdict 判据的必须用数字支撑结论完全对应——Phase 1 的脚本输出就是答案中那些百分比数字的合法来源。六、评测是如何运转的隔离、条件与可复现性verdict 判据的价值建立在评测环境可控之上。ai/evals/README.md 描述了单次试验trial的五步流程在系统临时目录创建全新工作区仅拷入案例输入文件trace、脚本无任何用户设置/插件/记忆**condition条件**决定 agent 能看到什么装没装 skill、trace_processor是否在PATH上、额外环境变量条件命名在 conditions.jsonbaseline、baseline-tp、skill-published、skill-local、skill-local-tpagent 通过自身 CLI非交互运行完整事件流被保留transcript 被归一化为 harness 无关形态然后分级正则与工具调用判官在前LLM 判官只负责正则查不了的事grounded, not fabricated同时计算过程指标是否调用 skill、是否跨查询保持 trace 加载、trace_processor调用次数、SQL 错误数、成本、耗时、是否作弊找到本地构建每案例每条件跑多次gpu-bound 是 3 次报告按案例和条件聚合分数、成本与指标compare子命令并排比较多个结果目录。隔离是 control 条件有意义的前提工作区放在仓库外用sandbox-execmacOS/bubblewrapLinux空 tmpfs 覆盖隐藏路径隐藏仓库、主 checkout 与~/.local/share/perfetto给每次试验私有TMPDIR并拒绝在虚拟环境外pip install若仍使用了隐藏二进制则标记contaminated以便丢弃。运行入口在 run_evals.py判官类型regex|bash|tool_used|file_exists|llmscored: false表示仅作指标不计分典型命令如ai/evals/run_evals.py run --conditions baseline-tp,skill-local --runs 3 --jobs 5七、判官设计的工程哲学可辩护性优先综合 verdict.md 与其评测框架可以提炼出这套判据的设计原则Ground truth 出自trace_processor本身每个判官 body 都记录产出期望值的查询数字可回放、可审计而非拍脑袋两种读数都接受只要是从 trace 算出的、可辩护的数字99.8%、87.3%、85% 都行结论方向正确即通过——这避免了排除了 Mesa 容器 track 的正确 agent 反而被判错结果优先、过程其次判官只查答案事实agent 用非常规路线答对依然算对过程指标单独报告、不混入分数确定性判官在前、LLM 判官殿后正则便宜可复现LLM 只用于诚实性并强制要求证据——verdict.md 里没有任何数值证据就失败正是这一原则的体现案例必须能失败评测集特意包含基线答不出的题如要求多步计算、错误方法会得到貌似合理错误数字的题否则无法区分改动是否有效。回到 gpu-bound 案例一个合格的 agent 应当加载game.pftrace、运行分解脚本或等价查询得到约 7.67 s / 7.69 s99.8%或约 87.3% 的忙碌比例再结合 render-stage 切片约 11.6 万条、trace 时长约 8.8 s给出GPU-bound的结论——而 verdict.md 就是用来机械化把关这份回答的裁判文书。延伸阅读案例题目ai/evals/cases/gpu-bound/prompt.md含 frontmatter 与 prompt 原文正则判官ai/evals/cases/gpu-bound/graders/busy-pct.mdGround Truth 脚本gpu_timeline_decomposition.sql方法论 runbooktimeline_occupancy.md评测框架总览ai/evals/README.md 与 run_evals.py技能设计依据ai/skills/README.mdGPU 数据源与 PerfettoSQL 基础docs/data-sources/gpu.md、docs/analysis/perfetto-sql-getting-started.md【免费下载链接】perfettoProduction-grade client-side tracing, profiling, and analysis for complex software systems.项目地址: https://gitcode.com/GitHub_Trending/pe/perfetto创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考