Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions docs/optimization-workflow-unification.md
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,8 @@ inferrsi campaign start --directory <campaign-dir-outside-project> \

项目适配器先检查基线和候选质量,再做 warmup 和交替顺序的基线/候选测量;每轮和 final 使用相同协议。每步骤启动新进程,因此跨进程 warmup 只能预热可持久缓存;设备/进程内 warmup 必须在测量脚本内完成并说明。性能取声明指标的中位数,当前没有通用服务生命周期管理器或统计显著性判定。

assessment 另附只读的 `paired_statistics`:同一次重复内的第 k 个基线与第 k 个候选样本按顺序配对,计算逐对加速比的中位数,以及按重复重采样的 95% percentile bootstrap 区间(记录 resamples 与 seed),并给出区间与冻结门槛的关系(`above_gate`、`straddles_gate`、`below_gate`;门槛没有有限加速比时为 `gate_unreachable`;少于 5 次重复为 `insufficient_pairs`;样本或派生值无效为 `unavailable`)。`agrees_with_point_gate` 标出中位数点估计的判定与配对区间是否一致。该字段只描述留存样本,不改变 verdict、eligible 或选优,`statistical_significance` 仍为 `not_established`。区间是名义 95%,覆盖率未经校准:合成对照中 3 对时约 75%,因此少于 5 对不报告区间。区间假设各次重复独立,不能消除同一对内共同的设备争用,也不构成环境资格。合成对照可用 `python tools/measurement_simulation.py` 复算。

结果协议:

- 测量脚本正常结束并写 JSON,提供指定字段的有限正数。
Expand All @@ -195,6 +197,36 @@ inferrsi dashboard --input <campaign-dir> --output <report.html>

知识检索和 profiling 按当前问题需要进行,不要求每轮重查或每轮 profile。知识关闭时受管 `knowledge` 操作拒绝执行;这不是对宿主所有文件访问的隔离。

### 用 profile 解释改进(可选)

端到端时间会随时钟、温度和共享负载整体漂移,单凭数值很难区分真实改进与波动。测量脚本可以在结果 JSON 中额外输出同一步骤的分区域耗时和工作量计数,单位由脚本自定并在各步骤保持一致:

```json
{"metric": 8.1,
"breakdown": {"attention": 4.0, "norm": 0.1, "other": 4.0},
"counters": {"kernel_launches": 20, "dram_bytes": 8.0e8}}
```

每轮可以用 `--mechanism-file` 声明机制和可核对的预期特征:

```json
{"mechanism": "把 norm 融合进 attention 的 epilogue,少一次 HBM 往返",
"expect": [{"region": "norm", "direction": "decrease"},
{"region": "attention", "direction": "unchanged"},
{"counter": "kernel_launches", "direction": "decrease"}]}
```

assessment 的 `profile_evidence` 按重复配对比较每个区域和计数,`raw` 保留原始比值。声明为 `unchanged` 的区域是本轮的假设,不是结论:其他区域另外给出除以同一步骤参照区域总和后的 `normalized` 比较,`share_based_speedup` 用参照区域在步骤总时间中的占比推算整体加速。只有当某种变化让同一步骤的所有区域按同一比例缩放时,它才会被抵消;若各区域受影响程度不同(例如降频对计算受限和访存受限的区域影响不同),抵消就不成立。参照区域本身始终只做原始比较,不会互相归一化,因此整体漂移较大时它可能显示为变化,使解释判为矛盾。计数一类的工作量指标基本不随时钟和温度变化,可以说明波动范围内的小幅改进是否可重复。方向只由配对区间判断(区间整体低于或高于 1),仓库内没有设置数值容差;基线为 0 的计数没有比值,记为 `undefined`。`profile_evidence` 只描述数据,不判断机制文字本身。

`explanation.status` 取值:`explained`(每条预期都被数据确认,且至少一条是变化)、`unsupported`(预期的变化没有在数据中出现)、`contradicted`(数据与预期方向相反,或声明不变的项出现明显变化)、`unverifiable`(缺少对应区域或计数、比值无定义,或少于 5 对)、`not_declared`(本轮未声明)。机制声明在执行前绑定:判定使用执行前保存的声明,并核对其摘要与 attempt 目录中的 `mechanism.json`;副本被改动时按完整性错误阻断 campaign。执行后被中断、经 `recover` 结算的轮次无法证明执行前绑定的是哪份声明,因此按未声明处理(记录 `mechanism_unverified_after_recovery`),在 `--require-explanation` 下不会被采纳。final 沿用被选中轮次绑定的机制重新核对。

两个开关在 `campaign start` 时冻结,默认都不改变原有判定:

- `--require-explanation`:只有 `explained` 的候选可以被采纳。`unsupported`、`contradicted` 记为 FAIL,`unverifiable`、`not_declared` 记为 INCONCLUSIVE;两类都不阻塞后续轮次。
- `--decision paired`:用 `paired_statistics` 判定,要求至少 5 次重复。区间整体高于门槛为 PASS;跨过门槛为 FAIL,`reason` 为 `within_noise`,搜索继续;统计不可用时为 INCONCLUSIVE。默认 `point` 保持中位数点估计规则。

提交未修改的候选可以作为 A/A 对照,`paired_statistics` 的区间即给出该环境的噪声范围。

## 实际保留什么、保护什么

`campaign.json` 关联计划,`plan.json` 固定协议、预算和候选格式,`state.json` 是唯一可写控制状态。`summary.json` 是可重建摘要,dashboard 从同一记录生成展示;不额外写一份 `rounds.jsonl`。原有知识交付和优化日志格式继续复用。
Expand Down
8 changes: 8 additions & 0 deletions src/inferrsi/arguments.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,12 @@ def _optimization_actions(stages, *, project=False):
start.add_argument("--min-improvement-pct", type=float, required=True)
start.add_argument("--repetitions", type=int, required=True)
start.add_argument("--warmups", type=int, required=True)
start.add_argument("--decision", choices=("point", "paired"), default="point",
help="point: independent medians (default); paired: the paired "
"interval must clear the gate, within-noise rounds fail")
start.add_argument("--require-explanation", action="store_true",
help="Adopt a candidate only when its declared mechanism is "
"confirmed by measured breakdown/counters")
start.add_argument("--round-mode", choices=("exact", "up_to"), default="up_to")
else:
start.add_argument("task")
Expand All @@ -89,6 +95,8 @@ def _optimization_actions(stages, *, project=False):
if name == "round":
stage.add_argument("--candidate", type=Path, required=True)
stage.add_argument("--hypothesis", required=True)
stage.add_argument("--mechanism-file", type=Path,
help="JSON mechanism with expected region/counter directions")
if name == "final":
stage.add_argument("--reason", help="Why the caller stopped an up-to-budget search")
if name in ("round", "final"):
Expand Down
Loading
Loading