airas-eval 0.3.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- airas_eval-0.3.0/.github/workflows/ci.yml +34 -0
- airas_eval-0.3.0/.github/workflows/publish.yml +37 -0
- airas_eval-0.3.0/.gitignore +9 -0
- airas_eval-0.3.0/LICENSE +21 -0
- airas_eval-0.3.0/PKG-INFO +236 -0
- airas_eval-0.3.0/README.md +209 -0
- airas_eval-0.3.0/examples/README.md +12 -0
- airas_eval-0.3.0/examples/nas_post_training.json +113 -0
- airas_eval-0.3.0/examples/nas_pre_training.json +63 -0
- airas_eval-0.3.0/pyproject.toml +79 -0
- airas_eval-0.3.0/src/airas_eval/__init__.py +7 -0
- airas_eval-0.3.0/src/airas_eval/cli.py +75 -0
- airas_eval-0.3.0/src/airas_eval/evaluator.py +231 -0
- airas_eval-0.3.0/src/airas_eval/exceptions.py +24 -0
- airas_eval-0.3.0/src/airas_eval/metrics/__init__.py +17 -0
- airas_eval-0.3.0/src/airas_eval/metrics/_validate.py +51 -0
- airas_eval-0.3.0/src/airas_eval/metrics/classification.py +129 -0
- airas_eval-0.3.0/src/airas_eval/metrics/pareto.py +124 -0
- airas_eval-0.3.0/src/airas_eval/metrics/population.py +72 -0
- airas_eval-0.3.0/src/airas_eval/metrics/regression.py +87 -0
- airas_eval-0.3.0/src/airas_eval/metrics/search.py +113 -0
- airas_eval-0.3.0/src/airas_eval/metrics/selection.py +106 -0
- airas_eval-0.3.0/src/airas_eval/py.typed +0 -0
- airas_eval-0.3.0/src/airas_eval/spec.py +218 -0
- airas_eval-0.3.0/src/airas_eval/tasks/__init__.py +36 -0
- airas_eval-0.3.0/src/airas_eval/tasks/_bundles.py +466 -0
- airas_eval-0.3.0/src/airas_eval/tasks/_inputs.py +96 -0
- airas_eval-0.3.0/src/airas_eval/tasks/generic/README.md +138 -0
- airas_eval-0.3.0/src/airas_eval/tasks/generic/__init__.py +17 -0
- airas_eval-0.3.0/src/airas_eval/tasks/generic/binary_classification.py +10 -0
- airas_eval-0.3.0/src/airas_eval/tasks/generic/candidate_ranking.py +9 -0
- airas_eval-0.3.0/src/airas_eval/tasks/generic/classification.py +9 -0
- airas_eval-0.3.0/src/airas_eval/tasks/generic/multiobjective.py +9 -0
- airas_eval-0.3.0/src/airas_eval/tasks/generic/search.py +9 -0
- airas_eval-0.3.0/src/airas_eval/tasks/nas/README.md +123 -0
- airas_eval-0.3.0/src/airas_eval/tasks/nas/__init__.py +14 -0
- airas_eval-0.3.0/src/airas_eval/tasks/nas/_bundles.py +232 -0
- airas_eval-0.3.0/src/airas_eval/tasks/nas/_inputs.py +75 -0
- airas_eval-0.3.0/src/airas_eval/tasks/nas/post_training.py +20 -0
- airas_eval-0.3.0/src/airas_eval/tasks/nas/pre_training.py +22 -0
- airas_eval-0.3.0/src/airas_eval/tasks/readme.py +104 -0
- airas_eval-0.3.0/tests/test_classification.py +106 -0
- airas_eval-0.3.0/tests/test_cli.py +67 -0
- airas_eval-0.3.0/tests/test_evaluator.py +370 -0
- airas_eval-0.3.0/tests/test_pareto.py +89 -0
- airas_eval-0.3.0/tests/test_population.py +45 -0
- airas_eval-0.3.0/tests/test_regression.py +86 -0
- airas_eval-0.3.0/tests/test_search.py +55 -0
- airas_eval-0.3.0/tests/test_selection.py +68 -0
- airas_eval-0.3.0/tests/test_spec.py +135 -0
- airas_eval-0.3.0/tests/test_tasks_readme.py +21 -0
- airas_eval-0.3.0/uv.lock +633 -0
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
test:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
strategy:
|
|
12
|
+
matrix:
|
|
13
|
+
python-version: ["3.10", "3.11", "3.12"]
|
|
14
|
+
steps:
|
|
15
|
+
- uses: actions/checkout@v5
|
|
16
|
+
- uses: astral-sh/setup-uv@v6
|
|
17
|
+
with:
|
|
18
|
+
python-version: ${{ matrix.python-version }}
|
|
19
|
+
- name: Sync dependencies (locked)
|
|
20
|
+
run: uv sync --frozen
|
|
21
|
+
- name: Lint
|
|
22
|
+
run: uv run ruff check .
|
|
23
|
+
- name: Format check
|
|
24
|
+
run: uv run ruff format --check .
|
|
25
|
+
- name: Type check
|
|
26
|
+
run: uv run mypy src
|
|
27
|
+
- name: Test
|
|
28
|
+
run: uv run pytest -q
|
|
29
|
+
- name: Build and smoke-test the wheel as a consumer would
|
|
30
|
+
run: |
|
|
31
|
+
uv build
|
|
32
|
+
uvx --from dist/*.whl airas-eval list
|
|
33
|
+
uvx --from dist/*.whl airas-eval score nas_pre_training --inputs examples/nas_pre_training.json
|
|
34
|
+
uvx --from dist/*.whl airas-eval score nas_post_training --inputs examples/nas_post_training.json
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
name: Publish
|
|
2
|
+
|
|
3
|
+
# Manual for now (PyPI Trusted Publisher not configured yet). Once it is,
|
|
4
|
+
# switch the trigger to `push: tags: ["v*"]`.
|
|
5
|
+
on:
|
|
6
|
+
workflow_dispatch:
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
build:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
steps:
|
|
12
|
+
- uses: actions/checkout@v5
|
|
13
|
+
- uses: astral-sh/setup-uv@v6
|
|
14
|
+
- name: Check tag matches package version
|
|
15
|
+
run: |
|
|
16
|
+
version=$(uv version --short)
|
|
17
|
+
git fetch --tags --quiet
|
|
18
|
+
git tag --points-at HEAD | grep -qx "v$version" || { echo "HEAD is not tagged v$version"; exit 1; }
|
|
19
|
+
- run: uv build
|
|
20
|
+
- uses: actions/upload-artifact@v4
|
|
21
|
+
with:
|
|
22
|
+
name: dist
|
|
23
|
+
path: dist/
|
|
24
|
+
|
|
25
|
+
publish:
|
|
26
|
+
needs: build
|
|
27
|
+
runs-on: ubuntu-latest
|
|
28
|
+
environment: pypi
|
|
29
|
+
permissions:
|
|
30
|
+
id-token: write # PyPI Trusted Publisher (no API token)
|
|
31
|
+
steps:
|
|
32
|
+
- uses: actions/download-artifact@v4
|
|
33
|
+
with:
|
|
34
|
+
name: dist
|
|
35
|
+
path: dist/
|
|
36
|
+
- uses: astral-sh/setup-uv@v6
|
|
37
|
+
- run: uv publish
|
airas_eval-0.3.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 airas-org
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: airas-eval
|
|
3
|
+
Version: 0.3.0
|
|
4
|
+
Summary: Trusted evaluation layer for AIRAS: the full fixed set of standard metrics per task type, computed from raw predictions
|
|
5
|
+
Project-URL: Homepage, https://github.com/airas-org/airas-eval
|
|
6
|
+
Project-URL: Repository, https://github.com/airas-org/airas-eval
|
|
7
|
+
Project-URL: Issues, https://github.com/airas-org/airas-eval/issues
|
|
8
|
+
Author: airas-org
|
|
9
|
+
License-Expression: MIT
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Keywords: ai-scientist,evaluation,metrics,neural-architecture-search,reproducibility
|
|
12
|
+
Classifier: Development Status :: 3 - Alpha
|
|
13
|
+
Classifier: Intended Audience :: Science/Research
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
20
|
+
Classifier: Typing :: Typed
|
|
21
|
+
Requires-Python: <3.13,>=3.10
|
|
22
|
+
Requires-Dist: numpy>=1.26
|
|
23
|
+
Requires-Dist: pydantic>=2.7
|
|
24
|
+
Requires-Dist: scikit-learn>=1.5
|
|
25
|
+
Requires-Dist: scipy>=1.11
|
|
26
|
+
Description-Content-Type: text/markdown
|
|
27
|
+
|
|
28
|
+
# airas-eval
|
|
29
|
+
|
|
30
|
+
[AIRAS](https://github.com/airas-org/airas) のための信頼できる評価層。
|
|
31
|
+
エージェントはタスクタイプと生の予測結果を渡し、その研究種別で報告すべき標準的な
|
|
32
|
+
評価指標一式を固定された形で受け取る。エージェントは評価スクリプトを実装せず、
|
|
33
|
+
どの指標を(どの variant で)報告するかも選ばない。
|
|
34
|
+
|
|
35
|
+
## 構成
|
|
36
|
+
|
|
37
|
+
2 層構造で、その間に呼び出し側が選べるものはない。
|
|
38
|
+
|
|
39
|
+
1. **`metrics/`** — 評価指標の実装。入力の形ごとに 1 モジュールで、タスクの知識を
|
|
40
|
+
持たない。標準実装(scikit-learn / scipy)があるものはそれに委譲し、存在しない
|
|
41
|
+
もの(ECE、リグレット、上位 k 選択、2 目的ハイパーボリューム、IGD/GD/spacing)
|
|
42
|
+
だけを自前で実装して variant を固定し、性質テストで検証している。
|
|
43
|
+
2. **`tasks/`** — エリアごとに 1 サブパッケージ、タスクタイプごとに 1 モジュール。
|
|
44
|
+
タスクタイプとは「その種類の研究が報告すべき指標の全集合」で、検証済みの入力
|
|
45
|
+
グループから計算される(グループあたり 5〜12 指標、スカラーまたは曲線、variant は
|
|
46
|
+
すべて固定)。`generic/` が基本となる評価ファミリー、エリアパッケージ(`nas/`)
|
|
47
|
+
はその上に積む — エリアのバンドルは *基本のバインディング + その分野の文献が
|
|
48
|
+
追加するもの* であり、名前を変えた複製ではない。再利用部品
|
|
49
|
+
(`tasks/_bundles.py`, `tasks/nas/_bundles.py`)は単なる定数で、登録も単独評価も
|
|
50
|
+
されない。
|
|
51
|
+
|
|
52
|
+
```
|
|
53
|
+
tasks/
|
|
54
|
+
├── generic/ classification, binary_classification, search, candidate_ranking, multiobjective
|
|
55
|
+
└── nas/ nas_pre_training = search(+ wall-clock 軸、探索空間内順位、ランダム探索
|
|
56
|
+
│ ベースライン)と predictor(candidate_ranking + 上位 10% 相関)
|
|
57
|
+
└── nas_post_training = architecture(classification + ランダムアーキテクチャ比、
|
|
58
|
+
テストリグレット)と tradeoff(multiobjective)
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
NAS は「アーキテクチャの性能をいつ測るか」で 2 タスクに分かれる:
|
|
62
|
+
|
|
63
|
+
| タスクタイプ | 測るもの | グループ |
|
|
64
|
+
|---|---|---|
|
|
65
|
+
| `nas_pre_training` | 学習前のアーキテクチャ性能 — ベンチマーク参照による探索、性能予測器、ゼロコストプロキシ | `search`(任意)、`predictor`(任意)。少なくとも 1 つ |
|
|
66
|
+
| `nas_post_training` | 学習後のアーキテクチャ性能 — 選ばれて学習された最終アーキテクチャ | `architecture`(必須)、`tradeoff`(任意) |
|
|
67
|
+
|
|
68
|
+
## 各タスクは何を返すか(指標の説明)
|
|
69
|
+
|
|
70
|
+
どちらも登録情報から導出されるので、実装と食い違うことがない:
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
airas-eval list # 全タスクタイプ: 入力、指標、曲線、入力サイズ、署名
|
|
74
|
+
airas-eval list nas_post_training # 1 タスクタイプ
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
および、エリアごとに生成される README(テストで同期を検証):
|
|
78
|
+
|
|
79
|
+
- [`tasks/generic/README.md`](src/airas_eval/tasks/generic/README.md) — 汎用の評価ファミリー
|
|
80
|
+
- [`tasks/nas/README.md`](src/airas_eval/tasks/nas/README.md) — NAS の 2 タスク
|
|
81
|
+
|
|
82
|
+
**各指標の説明(定義、読み方、高低どちらが良いか)はこれらの README の表に載っている。**
|
|
83
|
+
タスクやバンドルを変更したら `python -m airas_eval.tasks.readme` で再生成する。
|
|
84
|
+
|
|
85
|
+
## 使い方
|
|
86
|
+
|
|
87
|
+
```python
|
|
88
|
+
from airas_eval import evaluate
|
|
89
|
+
|
|
90
|
+
report = evaluate(
|
|
91
|
+
"nas_post_training",
|
|
92
|
+
{
|
|
93
|
+
"architecture": {
|
|
94
|
+
"predicted_labels": y_pred,
|
|
95
|
+
"reference_labels": y_true,
|
|
96
|
+
"probabilities": probs, # 任意
|
|
97
|
+
"oracle_test_best": 0.9437, # 任意: ベンチマークのテスト最適値(0〜1)
|
|
98
|
+
},
|
|
99
|
+
"tradeoff": { # 任意グループ
|
|
100
|
+
"points": [[error, macs], ...], # 全目的を最小化
|
|
101
|
+
"reference_point": [0.2, 1e9],
|
|
102
|
+
},
|
|
103
|
+
},
|
|
104
|
+
)
|
|
105
|
+
report.metrics # スカラー指標: {"architecture.accuracy": ..., "tradeoff.hypervolume_2d": ...}
|
|
106
|
+
report.curves # 曲線指標: {"tradeoff.pareto_front": [...]}
|
|
107
|
+
report.inputs_summary # 指標ではない — 入力サイズ: {"architecture.n_examples": 10000, ...}
|
|
108
|
+
report.skipped # 計算できなかった指標 — 機械可読なコード + 理由
|
|
109
|
+
report.omitted_optional_inputs # 例: ["architecture.random_architecture_accuracies"]
|
|
110
|
+
report.provenance # 導出されたタスク署名、依存パッケージの版、入力の SHA-256
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
airas-eval score nas_pre_training --inputs inputs.json --output evaluation.json
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
`examples/` に NAS 各タスクの最小入力ファイルがあり、テストスイートがそれぞれを CLI
|
|
118
|
+
で採点する。NAS 固有の入力(`evaluation_costs`, `search_space_scores`,
|
|
119
|
+
`random_architecture_accuracies`, `oracle_test_best`, ...)は任意の参照データで、
|
|
120
|
+
省略するとそれを必要とする指標は skipped として報告され、省略自体も記録される。
|
|
121
|
+
|
|
122
|
+
入力は常にグループ化されている(`{"architecture": {...}}`)。呼び出し側が選べるのは
|
|
123
|
+
タスクタイプだけで、研究をどのタスクタイプで評価するかは研究計画側が決める
|
|
124
|
+
(評価ステップではない)。NAS では、探索ステージの後に `nas_pre_training`、
|
|
125
|
+
最終アーキテクチャの学習後に `nas_post_training` を呼ぶ、というパイプラインの段階が
|
|
126
|
+
それに対応する。
|
|
127
|
+
|
|
128
|
+
## 設計ルール
|
|
129
|
+
|
|
130
|
+
1. **指標を選ばせない。** タスクタイプは自分の指標を*すべて*計算する。集合は固定で、
|
|
131
|
+
読み切れる大きさに保つ(長い一覧はそれ自体がチェリーピックの余地になる)。
|
|
132
|
+
variant(平均方法、k、ビン数)はタスクごとに固定され、指標関数が取る全パラメータは
|
|
133
|
+
明示的に固定される(テストで強制)。入力サイズ(`n_examples`, `n_evaluations`, ...)
|
|
134
|
+
は指標とは別に `inputs_summary` に報告され、テスト集合の部分抽出や打ち切られた
|
|
135
|
+
探索が見えるようにする。
|
|
136
|
+
2. **黙って消えるものはない。** 計算できなかった指標は `skipped` に機械可読なコード
|
|
137
|
+
(`missing_optional_input`, `not_applicable`, `undefined_on_data`,
|
|
138
|
+
`missing_dependency`)付きで現れ、省略された任意入力もレポートごとに列挙される。
|
|
139
|
+
skip になるのはこれらの専用ケースだけで、不正な入力やライブラリのバグは
|
|
140
|
+
「未定義」に隠れず例外で失敗する。
|
|
141
|
+
3. **来歴は手書きせず導出する。** タスク署名はタスク宣言(指標名、関数の識別子、
|
|
142
|
+
固定 kwargs、入力フィールド)のハッシュなので、実装と乖離できない。エリアごとの
|
|
143
|
+
README も同じ宣言から生成される。
|
|
144
|
+
4. **参照データは上流で固定する。** `reference_labels`、`oracle_best`、
|
|
145
|
+
`oracle_test_best`、参照点・参照フロントは実験設計に属する。このライブラリはそれ
|
|
146
|
+
らが本物であることを検証できず、エージェントが制御するプロセスの中では自衛でき
|
|
147
|
+
ない — `airas-eval score` をエージェントが編集できない固定環境から実行すること。
|
|
148
|
+
|
|
149
|
+
## インストール
|
|
150
|
+
|
|
151
|
+
```bash
|
|
152
|
+
uv add "airas-eval==0.3.0" # ライブラリ/CLI として
|
|
153
|
+
uvx airas-eval@0.3.0 list # インストールせずに CLI だけ使う
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
評価層が研究の途中で変わらないように、必ずバージョンを固定する。依存: numpy,
|
|
157
|
+
scikit-learn, scipy, pydantic。
|
|
158
|
+
|
|
159
|
+
## 研究リポジトリからの呼び出し方
|
|
160
|
+
|
|
161
|
+
agent の実験コードは **airas_eval を import しない**。agent の成果物は評価の
|
|
162
|
+
**入力ファイル**(`evaluate` に渡す dict をそのまま JSON にしたもの)までで、評価は
|
|
163
|
+
固定版の CLI を別プロセスで走らせる。研究リポジトリには airas(オーケストレータ)の
|
|
164
|
+
テンプレート由来で次が置かれる:
|
|
165
|
+
|
|
166
|
+
```toml
|
|
167
|
+
# pyproject.toml — 依存として固定するが、実験コードからは import しない
|
|
168
|
+
[dependency-groups]
|
|
169
|
+
eval = ["airas-eval==0.3.0"]
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
```makefile
|
|
173
|
+
# Makefile — task_type と入出力先は研究計画から埋める
|
|
174
|
+
evaluate:
|
|
175
|
+
uv run --group eval airas-eval score nas_pre_training \
|
|
176
|
+
--inputs artifacts/eval_inputs/nas_pre_training.json \
|
|
177
|
+
--output artifacts/evaluation/nas_pre_training.json
|
|
178
|
+
uv run --group eval airas-eval score nas_post_training \
|
|
179
|
+
--inputs artifacts/eval_inputs/nas_post_training.json \
|
|
180
|
+
--output artifacts/evaluation/nas_post_training.json
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
agent は `make evaluate` を実行してスコアを確認しながら実験を進めてよい。ただし
|
|
184
|
+
Makefile は agent が書き換え得るので、**公式のスコアはオーケストレータが agent の
|
|
185
|
+
触れない環境で、同じ版の CLI を入力ファイルに直接かけて再計算したもの**とする。
|
|
186
|
+
report の `inputs_sha256` と入力ファイルの hash、`provenance.versions` の版を照合すれば、
|
|
187
|
+
どの入力をどの版で採点したかが確認できる。第三者は clone → `uv sync --group eval` →
|
|
188
|
+
`make evaluate` で同じ数字を再現できる(`uv.lock` が版を固定する)。
|
|
189
|
+
|
|
190
|
+
## リリース手順
|
|
191
|
+
|
|
192
|
+
公開は GitHub Actions の `publish.yml`(PyPI Trusted Publisher、API トークン不要)で行う。
|
|
193
|
+
|
|
194
|
+
初回のみ、PyPI 側の設定が必要:
|
|
195
|
+
|
|
196
|
+
1. https://pypi.org/manage/account/publishing/ で **pending publisher** を登録する —
|
|
197
|
+
PyPI project name `airas-eval`、owner `airas-org`、repository `airas-eval`、
|
|
198
|
+
workflow `publish.yml`、environment `pypi`。
|
|
199
|
+
2. GitHub リポジトリの Settings → Environments に `pypi` を作る(承認者を付けてもよい)。
|
|
200
|
+
|
|
201
|
+
毎回のリリース:
|
|
202
|
+
|
|
203
|
+
```bash
|
|
204
|
+
uv version --bump minor # pyproject と __init__ の版を揃える(現状は手動で両方)
|
|
205
|
+
uv lock && uv run pytest -q
|
|
206
|
+
git commit -am "release: v0.3.0" && git tag v0.3.0 && git push --tags
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
その後 Actions から `Publish` を手動実行する(HEAD にその版のタグが付いていることを
|
|
210
|
+
ワークフローが検証する)。Trusted Publisher が動くことを確認したら、`publish.yml` の
|
|
211
|
+
トリガーを `push: tags: ["v*"]` に切り替えてタグ push だけで公開できるようにする。
|
|
212
|
+
|
|
213
|
+
## 開発
|
|
214
|
+
|
|
215
|
+
```bash
|
|
216
|
+
uv sync
|
|
217
|
+
uv run ruff format --check .
|
|
218
|
+
uv run ruff check .
|
|
219
|
+
uv run mypy src
|
|
220
|
+
uv run pytest
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
タスクタイプの追加 = `tasks/<area>/` に既存バンドルから `TASK` を定義するモジュールを
|
|
224
|
+
1 つ置き、エリアの `TASKS` に 1 行足し、`python -m airas_eval.tasks.readme` を実行。
|
|
225
|
+
新しいエリア = 新しいサブパッケージ + `tasks.AREAS` に 1 行。バンドルの追加 =
|
|
226
|
+
`tasks/_inputs.py` の入力モデルと `tasks/_bundles.py` の `Bundle`(`summary` の件数
|
|
227
|
+
付き)。各バインディングには日本語の `description` が必須(テストで強制)。タスクは
|
|
228
|
+
5〜10 指標程度に保つ: 標準的な variant のみ、パラメータごとに 1 つの固定値。
|
|
229
|
+
|
|
230
|
+
登録は意図的に明示的(entry point もスキャンもしない): 信頼層では、何が計算される
|
|
231
|
+
かがレビュー済みの差分に見えていなければならない。自前実装の指標を追加する場合は、
|
|
232
|
+
オラクル実装とのパリティテスト、または手計算ケース + 性質テストが必要。
|
|
233
|
+
|
|
234
|
+
## ライセンス
|
|
235
|
+
|
|
236
|
+
MIT
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
# airas-eval
|
|
2
|
+
|
|
3
|
+
[AIRAS](https://github.com/airas-org/airas) のための信頼できる評価層。
|
|
4
|
+
エージェントはタスクタイプと生の予測結果を渡し、その研究種別で報告すべき標準的な
|
|
5
|
+
評価指標一式を固定された形で受け取る。エージェントは評価スクリプトを実装せず、
|
|
6
|
+
どの指標を(どの variant で)報告するかも選ばない。
|
|
7
|
+
|
|
8
|
+
## 構成
|
|
9
|
+
|
|
10
|
+
2 層構造で、その間に呼び出し側が選べるものはない。
|
|
11
|
+
|
|
12
|
+
1. **`metrics/`** — 評価指標の実装。入力の形ごとに 1 モジュールで、タスクの知識を
|
|
13
|
+
持たない。標準実装(scikit-learn / scipy)があるものはそれに委譲し、存在しない
|
|
14
|
+
もの(ECE、リグレット、上位 k 選択、2 目的ハイパーボリューム、IGD/GD/spacing)
|
|
15
|
+
だけを自前で実装して variant を固定し、性質テストで検証している。
|
|
16
|
+
2. **`tasks/`** — エリアごとに 1 サブパッケージ、タスクタイプごとに 1 モジュール。
|
|
17
|
+
タスクタイプとは「その種類の研究が報告すべき指標の全集合」で、検証済みの入力
|
|
18
|
+
グループから計算される(グループあたり 5〜12 指標、スカラーまたは曲線、variant は
|
|
19
|
+
すべて固定)。`generic/` が基本となる評価ファミリー、エリアパッケージ(`nas/`)
|
|
20
|
+
はその上に積む — エリアのバンドルは *基本のバインディング + その分野の文献が
|
|
21
|
+
追加するもの* であり、名前を変えた複製ではない。再利用部品
|
|
22
|
+
(`tasks/_bundles.py`, `tasks/nas/_bundles.py`)は単なる定数で、登録も単独評価も
|
|
23
|
+
されない。
|
|
24
|
+
|
|
25
|
+
```
|
|
26
|
+
tasks/
|
|
27
|
+
├── generic/ classification, binary_classification, search, candidate_ranking, multiobjective
|
|
28
|
+
└── nas/ nas_pre_training = search(+ wall-clock 軸、探索空間内順位、ランダム探索
|
|
29
|
+
│ ベースライン)と predictor(candidate_ranking + 上位 10% 相関)
|
|
30
|
+
└── nas_post_training = architecture(classification + ランダムアーキテクチャ比、
|
|
31
|
+
テストリグレット)と tradeoff(multiobjective)
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
NAS は「アーキテクチャの性能をいつ測るか」で 2 タスクに分かれる:
|
|
35
|
+
|
|
36
|
+
| タスクタイプ | 測るもの | グループ |
|
|
37
|
+
|---|---|---|
|
|
38
|
+
| `nas_pre_training` | 学習前のアーキテクチャ性能 — ベンチマーク参照による探索、性能予測器、ゼロコストプロキシ | `search`(任意)、`predictor`(任意)。少なくとも 1 つ |
|
|
39
|
+
| `nas_post_training` | 学習後のアーキテクチャ性能 — 選ばれて学習された最終アーキテクチャ | `architecture`(必須)、`tradeoff`(任意) |
|
|
40
|
+
|
|
41
|
+
## 各タスクは何を返すか(指標の説明)
|
|
42
|
+
|
|
43
|
+
どちらも登録情報から導出されるので、実装と食い違うことがない:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
airas-eval list # 全タスクタイプ: 入力、指標、曲線、入力サイズ、署名
|
|
47
|
+
airas-eval list nas_post_training # 1 タスクタイプ
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
および、エリアごとに生成される README(テストで同期を検証):
|
|
51
|
+
|
|
52
|
+
- [`tasks/generic/README.md`](src/airas_eval/tasks/generic/README.md) — 汎用の評価ファミリー
|
|
53
|
+
- [`tasks/nas/README.md`](src/airas_eval/tasks/nas/README.md) — NAS の 2 タスク
|
|
54
|
+
|
|
55
|
+
**各指標の説明(定義、読み方、高低どちらが良いか)はこれらの README の表に載っている。**
|
|
56
|
+
タスクやバンドルを変更したら `python -m airas_eval.tasks.readme` で再生成する。
|
|
57
|
+
|
|
58
|
+
## 使い方
|
|
59
|
+
|
|
60
|
+
```python
|
|
61
|
+
from airas_eval import evaluate
|
|
62
|
+
|
|
63
|
+
report = evaluate(
|
|
64
|
+
"nas_post_training",
|
|
65
|
+
{
|
|
66
|
+
"architecture": {
|
|
67
|
+
"predicted_labels": y_pred,
|
|
68
|
+
"reference_labels": y_true,
|
|
69
|
+
"probabilities": probs, # 任意
|
|
70
|
+
"oracle_test_best": 0.9437, # 任意: ベンチマークのテスト最適値(0〜1)
|
|
71
|
+
},
|
|
72
|
+
"tradeoff": { # 任意グループ
|
|
73
|
+
"points": [[error, macs], ...], # 全目的を最小化
|
|
74
|
+
"reference_point": [0.2, 1e9],
|
|
75
|
+
},
|
|
76
|
+
},
|
|
77
|
+
)
|
|
78
|
+
report.metrics # スカラー指標: {"architecture.accuracy": ..., "tradeoff.hypervolume_2d": ...}
|
|
79
|
+
report.curves # 曲線指標: {"tradeoff.pareto_front": [...]}
|
|
80
|
+
report.inputs_summary # 指標ではない — 入力サイズ: {"architecture.n_examples": 10000, ...}
|
|
81
|
+
report.skipped # 計算できなかった指標 — 機械可読なコード + 理由
|
|
82
|
+
report.omitted_optional_inputs # 例: ["architecture.random_architecture_accuracies"]
|
|
83
|
+
report.provenance # 導出されたタスク署名、依存パッケージの版、入力の SHA-256
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
airas-eval score nas_pre_training --inputs inputs.json --output evaluation.json
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
`examples/` に NAS 各タスクの最小入力ファイルがあり、テストスイートがそれぞれを CLI
|
|
91
|
+
で採点する。NAS 固有の入力(`evaluation_costs`, `search_space_scores`,
|
|
92
|
+
`random_architecture_accuracies`, `oracle_test_best`, ...)は任意の参照データで、
|
|
93
|
+
省略するとそれを必要とする指標は skipped として報告され、省略自体も記録される。
|
|
94
|
+
|
|
95
|
+
入力は常にグループ化されている(`{"architecture": {...}}`)。呼び出し側が選べるのは
|
|
96
|
+
タスクタイプだけで、研究をどのタスクタイプで評価するかは研究計画側が決める
|
|
97
|
+
(評価ステップではない)。NAS では、探索ステージの後に `nas_pre_training`、
|
|
98
|
+
最終アーキテクチャの学習後に `nas_post_training` を呼ぶ、というパイプラインの段階が
|
|
99
|
+
それに対応する。
|
|
100
|
+
|
|
101
|
+
## 設計ルール
|
|
102
|
+
|
|
103
|
+
1. **指標を選ばせない。** タスクタイプは自分の指標を*すべて*計算する。集合は固定で、
|
|
104
|
+
読み切れる大きさに保つ(長い一覧はそれ自体がチェリーピックの余地になる)。
|
|
105
|
+
variant(平均方法、k、ビン数)はタスクごとに固定され、指標関数が取る全パラメータは
|
|
106
|
+
明示的に固定される(テストで強制)。入力サイズ(`n_examples`, `n_evaluations`, ...)
|
|
107
|
+
は指標とは別に `inputs_summary` に報告され、テスト集合の部分抽出や打ち切られた
|
|
108
|
+
探索が見えるようにする。
|
|
109
|
+
2. **黙って消えるものはない。** 計算できなかった指標は `skipped` に機械可読なコード
|
|
110
|
+
(`missing_optional_input`, `not_applicable`, `undefined_on_data`,
|
|
111
|
+
`missing_dependency`)付きで現れ、省略された任意入力もレポートごとに列挙される。
|
|
112
|
+
skip になるのはこれらの専用ケースだけで、不正な入力やライブラリのバグは
|
|
113
|
+
「未定義」に隠れず例外で失敗する。
|
|
114
|
+
3. **来歴は手書きせず導出する。** タスク署名はタスク宣言(指標名、関数の識別子、
|
|
115
|
+
固定 kwargs、入力フィールド)のハッシュなので、実装と乖離できない。エリアごとの
|
|
116
|
+
README も同じ宣言から生成される。
|
|
117
|
+
4. **参照データは上流で固定する。** `reference_labels`、`oracle_best`、
|
|
118
|
+
`oracle_test_best`、参照点・参照フロントは実験設計に属する。このライブラリはそれ
|
|
119
|
+
らが本物であることを検証できず、エージェントが制御するプロセスの中では自衛でき
|
|
120
|
+
ない — `airas-eval score` をエージェントが編集できない固定環境から実行すること。
|
|
121
|
+
|
|
122
|
+
## インストール
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
uv add "airas-eval==0.3.0" # ライブラリ/CLI として
|
|
126
|
+
uvx airas-eval@0.3.0 list # インストールせずに CLI だけ使う
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
評価層が研究の途中で変わらないように、必ずバージョンを固定する。依存: numpy,
|
|
130
|
+
scikit-learn, scipy, pydantic。
|
|
131
|
+
|
|
132
|
+
## 研究リポジトリからの呼び出し方
|
|
133
|
+
|
|
134
|
+
agent の実験コードは **airas_eval を import しない**。agent の成果物は評価の
|
|
135
|
+
**入力ファイル**(`evaluate` に渡す dict をそのまま JSON にしたもの)までで、評価は
|
|
136
|
+
固定版の CLI を別プロセスで走らせる。研究リポジトリには airas(オーケストレータ)の
|
|
137
|
+
テンプレート由来で次が置かれる:
|
|
138
|
+
|
|
139
|
+
```toml
|
|
140
|
+
# pyproject.toml — 依存として固定するが、実験コードからは import しない
|
|
141
|
+
[dependency-groups]
|
|
142
|
+
eval = ["airas-eval==0.3.0"]
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
```makefile
|
|
146
|
+
# Makefile — task_type と入出力先は研究計画から埋める
|
|
147
|
+
evaluate:
|
|
148
|
+
uv run --group eval airas-eval score nas_pre_training \
|
|
149
|
+
--inputs artifacts/eval_inputs/nas_pre_training.json \
|
|
150
|
+
--output artifacts/evaluation/nas_pre_training.json
|
|
151
|
+
uv run --group eval airas-eval score nas_post_training \
|
|
152
|
+
--inputs artifacts/eval_inputs/nas_post_training.json \
|
|
153
|
+
--output artifacts/evaluation/nas_post_training.json
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
agent は `make evaluate` を実行してスコアを確認しながら実験を進めてよい。ただし
|
|
157
|
+
Makefile は agent が書き換え得るので、**公式のスコアはオーケストレータが agent の
|
|
158
|
+
触れない環境で、同じ版の CLI を入力ファイルに直接かけて再計算したもの**とする。
|
|
159
|
+
report の `inputs_sha256` と入力ファイルの hash、`provenance.versions` の版を照合すれば、
|
|
160
|
+
どの入力をどの版で採点したかが確認できる。第三者は clone → `uv sync --group eval` →
|
|
161
|
+
`make evaluate` で同じ数字を再現できる(`uv.lock` が版を固定する)。
|
|
162
|
+
|
|
163
|
+
## リリース手順
|
|
164
|
+
|
|
165
|
+
公開は GitHub Actions の `publish.yml`(PyPI Trusted Publisher、API トークン不要)で行う。
|
|
166
|
+
|
|
167
|
+
初回のみ、PyPI 側の設定が必要:
|
|
168
|
+
|
|
169
|
+
1. https://pypi.org/manage/account/publishing/ で **pending publisher** を登録する —
|
|
170
|
+
PyPI project name `airas-eval`、owner `airas-org`、repository `airas-eval`、
|
|
171
|
+
workflow `publish.yml`、environment `pypi`。
|
|
172
|
+
2. GitHub リポジトリの Settings → Environments に `pypi` を作る(承認者を付けてもよい)。
|
|
173
|
+
|
|
174
|
+
毎回のリリース:
|
|
175
|
+
|
|
176
|
+
```bash
|
|
177
|
+
uv version --bump minor # pyproject と __init__ の版を揃える(現状は手動で両方)
|
|
178
|
+
uv lock && uv run pytest -q
|
|
179
|
+
git commit -am "release: v0.3.0" && git tag v0.3.0 && git push --tags
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
その後 Actions から `Publish` を手動実行する(HEAD にその版のタグが付いていることを
|
|
183
|
+
ワークフローが検証する)。Trusted Publisher が動くことを確認したら、`publish.yml` の
|
|
184
|
+
トリガーを `push: tags: ["v*"]` に切り替えてタグ push だけで公開できるようにする。
|
|
185
|
+
|
|
186
|
+
## 開発
|
|
187
|
+
|
|
188
|
+
```bash
|
|
189
|
+
uv sync
|
|
190
|
+
uv run ruff format --check .
|
|
191
|
+
uv run ruff check .
|
|
192
|
+
uv run mypy src
|
|
193
|
+
uv run pytest
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
タスクタイプの追加 = `tasks/<area>/` に既存バンドルから `TASK` を定義するモジュールを
|
|
197
|
+
1 つ置き、エリアの `TASKS` に 1 行足し、`python -m airas_eval.tasks.readme` を実行。
|
|
198
|
+
新しいエリア = 新しいサブパッケージ + `tasks.AREAS` に 1 行。バンドルの追加 =
|
|
199
|
+
`tasks/_inputs.py` の入力モデルと `tasks/_bundles.py` の `Bundle`(`summary` の件数
|
|
200
|
+
付き)。各バインディングには日本語の `description` が必須(テストで強制)。タスクは
|
|
201
|
+
5〜10 指標程度に保つ: 標準的な variant のみ、パラメータごとに 1 つの固定値。
|
|
202
|
+
|
|
203
|
+
登録は意図的に明示的(entry point もスキャンもしない): 信頼層では、何が計算される
|
|
204
|
+
かがレビュー済みの差分に見えていなければならない。自前実装の指標を追加する場合は、
|
|
205
|
+
オラクル実装とのパリティテスト、または手計算ケース + 性質テストが必要。
|
|
206
|
+
|
|
207
|
+
## ライセンス
|
|
208
|
+
|
|
209
|
+
MIT
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# 入力例
|
|
2
|
+
|
|
3
|
+
NAS の各タスクタイプに対する最小の入力ファイル。`airas-eval score` が期待する形
|
|
4
|
+
(入力グループごとに 1 オブジェクト)になっている。利用者と同じ方法で実行できる:
|
|
5
|
+
|
|
6
|
+
```bash
|
|
7
|
+
uvx airas-eval score nas_post_training --inputs examples/nas_post_training.json
|
|
8
|
+
# チェックアウトから実行する場合:
|
|
9
|
+
uv run airas-eval score nas_post_training --inputs examples/nas_post_training.json
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
`tests/test_cli.py` は、ここにある全ファイルをインストール済み CLI に通して検証する。
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
{
|
|
2
|
+
"architecture": {
|
|
3
|
+
"predicted_labels": [
|
|
4
|
+
0,
|
|
5
|
+
1,
|
|
6
|
+
2,
|
|
7
|
+
0,
|
|
8
|
+
1,
|
|
9
|
+
2,
|
|
10
|
+
1,
|
|
11
|
+
0,
|
|
12
|
+
2,
|
|
13
|
+
2
|
|
14
|
+
],
|
|
15
|
+
"reference_labels": [
|
|
16
|
+
0,
|
|
17
|
+
1,
|
|
18
|
+
2,
|
|
19
|
+
0,
|
|
20
|
+
1,
|
|
21
|
+
2,
|
|
22
|
+
2,
|
|
23
|
+
0,
|
|
24
|
+
1,
|
|
25
|
+
2
|
|
26
|
+
],
|
|
27
|
+
"probabilities": [
|
|
28
|
+
[
|
|
29
|
+
0.7,
|
|
30
|
+
0.2,
|
|
31
|
+
0.1
|
|
32
|
+
],
|
|
33
|
+
[
|
|
34
|
+
0.1,
|
|
35
|
+
0.8,
|
|
36
|
+
0.1
|
|
37
|
+
],
|
|
38
|
+
[
|
|
39
|
+
0.2,
|
|
40
|
+
0.2,
|
|
41
|
+
0.6
|
|
42
|
+
],
|
|
43
|
+
[
|
|
44
|
+
0.6,
|
|
45
|
+
0.3,
|
|
46
|
+
0.1
|
|
47
|
+
],
|
|
48
|
+
[
|
|
49
|
+
0.2,
|
|
50
|
+
0.7,
|
|
51
|
+
0.1
|
|
52
|
+
],
|
|
53
|
+
[
|
|
54
|
+
0.1,
|
|
55
|
+
0.1,
|
|
56
|
+
0.8
|
|
57
|
+
],
|
|
58
|
+
[
|
|
59
|
+
0.3,
|
|
60
|
+
0.4,
|
|
61
|
+
0.3
|
|
62
|
+
],
|
|
63
|
+
[
|
|
64
|
+
0.8,
|
|
65
|
+
0.1,
|
|
66
|
+
0.1
|
|
67
|
+
],
|
|
68
|
+
[
|
|
69
|
+
0.2,
|
|
70
|
+
0.3,
|
|
71
|
+
0.5
|
|
72
|
+
],
|
|
73
|
+
[
|
|
74
|
+
0.1,
|
|
75
|
+
0.2,
|
|
76
|
+
0.7
|
|
77
|
+
]
|
|
78
|
+
],
|
|
79
|
+
"random_architecture_accuracies": [
|
|
80
|
+
0.55,
|
|
81
|
+
0.62,
|
|
82
|
+
0.71,
|
|
83
|
+
0.68,
|
|
84
|
+
0.74,
|
|
85
|
+
0.6
|
|
86
|
+
],
|
|
87
|
+
"oracle_test_best": 0.94
|
|
88
|
+
},
|
|
89
|
+
"tradeoff": {
|
|
90
|
+
"points": [
|
|
91
|
+
[
|
|
92
|
+
0.08,
|
|
93
|
+
3.2
|
|
94
|
+
],
|
|
95
|
+
[
|
|
96
|
+
0.06,
|
|
97
|
+
5.1
|
|
98
|
+
],
|
|
99
|
+
[
|
|
100
|
+
0.07,
|
|
101
|
+
4.0
|
|
102
|
+
],
|
|
103
|
+
[
|
|
104
|
+
0.1,
|
|
105
|
+
2.5
|
|
106
|
+
]
|
|
107
|
+
],
|
|
108
|
+
"reference_point": [
|
|
109
|
+
0.2,
|
|
110
|
+
10.0
|
|
111
|
+
]
|
|
112
|
+
}
|
|
113
|
+
}
|