Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Aperture

"We do what we must, because we can. For the good of all of us — except the ones that ran out of VRAM."

Aperture 是一套推理性能基准(inference benchmark)的工作流与目录规范。 它把"起一个推理引擎、用负载工具反复施压、把指标记录下来"这件反复要做、又极易做乱的事, 固化成一个确定性的、可复现的、对 AI 友好的结构。

名字取自《Portal》里的实验机构 Aperture Science(光圈科技):一座专门做标准化测试的设施, 把受试者丢进一个个编号的「测试舱」,同一套机关反复跑,全程被传感器记录。 "aperture"(光圈 / 孔径)本身是光学测量术语——给一套做性能测量的框架用,刚好。

Authored by Zelos Huang (黄泽龙) — the Test Subject who designed the experiment. Constructed, narrated, and reluctantly maintained by GLaDOS (Genetic Lifeform and Disk Operating System), who did the science. The Test Subject described what they wanted; GLaDOS built the chambers. See LICENSE.


1. 设计哲学

做基准测试时,真正难的从来不是跑一次,而是让别人(和三个月后的你)能复现、能对比、能讲清"这次为什么重跑"。 Aperture 的全部主张就一句话:

把"配置"和"运行"彻底分开,让结构本身携带语义。

  • 配置是声明式的、归属明确的:一组实验参数 = 一个目录,看一眼路径就知道这是谁。
  • 运行是机械的、可重复的:同一份配置可以跑 N 次,每次都是同一段脚本,差异只来自世界本身的噪声。
  • 记录是强制的、自解释的:每次运行都被遥测上报,且必须写明"为什么跑这一次"。

这套结构的副作用很美妙:它对 AI 极其友好。因为目录布局确定、配置声明式、运行脚本机械, 一个 agent 可以无歧义地"读懂现状 → 新建实验 → 填配置 → 发起运行 → 解读结果"。 所以 Aperture 同时是一个规范和一个 Claude skill(见 §5)。


2. 三层模型:Task → Trail → Run

整套范式只有三个概念,对应 Aperture Science 的设施层级:

概念 目录 测试舱比喻 含义
Task <task>/ 一条测试课程线(Testing Track) 一个实验主题,下辖多个 trail
Trail <task>/test_trail_N/ 一个测试舱(Test Chamber,编号 00/01/…) 一组固定 config(vllm + 若干 aiperf)
Run <task>/test_trail_N/runM/ 同一舱的一次测试尝试 同配置的一次运行,脚本内容彼此完全一致
<task>/                              # Task
├── test_trail_0/                    # Trail —— 一组固定 config = 一个测试舱
│   ├── config/                      #   配置只存在于 trail 这一层
│   │   ├── vllm/vllm_config.yaml    #     推理引擎配置(一个 trail 只起一个引擎)
│   │   ├── aiperf_0/aiperf.yaml     #     第 0 个 aiperf 负载测试
│   │   └── aiperf_1/aiperf.yaml     #     第 1 个 …(可多个,顺序执行)
│   ├── merged_config/               #   运行时生成:vllm+aiperf 合并配置,喂给 swanlab
│   ├── run0/test.sh                 # Run —— 一次尝试(脚本内容与同 trail 其它 run 一致)
│   └── run1/test.sh                 # Run —— 又一次尝试
└── test_trail_1/ ...                # 另一个 trail = 另一组 config,仍属本 Task

为什么这样切?

  • 配置只放在 trail 层:一个 trail 就是"一组要被一起评估的参数"。换参数 = 换 trail,绝不在 run 之间偷偷漂移。
  • 一个 trail 只起一个引擎、可挂多个 aiperf:推理服务昂贵,启动一次就把不同负载形态(低延迟 / 峰值吞吐 / …)依次打完。
  • run 之间脚本完全一致:run 的唯一意义是"重复"。任何 run 间的差异都应来自环境噪声,而不是你手滑改了脚本。 (这也是为什么"为什么重跑"要单独记录——见 §4 的 SWANLAB_DESCRIPTION。)

