[DRAFT] feat: add generalized Kaggle Community Benchmarks adapter#191
Draft
mrshu wants to merge 1 commit into
Draft
[DRAFT] feat: add generalized Kaggle Community Benchmarks adapter#191mrshu wants to merge 1 commit into
mrshu wants to merge 1 commit into
Conversation
Previously the only Kaggle ingestion was a single hardcoded script
(utils/global-mmlu-lite) bound to one benchmark and one metric path. This
commit adds a generalized adapter that converts any Kaggle Community
Benchmark leaderboard into the EvalEval schema (v0.2.2), either for
explicit owner/slug targets or by discovering and converting every
published benchmark. A full run converts ~996/1017 benchmarks into
~13.7k schema-valid records, which would make Kaggle the second-largest
source in the datastore.
Discovery uses Kaggle's unauthenticated internal RPC
(benchmarks.BenchmarkService/ListBenchmarks) with the anonymous XSRF
cookie/header handshake, because no official package, sitemap, or public
endpoint can enumerate community benchmarks. Per-benchmark leaderboards
are read from the public REST endpoint
(/api/v1/benchmarks/{owner}/{slug}/leaderboard). Both APIs are
undocumented for consumers, so the response shapes the adapter relies on
are pinned by validation and tests rather than an upstream contract.
Schema mapping is deliberately conservative about what Kaggle actually
exposes:
- Numeric results in [0, 1] become bounded `continuous` metrics; boolean
results become `binary`. Numeric values outside [0, 1] have an unknown
scale (Kaggle does not publish metric bounds) and are left untyped
rather than given fabricated [0, 1] bounds; `COUNTS`-typed metrics are
never bounded even when a value happens to fall in [0, 1].
- Confidence intervals are emitted as `[score - ci, score + ci]` because
Kaggle's `confidenceInterval` is a symmetric half-width ("confidence
radius"), matching the sibling utils/hle adapter.
- Each result carries its Kaggle `evaluationDate` as
`evaluation_timestamp` when present (~70% of results).
- On the discovery path, benchmark scoring config enriches each record:
`lower_is_better` from `sortOrder`, `metric_kind` from `aggregationType`
(only `PERCENTAGE_PASSED -> pass_rate`; generic reductions like
AVERAGE/SUM are intentionally not metric families), `metric_unit` from
`displayType`, with `benchmark_id`/`aggregation_type`/`display_type`
recorded in `source_metadata.additional_details`. The targeted
`--benchmark` path has no access to this metadata, so those fields fall
back to defaults there (a documented limitation).
Bulk runs are built to fail loudly rather than silently lose data: a
fetch failure is distinguished from an empty leaderboard, discovery
truncation and per-benchmark conversion errors are isolated and surfaced,
and the process exits non-zero when any benchmark could not be fetched,
converted, or discovered, so a partial run is never reported as a clean
success.
- Add `utils/kaggle/adapter.py` with `--benchmark owner/slug`
(repeatable), `--all`, `--limit`, and `--output-dir`; targets are
de-duplicated by (owner, slug), preferring the metadata-carrying entry
- Resolve the leaderboard owner as the organization slug when org-owned,
else the creating user's username; owner-qualify `evaluation_id`
- Write to the standard data/{benchmark}/{developer}/{model}/{uuid}.json
layout via the shared helpers (make_model_info, make_source_metadata,
save_evaluation_log)
- Add `tests/test_kaggle_adapter.py`: 31 network-free tests covering
result-type handling, CI bracketing, metadata enrichment, discovery
pagination/filtering, the failure-vs-empty contract, dedup, and the
non-zero-exit path
- Document usage, the discovery/bounds behavior, and the targeted-path
limitation in utils/README.md; retain the global-mmlu-lite adapter for
backwards compatibility
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Previously the only Kaggle ingestion was a single hardcoded script (
utils/global-mmlu-lite) bound to one benchmark and one metric path. This commit adds a generalized adapter that converts any Kaggle Community Benchmark leaderboard into the EvalEval schema (v0.2.2), either for explicit owner/slug targets or by discovering and converting every published benchmark. A full run converts 996/1017 benchmarks into about 13.7k schema-valid records, which would make Kaggle the second-largest source in the datastore.Discovery uses Kaggle's unauthenticated internal RPC (
benchmarks.BenchmarkService/ListBenchmarks) with the anonymous XSRF cookie/header handshake, because no official package, sitemap, or public endpoint can enumerate community benchmarks. Per-benchmark leaderboards are read from the public REST endpoint(
/api/v1/benchmarks/{owner}/{slug}/leaderboard). Both APIs are undocumented for consumers, so the response shapes the adapter relies on are pinned by validation and tests rather than an upstream contract.Schema mapping is deliberately conservative about what Kaggle actually exposes:
continuousmetrics; boolean results becomebinary. Numeric values outside [0, 1] have an unknown scale (Kaggle does not publish metric bounds) and are left untyped rather than given fabricated [0, 1] bounds;COUNTS-typed metrics are never bounded even when a value happens to fall in [0, 1].[score - ci, score + ci]because Kaggle'sconfidenceIntervalis a symmetric half-width ("confidence radius"), matching the sibling utils/hle adapter.evaluationDateasevaluation_timestampwhen present (about 70% of results).lower_is_betterfromsortOrder,metric_kindfromaggregationType(onlyPERCENTAGE_PASSED -> pass_rate; generic reductions like AVERAGE/SUM are intentionally not metric families),metric_unitfromdisplayType, withbenchmark_id/aggregation_type/display_typerecorded insource_metadata.additional_details. The targeted--benchmarkpath has no access to this metadata, so those fields fall back to defaults there (a documented limitation).Bulk runs are built to fail loudly rather than silently lose data: a fetch failure is distinguished from an empty leaderboard, discovery truncation and per-benchmark conversion errors are isolated and surfaced, and the process exits non-zero when any benchmark could not be fetched, converted, or discovered, so a partial run is never reported as a clean success.
utils/kaggle/adapter.pywith--benchmark owner/slug(repeatable),--all,--limit, and--output-dir; targets are de-duplicated by (owner, slug), preferring the metadata-carrying entryevaluation_idtests/test_kaggle_adapter.py: 31 network-free tests covering result-type handling, CI bracketing, metadata enrichment, discovery pagination/filtering, the failure-vs-empty contract, dedup, and the non-zero-exit path