airas-eval
AIRAS のための信頼できる評価層。 エージェントはタスクタイプと生の予測結果を渡し、その研究種別で報告すべき標準的な 評価指標一式を固定された形で受け取る。エージェントは評価スクリプトを実装せず、 どの指標を(どの variant で)報告するかも選ばない。
用途は 2 つ。汎用の評価ファミリー(分類・探索など)と、固定ベンチマークのパック である。パックはデータセット(ハッシュで固定)、ベンチマーク公式の評価器(コミットで 固定)、論文の公表値をひとまとめにしたもので、AIRAS はパックに対して手法だけを変えて、 公表値を超えるまで研究を回す。パックは重い依存(シミュレータなど)を持ってよく、その 依存はパックを使う研究だけが負う。
構成
2 層構造で、その間に呼び出し側が選べるものはない。
metrics/— 評価指標の実装。入力の形ごとに 1 モジュールで、タスクの知識を 持たない。標準実装(scikit-learn / scipy)があるものはそれに委譲し、存在しない もの(ECE、リグレット、上位 k 選択、2 目的ハイパーボリューム、IGD/GD/spacing) だけを自前で実装して variant を固定し、性質テストで検証している。tasks/— エリアごとに 1 サブパッケージ、タスクタイプごとに 1 モジュール。 タスクタイプとは「その種類の研究が報告すべき指標の全集合」で、1 つの検証済み 入力ファイルから計算される(タスクあたり数十指標まで、スカラーまたは曲線、variant は すべて固定)。generic/が基本となる評価ファミリー、エリアパッケージ(nas/) はその上に積む — エリアの指標セットは 基本のバインディング + その分野の文献が 追加するもの であり、名前を変えた複製ではない。再利用部品 (tasks/generic/_metric_sets.py,tasks/nas/_metric_sets.py)は内部の定数で、登録も 公開も単独評価もされない。
tasks/
├── generic/ classification, binary_classification, search, candidate_ranking, multiobjective
├── nas/ nas_pre_training = search + candidate_ranking の全指標 + NAS 追加分(wall-clock 軸、
│ │ 探索空間内順位、ランダム探索比、上位 10% 相関)
│ └── nas_post_training = classification + multiobjective の全指標 + NAS 追加分
│ (ランダムアーキテクチャ比、テストリグレット)
└── scigym/ scigym_small = SciGym 公式 Evaluator(コミット固定)による STE と反応 P/R/F1、
137 件のデータをハッシュで固定、論文 Table 1 の最良値との差
ベンチマークパックの依存は本体に含めない。scigym_small を使うには SciGym を固定コミットから
入れる(pip install "scigym @ git+https://github.com/h4duan/SciGym@88a7b93609e35b6ecb4eb343d816d6ff09256c6a" pygraphviz。Evaluator が反応グラフの構築に pygraphviz を使うが、SciGym 自身は依存に挙げていない)。
無ければ指標は missing_dependency として skipped になる。
NAS は「アーキテクチャの性能をいつ測るか」で 2 タスクに分かれる:
| タスクタイプ | 測るもの | 入力(1 ファイル) |
|---|---|---|
nas_pre_training |
学習前のアーキテクチャ性能 — ベンチマーク参照による探索、性能予測器、ゼロコストプロキシ | 探索軌跡(evaluated_scores …)か予測器スコア(predicted_scores + reference_scores)の少なくとも一方。無い側の指標は skipped |
nas_post_training |
学習後のアーキテクチャ性能 — 選ばれて学習された最終アーキテクチャ | 予測ラベル・正解ラベル(必須)、確率・ベースライン・テスト最適値・(誤り率, コスト) 点集合(任意) |
各タスクは何を返すか(指標の説明)
どちらも登録情報から導出されるので、実装と食い違うことがない:
airas-eval list # タスクタイプの一覧(1 行ずつ: 名前、署名、概要、指標数)
airas-eval list nas_pre_training nas_post_training # 指定タスクの詳細: 入力(型・値域)、指標(値域・方向・説明)
airas-eval list --all # 全タスクの詳細
airas-eval list --json [task ...] # 同じ内容を dict で(プログラムから読む契約)
airas-eval validate nas_post_training --inputs inputs.json # 形式だけ検査(採点しない)
list <task> の入力欄(name?: type と説明、フィールド間の制約)と list --json の
input_schema(JSON Schema)は、入力検証に使うのと同じ pydantic モデルから生成される
ので、agent が読む契約と評価器が適用する検査が食い違わない。
および、エリアごとに生成される README(テストで同期を検証):
tasks/generic/README.md— 汎用の評価ファミリーtasks/nas/README.md— NAS の 2 タスクtasks/scigym/README.md— SciGym-small ベンチマークパック
各指標の説明(定義、読み方、高低どちらが良いか)はこれらの README の表に載っている。
タスクやバンドルを変更したら python -m airas_eval.tasks.readme で再生成する。
使い方
from airas_eval import evaluate
report = evaluate(
"nas_post_training",
{
"predicted_labels": y_pred,
"reference_labels": y_true,
"probabilities": probs, # 任意
"oracle_test_best": 0.9437, # 任意: ベンチマークのテスト最適値(0〜1)
"points": [[error, macs], ...], # 任意: 精度–効率トレードオフ(全目的を最小化)
"reference_point": [0.2, 1e9],
},
)
report.metrics # スカラー指標: {"accuracy": ..., "test_regret": ..., "hypervolume_2d": ...}
report.curves # 曲線指標: {"pareto_front": [...]}
report.inputs_summary # 指標ではない — 入力サイズ: {"n_examples": 10000, ...}
report.skipped # 計算できなかった指標(理由コード別): missing_optional_input は名前の一覧、他は名前 → 理由
report.omitted_optional_inputs # 例: ["random_architecture_accuracies", "reference_front"]
report.provenance # 導出されたタスク署名、依存パッケージの版、入力の SHA-256
airas-eval score nas_pre_training --inputs inputs.json --output evaluation.json
複数 seed と 2 システム比較も評価層が引き受ける(agent が統計を自前実装しないため):
# seed ごとの report を手法ごとに集約(同じタスク署名のものだけ)。指標ごとに mean / std / sem /
# min / max / median / q25 / q75 / 95% t 信頼区間 / n / 生の値。曲線は横軸が揃うものだけ点ごとに集約し、
# 揃わないもの(pareto_front など)は not_aggregated に理由付きで列挙。一部の run にしか無い指標は
# 平均せず incomplete に件数を列挙。--label で手法名を記録する
airas-eval aggregate --label method_A --reports runs/A/seed*.json --output aggregate_A.json
# 同じ参照データ上での 2 システムのペア比較(事例ごとの正誤に対する符号反転パーミュテーション検定)
airas-eval compare nas_post_training --a inputs_A.json --b inputs_B.json
examples/ に NAS 各タスクの最小入力ファイルがあり、テストスイートがそれぞれを CLI
で採点する。NAS 固有の入力(evaluation_costs, search_space_scores,
random_architecture_accuracies, oracle_test_best, ...)は任意の参照データで、
省略するとそれを必要とする指標は skipped として報告され、省略自体も記録される。
入力は 1 タスク 1 ファイル(フラットな JSON オブジェクト)。呼び出し側が選べるのは
タスクタイプだけで、研究をどのタスクタイプで評価するかは研究計画側が決める
(評価ステップではない)。NAS では、探索ステージの後に nas_pre_training、
最終アーキテクチャの学習後に nas_post_training を呼ぶ、というパイプラインの段階が
それに対応する。
設計ルール
- 指標を選ばせない。 タスクタイプは自分の指標をすべて計算する。集合は固定で、
読み切れる大きさに保つ(長い一覧はそれ自体がチェリーピックの余地になる)。
variant(平均方法、k、ビン数)はタスクごとに固定され、指標関数が取る全パラメータは
明示的に固定される(テストで強制)。入力サイズ(
n_examples,n_evaluations, ...) は指標とは別にinputs_summaryに報告され、テスト集合の部分抽出や打ち切られた 探索が見えるようにする。 - 黙って消えるものはない。 計算できなかった指標は
skippedに理由コード別 (missing_optional_input,not_applicable,undefined_on_data,missing_dependency)で現れる。任意入力の省略によるものは名前だけを列挙し (原因はomitted_optional_inputsとlistの「必要な入力」で分かる)、それ以外は 名前 → 理由を持つ。 skip になるのはこれらの専用ケースだけで、不正な入力やライブラリのバグは 「未定義」に隠れず例外で失敗する。 - 来歴は手書きせず導出する。 タスク署名はタスク宣言(指標名、関数の識別子、 固定 kwargs、入力フィールド)のハッシュなので、実装と乖離できない。エリアごとの README も同じ宣言から生成される。
- 参照データは上流で固定する。
reference_labels、oracle_best、oracle_test_best、参照点・参照フロントは実験設計に属する。このライブラリはそれ らが本物であることを検証できず、エージェントが制御するプロセスの中では自衛でき ない —airas-eval scoreをエージェントが編集できない固定環境から実行すること。
インストール
uv add "airas-eval==0.10.0" # ライブラリ/CLI として
uvx airas-eval@0.10.0 list # インストールせずに CLI だけ使う
評価層が研究の途中で変わらないように、必ずバージョンを固定する。依存: numpy, scikit-learn, scipy, pydantic。
研究リポジトリからの呼び出し方
agent の実験コードは airas_eval を import しない。agent の成果物は評価の
入力ファイル(evaluate に渡す dict をそのまま JSON にしたもの)までで、評価は
固定版の CLI を別プロセスで走らせる。研究リポジトリには airas(オーケストレータ)の
テンプレート由来で次が置かれる:
# pyproject.toml — 依存として固定するが、実験コードからは import しない
[dependency-groups]
eval = ["airas-eval==0.10.0"]
# Makefile — task_type と入出力先は研究計画から埋める
evaluate:
uv run --group eval airas-eval score nas_pre_training \
--inputs artifacts/eval_inputs/nas_pre_training.json \
--output artifacts/evaluation/nas_pre_training.json
uv run --group eval airas-eval score nas_post_training \
--inputs artifacts/eval_inputs/nas_post_training.json \
--output artifacts/evaluation/nas_post_training.json
agent は make evaluate を実行してスコアを確認しながら実験を進めてよい。ただし
Makefile は agent が書き換え得るので、公式のスコアはオーケストレータが agent の
触れない環境で、同じ版の CLI を入力ファイルに直接かけて再計算したものとする。
report の inputs_sha256 と入力ファイルの hash、provenance.versions の版を照合すれば、
どの入力をどの版で採点したかが確認できる。第三者は clone → uv sync --group eval →
make evaluate で同じ数字を再現できる(uv.lock が版を固定する)。
リリース手順
公開は GitHub Actions の publish.yml(PyPI Trusted Publisher、API トークン不要)で行う。
初回のみ、PyPI 側の設定が必要:
- https://pypi.org/manage/account/publishing/ で pending publisher を登録する —
PyPI project name
airas-eval、ownerairas-org、repositoryairas-eval、 workflowpublish.yml、environmentpypi。 - GitHub リポジトリの Settings → Environments に
pypiを作る(承認者を付けてもよい)。
毎回のリリース:
uv version --bump minor # 版は pyproject.toml のみ(__version__ はメタデータから読む)
uv lock && uv run pytest -q
git commit -am "release: v0.10.0" && git tag v0.10.0 && git push --tags
タグの push で Publish ワークフローが起動し、HEAD にその版のタグが付いていることを
検証してから PyPI に公開する(Actions から手動実行も可能)。
開発
uv sync
uv run ruff format --check .
uv run ruff check .
uv run mypy src
uv run pytest
タスクタイプの追加 = tasks/<area>/ に既存バンドルから TASK を定義するモジュールを
1 つ置き、エリアの TASKS に 1 行足し、python -m airas_eval.tasks.readme を実行。
新しいエリア = 新しいサブパッケージ + tasks.AREAS に 1 行。バンドルの追加 =
tasks/generic/_inputs.py の入力モデルと tasks/_bundles.py の Bundle(summary の件数
付き)。各バインディングには日本語の description が必須(テストで強制)。タスクは
5〜10 指標程度に保つ: 標準的な variant のみ、パラメータごとに 1 つの固定値。
登録は意図的に明示的(entry point もスキャンもしない): 信頼層では、何が計算される かがレビュー済みの差分に見えていなければならない。自前実装の指標を追加する場合は、 オラクル実装とのパリティテスト、または手計算ケース + 性質テストが必要。
ライセンス
MIT
Release files for airas-eval 0.11.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| airas_eval-0.11.0.tar.gz | 152.7 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| airas_eval-0.11.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 243.5 kB
Release files / airas_eval-0.11.0.tar.gz
| Download URL | airas_eval-0.11.0.tar.gz |
|---|---|
| Size | 152.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
e211dfb29e9b4ffa5e65a7fd1619434f0a0f5b68c1858c8cf62afbc157b3985f
|
|
BLAKE2b-256 checksum How to use checksums |
80e00935b2f88eb21b40f86c0d616d392aa634937798e077842423b6b73b74da
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.19 {"installer":{"name":"uv","version":"0.12.19","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / airas_eval-0.11.0-py3-none-any.whl
| Download URL | airas_eval-0.11.0-py3-none-any.whl |
|---|---|
| Size | 90.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
171dc7be48c2af8c359bfc659d774ea0f195b23769f6c7b664cff8e876badc4b
|
|
BLAKE2b-256 checksum How to use checksums |
569b320d1eeb2f2d94887bb29f2981fc7c1da144eb38a31ac33d841049508ece
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.19 {"installer":{"name":"uv","version":"0.12.19","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|