HelloGPU-P03-Agent(算子层)
第 3 篇 Agent(算子层)
第 14 章 Agent 入门
本章先为Agent优化算子建模。提出在优化要在相同环境、相同测量基准下执行,要首先给出任务规格、参考实现(可以认为是基准baseline),在验证过的baseline基础上进行分析、寻找瓶颈假设与优化点,借助大模型做一步的优化分析与优化实现,得出候选,首先验证候选结果的正确性,然后才能检查其延迟并与
baseline和当前方案
进行对比,如果候选更优则替换掉当前方案,否则保留当前方案、同时对本轮与前面所有证据进行综合评估分析,针对瓶颈假设另做优化尝试,即循环上述过程(引入了ReAct这一agent开发思路)。
完整的Agent优化算子流程,如下: 
14.6 练习:判断一份报告是否可信
试着根据以下情形,区分模型的提议、工具的观察和可以得出的结论。
模型说“这个实现减少了一次全局内存写回,所以一定更快”。把这句话拆成代码事实、性能假设和需要补充的实验。 回答: 代码事实:减少了一次全局内存写回。 性能假设:同一环境下、相同的计算,运行更快、耗时更少。 需要补充的实验:将修改后的程序在同一个环境条件下,对相同的算子测试多次,以多次结果综合评估与检验。
候选编译成功,但尚未对答案。指出 图 14.2 中它还不能越过的检查,并说明原因。 回答:不能越过正确性检查。如果候选答案错误,应先检查索引和掩码,继续比较延迟没有意义,答案正确性是第一要务。
一轮候选被拒绝后,为什么
best.py应保持不变?如果每轮生成代码时都覆盖它,下一次比较会失去什么? 回答:基线是最初的参照,当前版本是已经被接受的参照,候选则是尚待验证的修改。一轮候选被拒绝,说明当前候选验证失败或未达到期望,现有best.py结果正确、性能更好,best.py应保持不变,这是由我们的优化目标决定的。 如果每轮生成代码时都覆盖它,下一次比较会失去”已经被接受的参照“。不看源码,画出模型、工具和反馈之间的关系;再打开
agent.py,找到与三个角色对应的位置。 回答:模型、工具和反馈之间的关系,如下图所示:
本章小结
- Agent 在目标约束下反复选择行动、调用工具和读取反馈,模型参数不会因一次反馈而自动更新。
- 基线是最初的参照,当前版本是已经被接受的参照,候选则是尚待验证的修改。
- 正确性、计时和接受判定承担不同职责;瓶颈估算需要与硬件实测区分。
- 一次搜索没有获得加速,也可以通过完整的负结果帮助我们缩小后续尝试范围。
第 15 章 工具封装
本章给出了任务配置规范,编译与正确性检查compile_kernel、再次编译与多样本多次 GPU Event 计时、瓶颈假设列表、接受候选的采用的评价标准 等做出了设计。还具体阐明要根据实际情况(失败或性能未达标)决定下一步检查内容与优化方向。
15.7 练习:为结果找对解释
compile_kernel返回ok = true,但bench_kernel失败。列出仍需检查的信息,说明为什么两次工具调用不矛盾。 回答:首先要明确这二者做的事情分别有哪些,如下。两者的正确性数据由固定种子生成,两者的“正确性输入分布/规则”是一致的;但1
2
3
4
5
6compile_kernel:
检查源码 → 首次启动、编译并执行 → 与参考结果比较
bench_kernel:
重新检查源码与正确性 → 预热 → 多个样本、每样本多次 GPU Event 计时
→ 每次仍检查结果bench_kernel会在更多次调用中重新填充输入、重置输出并反复验证,不能把它理解为只拿compile_kernel那一次已经算过的同一块 GPU 内存继续计时。如果某kernel检查成功与否依赖于输出数组的旧内容:第一次输出初值“碰巧”使结果正确;bench_kernel在后续重置输出后,这个偶然条件消失,验证失败。 另外,显然bench_kernel做的事情更多、执行轮次更多,可能在compile_kernel中包含事情之外的事情中出错, 如计时阶段出错;且这两者的执行总是有时间先后,并不能保证不同时刻环境(GPU可用性)是完全一致的。其他的可以考虑检查的事情如下表:
| 仍需检查什么 | 为什么会导致 bench_kernel 失败 |
|---|---|
bench_kernel 的 source 是否与
compile_kernel 字节完全相同 |
两个工具都接收独立的 source
参数。模型或用户可能在两次调用间改过源码;哪怕只改一个边界条件,也已经是新候选。 |
| 固定任务是否仍一致(即可能修改了源码或任务规格) | task.json 规定入口 launch、形状、FP16
类型、输入、误差阈值、warmup
和样本数。任务或工作区的参考实现变了,也不能把前一次成功直接沿用。 |
bench_kernel 返回的
stage、errors、具体错误日志 |
先区分是源码策略/入口检查失败、首次启动时的编译失败、运行时错误、数值错误,还是计时阶段的问题。不同阶段的修复办法不同。 |
| 候选能否在重复执行、输出重置后仍保持正确 | compile_kernel 做正确性检查;bench_kernel
会再次验证,并在预热和每次测量中反复调用
launch(...),每次还会重置输出、检查结果。某些实现一次能对,多次执行时才暴露依赖旧输出、未完整写输出、异步错误或状态依赖。 |
| GPU/运行环境是否稳定可用 | 两次评测在独立进程中执行。两次之间可能发生显存不足、设备错误、依赖/驱动问题或超时;前一次成功不构成对后一次环境状态的保证。 |
在正常、确定性的候选代码与稳定环境中,若两次传入的是同一源码、同一任务,那么
compile_kernel 成功后,bench_kernel
通常也应通过正确性检查。若失败,优先看 bench_kernel
返回的 stage、errors
和运行日志,不能只凭“前一次已编译成功”断定是计时器的问题。
对照成本模型,推导 FP32 向量加法的算法字节数和算术强度。这里计算的是物理显存事务数吗? 回答:不是。对照成本模型,推导 FP32 向量加法的算法字节数和算术强度,计算出来的都是逻辑统计数据,并不是由计数器测得的物理实际数据,比如其中关键的字节数数据就是由逻辑分析得到,并不是由计数器测得的物理显存流量,这是由任务语义得到的工作量模型,实际缓存行为、内存事务和编译器生成代码可能使物理流量与它不同。
两份摘要都有中位延迟,却没有配对样本。说明哪些比较可以描述,哪些接受结论还不能下。 回答: 没有配对样本时, 哪些比较可以描述:两份独立测试摘要显示,候选的中位延迟低于当前版本;在各自测试时段与配置下,候选观察到的延迟更低。 哪些结论还不能下:
- 候选达到本任务的接受阈值;
- 候选有至少 60% 的配对改进为正;
- 配对改进比例的中位数达到阈值;
- 性能差异由代码改动导致,而非负载、温度或运行状态漂移;
- 每一对中候选都更快。
如果有配对样本,则可以做如下陈述: 在相同任务、相同测试数据、交错顺序的配对测量中,候选的配对改进比例中位数达到接受阈值,且至少 60% 配对为正,因此该候选满足当前任务的接受规则。 哪些结论还不能下:每一对测量中候选都更快,构成对其他输入、其他设备或其他运行环境的普遍性能保证。
- 设计一份错误返回结构,使模型能够分清“答案错误”和“缺少设备”;只需画字段表,不需要伪造实验输出。 回答:
本章小结
- 工具共享固定任务,将候选源码与实验条件分开。
- 编译、正确性和计时逐层检查;有效带宽和 Roofline 分类需要注明推算来源。
- 接受工具重新配对比较,以配置阈值和样本条件裁决候选,拒绝时保留当前版本。
- 裁决摘要不等于完整实验档案,缺少的信息必须如实标记。
第 16 章 算子优化 Agent 设计
一次优化分成三部分:模型选择行动,工具执行评测,工作区保存结果。
一项假设对应一份候选,这样方便检验每个假设的结果、避免混淆。
管理已经测过计时、尚未裁决的候选的处理流程如下:
run_agent流程执行结束,并不表示所有接受版本一定比其基线快,还需进行独立复测才能报告相对最初基线的整体收益。
16.7 练习:沿着状态检查程序
模型已成功 benchmark 版本 A,随后尝试提交版本 B。沿 图 16.2 说明程序应当拒绝哪一步,以及理由。 回答:拒绝版本 B 的”accept_candidate:提交同一源码“这一步。理由是:等待期间,只允许对同一份源码继续计时、分析或裁决;不能换一份源码直接提交,也不能跳到下一份候选。
一轮模型回复调用了三个工具,其中只有一次
accept_candidate。分别计算模型轮次、工具调用数和裁决数。 回答: 计算模型轮次:1轮。 工具调用数:3个次。 裁决数:1次。所有候选都被拒绝时,什么条件下报告仍然有价值?报告中的“最终结果”应如何表述? 回答: 所有候选都被拒绝时,候选的状态是complete或complete_with_warning 时报告仍然有价值。 报告中的“最终结果”大致描述如下:虽然所有都被拒绝,但候选的状态是complete或complete_with_warning,这表示候选的相关检查流程已经正常完成,有可分析的裁决证据且没有未清除的 pending ,或者 前面有可分析记录但存在未完成尝试等限制,这些可分析的裁决证据或可分析记录也能形成一份完整报告,在报告的基础上有助于决定下一步如何修改。
在
agent.py中找到保存和清除pending_candidate.py的位置,解释为什么不能在收到任意字符串返回后立即清除它。 回答:两个关于保存与清除的方法定义在agent.py文件中第196行、203 行左右:def persist_pending(source: str) -> None:、def clear_pending() -> None:。它们分别在第510行、516行 处被调用。
什么不能在收到任意字符串返回后立即清除: 程序只有在调用
accept_candidate 后,确认返回值是包含 accepted
字段的 JSON,且 trajectory.jsonl
文件大小确实增长、即裁决摘要已写入时,才调用
clear_pending()。该裁决可以是“接受”或“拒绝”,关键是已经留下可追溯的裁决记录。
因此,不能收到任意字符串返回就立刻清除
pending。任意字符串可能是工具报错、格式异常,或一次没有写入裁决轨迹的失败调用;若此时清除,就会丢失已
benchmark 的候选 A 的身份和待裁决状态。之后模型可能直接改用候选 B,却把
A 的 benchmark 结果误关联到 B,或者让 A 没有经过
accept_candidate 裁决就被遗漏。
本章小结
- 模型选择行动,工具执行实验,工作区保存任务与当前状态,三者职责分开。
- 提示词建议的流程不等于程序强制的流程;理解实现时需要分别核对。
- 非交互模式为成功 benchmark 的新候选建立待裁决状态,并检查源码一致性。
- 停止运行、证据完整和获得加速是三个不同判断,报告必须分别说明。
下一章用向量加法串起这些检查,学习怎样保存、读图并报告一次多轮优化实验。
第 17 章 多轮优化实战
操作记录
创建~/.config/hello-gpu/kernel-agent.env文件,其中设置如下内容:
1
2
3
4
5root@j-n3fgz62ihbedsl622r5kxsbxhn:/workspace/code/part3-agent# cat ~/.config/hello-gpu/kernel-agent.env
KERNEL_AGENT_MODEL=deepseek/deepseek-flash
KERNEL_AGENT_API_KEY=sk-39904f187aaa405fb7e4fcd1c1xxxx
KERNEL_AGENT_API_BASE=https://api.deepseek.com
KERNEL_AGENT_EXTRA_BODY={"thinking":{"type":"disabled"}} # 按模型接口要求调整额外参数;需要移除默认扩展时可设为 {}
修改code/part3-agent/pyproject.toml文件: 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25...
[project]
name = "part3-agent"
version = "0.1.0"
requires-python = ">=3.12,<3.13"
dependencies = [
"numpy>=2.4.4",
#"torch[device-gfx1201]==2.13.0+rocm10.0.0",
#"torchvision[device-gfx1201]==0.28.0+rocm10.0.0",
#"torchaudio==2.11.0.2+rocm10.0.0",
#"rocm[devel,device-gfx1201]==10.0.0",
# Agent 层依赖:LLM 调用、结构化输出、TUI
"litellm>=1.50",
"pydantic>=2.0",
"prompt_toolkit>=3.0",
"fastapi>=0.100",
"orjson>=3.0", # litellm MCP handler 的 http parsing 依赖(function calling 时的一个 import 链)
"matplotlib>=3.0", # Roofline 可视化
"torch[device-gfx1100]==2.13.0+rocm10.0.0",
"torchvision[device-gfx1100]==0.28.0+rocm10.0.0",
"torchaudio[device-gfx1100]==2.11.0.2+rocm10.0.0",
"rocm[devel,device-gfx1100]==10.0.0",
]
...1
2
3
4cd code/part3-agent
uv sync
source ./activate-rocm.sh
解决绘图时字体缺失的问题: 1
2
3
4
5apt-get update
apt-get install -y fonts-noto-cjk
fc-cache -fv
fc-list :lang=zh family | head
1 | |
这个命令做的事情比较,如下: 它不只是让 Agent 尝试优化,也包含搜索后的性能复测与可视化。 正常完成时,它会依次做:
- 检查原始
baseline.py正确性,并重新校准硬件峰值; - 运行 Agent 搜索候选;
- 将原始
baseline.py与最终best.py做 5 次独立配对复测; - 生成搜索过程图;
- 保存结构化汇总和 Agent 的文字报告。
主要产物在终端打印的实际 workspace 中,通常类似:
1 | |
但需区分两件事:
- 会自动生成
agent-report.md,但这是 Agent 生成的文字报告,不能脱离trajectory.jsonl、final-comparison.json等证据单独采信。 - 不保证一定进行
profile_kernel一类的细粒度性能剖析;它是 Agent 按需调用的工具。脚本一定会做硬件校准、最终独立配对复测和可视化,但不保证产生硬件计数器级别的性能分析。
另外,只有 Agent 阶段成功后,脚本才会继续执行最终的 5 次独立复测;若
Agent 阶段失败,则应先检查
agent-status.json、日志和错误原因。
独立复测: 1
2
3
4
5uv run python chapter14/compare.py \
--task "chapter15/logs/tasks/<本次工作区>/task.json" \
--incumbent "chapter15/logs/tasks/<本次工作区>/baseline.py" \
--candidate "chapter15/logs/tasks/<本次工作区>/best.py" \
--runs 5
20261031: 由于部署环境中”uv
sync“命令执行时间过久,暂时没有自己执行出结果。明天再试。
从教程docs/part3-agent/chapter17/optimization-report.md中输出的文字报告来看,通过对测试的结果的分析看到,block_size的基线值为256,将block_size修改为512时获得的测试效果最好,报告中给出了详细的优化与分析过程。
20261101:执行过程中的输出如下: 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95(part3-agent) root@j-226vu6mkspiem7bepwysjyb65g:/workspace/code/part3-agent# bash chapter17/run_all.sh --skip-pytest
Activated ROCm uv environment:
PROJECT: /workspace/code/part3-agent
VENV: /workspace/code/part3-agent/.venv
ROCM_PATH: /workspace/code/part3-agent/.venv/lib/python3.12/site-packages/_rocm_sdk_devel
Python: /workspace/code/part3-agent/.venv/bin/python
ROCm SDK: 10.0.0
Python 3.12.3
╭════════════════════════════════════════════════════════════╮
│ part3-agent 本地验收 · docs/part3-agent ch14–17 │
╰════════════════════════════════════════════════════════════╯
映射:
ch14 Agent 入门 → kernel_optimize 主循环
ch15 工具封装 → chapter14 evaluate + tools
ch16 Agent 设计 → fixtures/vector_add + batch 入口
ch17 多轮实战 → 本脚本:跑闭环 + 打印 + 可视化
[env] MODEL = deepseek/deepseek-flash
[env] API_BASE = https://api.deepseek.com
[env] API_KEY = set
[gpu] torch=2.13.0+rocm10.0.0 device=AMD Radeon Pro W7900D arch=gfx1100
── 2) vector_add Agent 闭环(batch)──
fixtures : /workspace/code/part3-agent/chapter15/fixtures/vector_add
workspace: /workspace/code/part3-agent/chapter15/logs/tasks/task-20261101-102036
max_steps: 25
[gpu] torch=2.13.0+rocm10.0.0 device=AMD Radeon Pro W7900D arch=gfx1100
[step 1] 调工具 get_environment …
[step 1] → {"device": "AMD Radeon Pro W7900D", "gpu_arch": "gfx1100", "rocm": "7.15.26333", "torch": "2.13.0+rocm10.0.0"}
[step 1] 调工具 measure_peak …
[step 1] → {"name": "AMD Radeon Pro W7900D", "bandwidth_gb_s": 720.5537473238618, "fp32_tflops": 2.644106371845981, "fp16_tflops": 64.89814432747362}
[step 2] 调工具 profile_kernel …
[step 2] → {"kernel": "vector-add", "time_ms": 0.10704039931297302, "grid": null, "vgpr": null, "bandwidth_utilization_pct": 65.3, "bottleneck": "DRAM bandwidth", "sm_satu
[step 2] 调工具 read_reference …
[step 2] → # 优化套路库(按 bound 类型)
[step 3] 调工具 bench_kernel …
[step 3] → {"ok": true, "status": "ok", "mean_ms": 0.11397427201271057, "median_ms": 0.10666420012712478, "p95_ms": 0.11058403998613357, "std_ms": 0.03471536862449307, "ba
[step 4] 调工具 compile_kernel …
[step 4] → {"ok": true, "stage": "run", "errors": [], "warnings": []}
[step 5] 调工具 bench_kernel …
[step 5] → {"ok": true, "status": "ok", "mean_ms": 0.1143850153684616, "median_ms": 0.10637219995260239, "p95_ms": 0.11330440014600754, "std_ms": 0.03514038174353577, "ban
...
── 原始 baseline 与最终 best 独立配对复测(5 次)──
[compare] exit=0 result=/workspace/code/part3-agent/chapter15/logs/tasks/task-20261101-102036/final-comparison.json
═══ 最终报告(模型文本)═══
达到最大步数(25),停止。轨迹见 /workspace/code/part3-agent/chapter15/logs/tasks/task-20261101-102036/trajectory.jsonl。
═══ 确定性汇总(trajectory)═══
轮次:7;接受:1
[1] ✗ block_size 256 -> 1024(增大单 program 处理量,摊薄 launch/索引开销) latency=0.10586259812116623ms improvement=-0.0006 · below_threshold(中位改进 -0.0006 < 阈值 0.01;最差配对 -1.4379)
[2] ✓ 去掉 mask 谓词(N 可被 block 整除)+ max_contiguous/multiple_of 提示,启用无 latency=0.10689819902181626ms improvement=0.0132 · improved(中位改进 0.0132,60% 配对为正,最差配对 -1.5800)
[3] ✗ 每 program 展开 4 段(grid 缩小 4 倍,提高访存 ILP),保持 mask-free latency=0.10862599909305573ms improvement=-0.0146 · below_threshold(中位改进 -0.0146 < 阈值 0.01;最差配对 -0.1581)
[4] ✗ num_warps 4->8(每线程 4 元素 = float4 128-bit 访存),保持 mask-free bl latency=0.10701859891414642ms improvement=0.0084 · below_threshold(中位改进 0.0084 < 阈值 0.01;最差配对 -0.1047)
[5] ✗ 对 load/load/store 加 eviction_policy="evict_first" 流式缓存提示,减少 latency=0.10600479990243912ms improvement=0.0063 · below_threshold(中位改进 0.0063 < 阈值 0.01;最差配对 -0.0499)
[6] ✗ block 1024 -> 2048 配 num_warps=8(每线程 8 元素),加大单 program 数据量 latency=0.10709039866924286ms improvement=-0.0016 · below_threshold(中位改进 -0.0016 < 阈值 0.01;最差配对 -0.0897)
[7] ✗ 叠加两个已独立微正的旋钮:num_warps=8 + evict_first 流式提示(block 1024, mask latency=0.10656879991292953ms improvement=0.0031 · below_threshold(中位改进 0.0031 < 阈值 0.01;最差配对 -0.0925)
best.py:/workspace/code/part3-agent/chapter15/logs/tasks/task-20261101-102036/best.py
轨迹:/workspace/code/part3-agent/chapter15/logs/tasks/task-20261101-102036/trajectory.jsonl
── 3) 可视化优化过程 ──
═══ 优化轨迹表 ═══
# acc status lat(ms) imp% change
----------------------------------------------------------------------------------------------------
1 ✗ below_threshold 0.1059 -0.06 block_size 256 -> 1024(增大单 program 处理量,摊薄 launch
2 ✓ accepted 0.1069 +1.32 去掉 mask 谓词(N 可被 block 整除)+ max_contiguous/multip
3 ✗ below_threshold 0.1086 -1.46 每 program 展开 4 段(grid 缩小 4 倍,提高访存 ILP),保持 mask-f
4 ✗ below_threshold 0.1070 +0.84 num_warps 4->8(每线程 4 元素 = float4 128-bit 访存),保持
5 ✗ below_threshold 0.1060 +0.63 对 load/load/store 加 eviction_policy="evict_first
6 ✗ below_threshold 0.1071 -0.16 block 1024 -> 2048 配 num_warps=8(每线程 8 元素),加大单 p
7 ✗ below_threshold 0.1066 +0.31 叠加两个已独立微正的旋钮:num_warps=8 + evict_first 流式提示(bloc
----------------------------------------------------------------------------------------------------
轮次=7 接受=1 阈值=1%
findfont: Failed to find font weight 600, now using 400.
findfont: Failed to find font weight 600, now using 400.
findfont: Failed to find font weight 600, now using 400.
findfont: Failed to find font weight 600, now using 400.
可视化输出:
- /workspace/code/part3-agent/chapter16/logs/task-20261101-102036/viz/process_timeline.png
- /workspace/code/part3-agent/chapter16/logs/task-20261101-102036/viz/status_breakdown.png
- /workspace/code/part3-agent/chapter16/logs/task-20261101-102036/viz/rounds_overview.png
[summary] /workspace/code/part3-agent/chapter15/logs/tasks/task-20261101-102036/run_summary.json
═══ 验收结论 ═══
workspace : /workspace/code/part3-agent/chapter15/logs/tasks/task-20261101-102036
agent_exit: 0
figures : 3 files/workspace/code/part3-agent/chapter15/logs/tasks/task-20261101-102036/目录下可得到如下几个文件:
(1)run_summary.json文件如下: 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46{
"workspace": "/workspace/code/part3-agent/chapter15/logs/tasks/task-20261101-102036",
"fixture": "/workspace/code/part3-agent/chapter15/fixtures/vector_add",
"agent_exit": 0,
"pytest_exit": null,
"rounds": 7,
"accepted": 1,
"largest_accepted_step_improvement": 0.013238277382001132,
"report_preview": "达到最大步数(25),停止。轨迹见 /workspace/code/part3-agent/chapter15/logs/tasks/task-20261101-102036/trajectory.jsonl。",
"generatedAt": "2026-11-01T10:23:49",
"agent_status": {
"state": "complete",
"evidenceReady": true,
"warning": false,
"trajectoryRows": 7,
"pendingCandidate": false
},
"final_comparison": {
"status": "ok",
"runs": 5,
"candidateMediansMs": [
0.10683259814977646,
0.10795859843492508,
0.10782279968261718,
0.10547419786453247,
0.10799040049314498
],
"incumbentMediansMs": [
0.10701820105314255,
0.10687859952449799,
0.10791639983654022,
0.1063625991344452,
0.10693060010671615
],
"pairedImprovementFractions": [
-0.001794141052157573,
-0.012213982847246124,
-0.0009896369087504379,
0.0009521668501340159,
-1.8701249504084012e-05
],
"medianCandidateMs": 0.10782279968261718,
"medianIncumbentMs": 0.10693060010671615,
"medianPairedImprovementFraction": -0.0009896369087504379
}
}viz子目录有如下3个图片文件: 
agent的整个内容很多,还有待进一步仔细、深入学习。我觉得这可以当成是一次标准的工程问题agent化处理的典型代码,很值得进一步深入学习、理解。
17.7 练习:完成一次可复盘的优化
找出当前 fixture 中与输入规模有关的所有字段,说明只修改
n_elements为什么可能改变实验含义。 回答: 当前 fixture 的输入规模由顶层shape.rows、shape.cols定义;tensors.x、tensors.y、tensors.output的shape: "input"将它们绑定到该形状;标量n_elements.value则把总元素数传给 kernel。此外,costModel.flops和costModel.bytes也依赖该规模,用于性能指标推算。 对该向量加法任务,应保持n_elements = rows × cols,并同步更新成本模型。只修改n_elements会使实际张量大小、kernel 的访问范围和性能成本模型不一致,可能造成正确性失败、越界访问,或错误的性能分析结论。假设某个候选跨轮看起来更快,却被配对裁决拒绝。结合采样时间和比较对象,给出一个可能的解释,并说明还需哪些数据。 回答: 某候选跨轮看起来更快,可能只是它在另一时间点、另一设备运行状态下测得的单独候选延迟较小;例如设备负载、温度或频率状态不同。
进入 accept_candidate
后,工具会在同一轮交错测量该候选与当时的当前版本
best.py,并交替二者的先后顺序。若该轮配对样本的改进中位数未达到阈值,或正改进配对比例不足,候选仍会被拒绝。
此外,跨轮的比较对象也可能不同:前一轮或许与当前版本 A 比较,若中间已有候选被接受,后一轮则可能与版本 B 比较。因此,不能按跨轮的最小候选延迟选“胜者”。
还需要查看:该轮评测目录中的候选与 incumbent 源码快照、每一对
candidate/current
的原始时间样本与运行先后顺序、improvementFraction
和拒绝原因,以及任务配置和环境记录。只有这些数据才能判断拒绝是由性能波动、比较对象变化,还是候选确实未达到接受条件导致。
- 运行完成后,分别指出支持“流程完成”“版本被接受”“相对基线获得加速”的证据文件或实验步骤。
回答:
“流程完成”:输出的
run_summary.json文件中"agent_status.state"属性值为”complete或complete_with_warning“。 “版本被接受”:在流程完成的基础上,run_summary.json文件中"agent_status.state"属性"accepted"对应的值大于等于1,当前版本best.py文件内容与原始baseline.py的不同。同时trajectory.jsonl文件中也有相关记录行。 “相对基线获得加速”:run_summary.json文件对应的”pairedImprovementFractions“属性值>0。
你的回答有部分字段位置和证据层级需要改正。可按三类结论分别写:
- “流程完成”
首要证据是工作区中的 agent-status.json,而非
run_summary.json。
1 | |
state == "complete":存在可分析的裁决证据,且没有未清除的 pending 候选。state == "complete_with_warning":也已有可分析记录,但报告必须写明其中的警告或未完成尝试。state == "incomplete":不能称本轮流程证据完整。
run_summary.json 只是汇总文件;其中的对应路径是:
1 | |
而不是 agent_status.state 的值中再包含
accepted。
- “版本被接受”
直接证据是 trajectory.jsonl 中存在某一行:
1 | |
该行还应包含
change、reason、improvementFraction
和 evaluation 等信息;evaluation
指向本轮评测目录,可继续核对候选、当时
incumbent、任务快照和完整评测结果。
辅助证据包括:
run_summary.json顶层的accepted >= 1;注意它是顶层字段,不是agent_status内的字段。- 检查最终
best.py,确认它是当前被保留的版本,并与baseline.py对照其实际改动。
“版本被接受”不需要以“流程完整”为前提;即使最终状态带 warning,某一轮也可能已经接受过候选。
- “相对初始基线获得加速”
不能用搜索阶段的
trajectory.jsonl.improvementFraction,也不能只看
run_summary.json 中某个单独的
pairedImprovementFractions
值。它们比较的是候选与当时的当前版本,不是原始
baseline.py。
应以搜索结束后的独立复测为证据:
1 | |
它来自原始 baseline.py 与最终 best.py 的 5
次独立配对测量。重点查看:
1 | |
其中:
medianIncumbentMs / medianCandidateMs > 1:按两边独立运行中位延迟列表的中位数计算,最终版本显示更快。medianPairedImprovementFraction > 0:5 次独立配对测量的配对改进中位数为正。- 还应查看
pairedImprovementFractions的正负分布和波动,以及各次正确性是否通过;小幅正值不能自动称为“稳定加速”。
run_summary.json 中会在 final_comparison
下保留一份删去原始 results
的摘要,可快速查看;但要写正式结论,应回到完整的
final-comparison.json。
你的当前实际结果若是“没有候选超越当前版本”,通常应表述为:
流程已完成,但没有任何候选通过接受裁决,因此
best.py仍为初始baseline.py;本次搜索没有产生可保留的优化版本,也不能报告相对初始基线获得加速。
- 选择一次被拒绝的尝试,用一个短段落区分源码改动、观察结果与原因假设。没有实测时,先完成这份记录的字段设计。 回答:
本章小结
- 先固定任务与基线,再搜索候选;一次搜索不预设收益大小。
- 运行状态、裁决摘要和完整实验档案的覆盖范围不同,需要逐项核对。
- 候选延迟、当前版本记录与配对改进有不同含义,图例应明确说明。
- 最终加速结论来自原始基线与最终版本的独立复测,不能从搜索曲线反推。