Workflow
从 CLI 输入到 artifacts、metrics、scorecard 和 report 的端到端执行流。
简介
本文追踪一次 evaluation run 从 CLI 到磁盘 artifact 的完整路径。当你需要知道某个 flag 落在哪段代码、哪个 runner 负责写文件、或 model mode 为何会分叉到 ContractRunner 与 ExistingResultsRunner 时读这里。面向用户的命令示例见 评测指南;本文聚焦执行 plumbing。
入口
每条用户可见命令最终都会到达 evaluation/tasks/execution/evaluate.py 中的 run_evaluate()。控制台入口是 worldfoundry/cli/main.py,子命令会分发到以下四种形态之一:
- evaluate — 归一化输入、选择 run mode,返回一个
EvaluateRunResult。 - existing outputs — 通过
existing_results.py评分磁盘上已有 artifact,不加载模型。 - model run — 经
resolver.py解析 model runner,调用generate(),再评分归一化结果。 - model plus benchmark — 经
model_benchmark.py先生成,再端到端调用 benchmark-zoo runner。
第一个实质分支始终是 mode 选择:本次 run 是否需要在 GPU 上加载权重,还是只消费已有文件。
Evaluate 主流程
主流程如下:一个 EvaluateRunRequest 进入 facade,选定 mode,从 task registry 加载或物化输入,再由 delegate runner 写出标准 artifact bundle。若输出目录缺文件,沿此流程查应由哪个 runner 阶段产出。
# worldfoundry/cli/main.py → evaluation/tasks/execution/evaluate.py
result = run_evaluate(EvaluateRunRequest(...))
mode = _mode(request)
requests, results = load_or_materialize(request) # task registry / 磁盘路径
runner = pick_delegate_runner(mode, request)
runner.run(requests, results)
# 写入 output_dir/:
write("run_manifest.json")
write("execution_plan.json")
write("requests.jsonl")
write("results.jsonl")
write("sample_ledger.jsonl")
write("metrics/summary.json")
write("scorecard.json")
write("summary.json")
write("report.md")Facade 本身很小。run_evaluate() 只做请求校验、模式选择和 runner 分发;真正的文件写入和样本级 accounting 由 delegate runner 负责。
模式行为
Mode 选择是第一个影响成本与前置条件的分支。existing-results 不加载权重,只评分磁盘上已有内容,因此 hosted API 批处理与离线 demo 常用它。model 会先解析 runner 并调用 generate();传入的 metrics 类型决定 scoring 留在进程内(ContractRunner)还是复用 existing-results 路径(ExistingResultsRunner)。
| Mode | 必需输入 | 是否加载模型 | 指标路径 | 什么时候用 |
|---|---|---|---|---|
existing-results | results 或 results_path;requests 可选 | 否 | Built-in metric ids 或 artifact checks | Demo、hosted job 或离线脚本已经产出 artifacts。 |
model | Requests 加 runner config 或 model-zoo id | 是 | 传 Metric objects 时走 ContractRunner;传 metric ids/artifact checks 时走 ExistingResultsRunner | 希望由框架执行模型。 |
Model Mode 细节
runner.generate() 返回后,_align_model_results() 保证每个 request 都有对应 result 行(含显式失败)。下面分叉容易被忽略:传入 Metric 对象则整次 run 留在 ContractRunner;传入 string metric ids 则 scoring 走与 existing-results 相同的代码路径。
runner = resolve_model_zoo_runner(request.model_id)
results = runner.generate(requests)
results = _align_model_results(requests, results)
if isinstance(request.metrics[0], Metric):
return ContractRunner(...).score(results) # Metric objects → 进程内
else:
return ExistingResultsRunner(...).score(results) # metric ids → existing-results 路径关键点:模型执行和 benchmark scoring 是分开的。Model runner 只输出 GenerationResult;结果归一化后才评分。
Contract Runner 细节
run_contract() 是最严格的 in-process path,也是 artifact 布局的参考实现。每个阶段都会写出或更新下游 validation、docs export 与 leaderboard 工具期望找到的文件。调试不完整 run 时按阶段顺序排查:缺少 metrics/per_sample.jsonl 通常是 generation 未完成对齐,而非 reporting 失败。
# evaluation/tasks/execution/contract.py → run_contract()
requests = _normalize_requests(request)
write_execution_plan(requests) # execution_plan.json
write_run_manifest(status="running") # run_manifest.json
results = run_generation_with_cache(runner, requests)
write_artifacts_jsonl(_artifact_rows(results)) # artifacts.jsonl
write_per_sample_metrics(...) # metrics/per_sample.jsonl
summary = _build_summary(...) # metrics/summary.json
write_scorecard(summary) # scorecard.json
write_run_report_artifacts(summary) # summary.json + report.md
write_run_manifest(status="finished") # 最终 run_manifest.jsonGeneration 是最耗时的阶段:runner 异常会变成 failed samples,确定性输出可复用 SQLite generation cache。Reporting 阶段只在每个样本都有对齐 result 行之后才运行。
Artifact 契约
这些文件构成 评测指南 中的 audit trail。各 run mode 下形态稳定:existing-results 仍会写 sample_ledger.jsonl 和 scorecard.json,便于与同一 benchmark 上的完整 model run 对比。路径均相对 run_manifest.json 中记录的 run 输出目录。
| 文件 | 生产者 | 含义 |
|---|---|---|
run_manifest.json | Runner | Run identity、status、model、benchmark、dataset、context metadata、output paths。 |
execution_plan.json | Runner 或 RunPlan | Planned stages、sample ids、materialization details、output files。 |
requests.jsonl | Runner | 每个样本一个归一化 GenerationRequest。 |
results.jsonl | Model runner through evaluation runner | 每个样本一个归一化 GenerationResult。 |
sample_ledger.jsonl | Runner | 样本级 pass/fail 状态和 stage-level errors。 |
artifacts.jsonl | Runner | 相对 output directory enrich 后的 flattened artifact refs。 |
metrics/per_sample.jsonl | Metrics layer | 样本级 metric output 或 skipped state。 |
metrics/summary.json | Metrics layer | Aggregates、failed ids、skipped ids、leaderboard fields。 |
scorecard.json | Reporting layer | Release/review surface,供 validation 和 docs 消费。 |
report.md | Reporting layer | 从 scorecard 派生的人类可读摘要。 |
Task Materialization
Task-driven run 在任意模型代码运行之前固定 sample id、split 与 input keys,使 rerun 与 cache 复现可预期:相同 task YAML 与 dataset manifest 应在每台机器上产出相同的 requests.jsonl 行。下方代码把 catalog task YAML 接到 run_evaluate() 已理解的 EvaluateRunRequest;YAML 文件位置见 基准和数据。
registry = load_task_registry_from_paths(task_yaml_paths)
plan = build_run_plan_from_task_registry(registry, dataset_manifest)
requests = _materialize_requests_from_task(plan)
requests = materialize_generation_requests(requests)
return EvaluateRunRequest(requests=requests, ...)当 sample id、split、input keys、output keys 和 cache policy 需要在 generation 前可复现时,用这条路径。