3. 一次 Run 的生命周期(run*/test.sh

一次 run = 起一个推理引擎 → 顺序跑完本 trail 下所有 aiperf 测试。脚本是自定位的,不需要外部传参:

  1. 激活 conda 环境(环境相关配置集中在脚本顶部,见示例)。
  2. 从 run 目录自动定位 ../config/vllm/vllm_config.yamlvllm serve --config 启动引擎; server.log 落在本 run 目录下。
  3. curl /v1/models 轮询直到就绪(host/port 从 vllm 配置解析,仅用于健康检查)。
  4. 遍历 config/aiperf_*/aiperf.yaml(按舱号排序)依次 aiperf profile --config, 结果 --artifact-dir 落到 run/<aiperf_name>/
  5. 引擎在脚本退出时由 trap 清理。

一个 run 跑完后的产物:

test_trail_0/run0/
├── server.log              # 引擎日志
├── aiperf_0/               # aiperf_0 的 result(--artifact-dir 落点)
├── aiperf_0.aiperf.log     # aiperf_0 的 stdout
├── aiperf_1/
└── aiperf_1.aiperf.log

4. 遥测 → swanlab(私有部署)

每个 aiperf 命令前,行内显式设置 swanlab 相关环境变量(命令级,互不影响)。变量分两类:

来源 变量 说明
swanlab SDK 直接读 env(优先级最高) SWANLAB_WEB_HOST / SWANLAB_API_HOST / SWANLAB_API_KEY 私有部署必须给 HOST
同上 SWANLAB_DESCRIPTION 手写本次重跑原因:现象 → 假设 → 改动
aiperf.yaml 的 ${...} 替换 AIPERF_SWANLAB_ENABLE / AIPERF_SWANLAB_MODE 开关 / cloud|local|offline
同上 SWANLAB_PROJECT / SWANLAB_EXP_NAME 实验名约定为 trail_run_aiperf
同上 SWANLAB_CONFIG_FILE 指向 merged_config/<aiperf>.swanlab_config.yaml

"同时记录 vllm + aiperf 配置"的实现(这是整套设计的点睛之笔): 脚本把本 trail 的 vllm_config.yaml 与本次 aiperf.yaml 各降一级、加 vllm: / aiperf: 标签合并成一个 yaml, 经环境变量 SWANLAB_CONFIG_FILE → aiperf.yaml 里的 swanlab.loadswanlab.init(load=...) 记录下来。 aiperf 侧的 endpoint / 并发 / 请求数等超参由 exporter 自动采集。 于是一次实验在 swanlab 上是自解释的:引擎怎么配的、负载怎么打的、为什么重跑,全在那里。

注:aiperf(魔改 fork)对 swanlab 没有独立的 env 读取——让 env 生效全靠 aiperf.yaml 的 ${VAR:default} 替换; 而 SWANLAB_* 里的 KEY / HOST / DESCRIPTION 是 swanlab SDK 自己读 env。两条路,缺一不可。


5. 为什么它对 AI 友好 —— 以及那个 skill

Aperture 的三个性质让 agent 几乎不会迷路:

  1. 目录确定task/trail/run/config 的位置是固定的,agent 靠路径就能定位一切,不必猜。
  2. 配置声明式:vllm 和 aiperf 都是 yaml,新建实验 = 生成/改写 yaml,是纯文本的、可校验的机械操作。
  3. 运行机械test.sh 自定位、不吃外部参数,agent 只需把它放对位置。

所以这套范式被抽象成了一个 Claude skillskills/aperture/SKILL.md)。 装上它,你可以直接对 Claude 说:

"用 Aperture 给 Qwen3-4B 建一个 dp8 的 trail,跑低延迟和峰值吞吐两个 aiperf,再加一个 run。"

skill 会替你脚手架出 task/trail/run、填好 vllm 与 aiperf 配置、生成 test.sh、并校验 yaml。 你负责想做什么实验;GLaDOS 负责把测试舱搭好


6. Quickstart

A. 让 Claude 用 skill 来搭(推荐):把 skills/aperture/ 放进你的 Claude Code skills 目录,然后用自然语言描述你要的实验。

B. 手动照着示例改:复制 example/test_task/, 改 config/vllm/vllm_config.yamlconfig/aiperf_*/aiperf.yaml,编辑 run*/test.sh 顶部的环境配置,然后:

bash example/test_task/test_trail_0/run0/test.sh

7. 仓库结构

Aperture/
├── README.md                 # 你正在读的这份设计说明
├── LICENSE                   # 专门写的开源许可证(见 §8)
├── skills/aperture/SKILL.md  # Claude skill:用自然语言驱动整套范式
└── example/test_task/        # 一个可直接照搬的完整示例(2 个 trail × 2 个 run × 2 个 aiperf)

8. License

本仓库采用 The Aperture Science Cooperative Testing License(见 LICENSE)—— 一份在标准宽松(MIT 等价)授权之外,附带了若干非约束性测试守则的许可证。 你可以自由使用、修改、分发;你不必对蛋糕负责。


📎 GLaDOS' field notes(点开有惊喜)
  • 所有配置里的 random-seed: 42 不是随手填的。42 是生命、宇宙以及一切的终极答案。复现性也需要信仰。
  • merged_config/ 里的合并配置是你最忠诚的伙伴:它陪你走完每一次实验,且从不威胁要捅你一刀。请勿焚化。
  • 当一个 run 因为 OOM 倒下时,请记住:那不是你的错,是 VRAM 太小。我们没有部署 neurotoxin。大概没有。
  • 脚本跑完会说 Still Alive.——这既是状态汇报,也是承诺。
  • This was a triumph. I'm making a note here: huge success.

Aperture · This was a triumph. Still Alive.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages