This repository forecasts AI benchmark performance over time using Bayesian sigmoidal growth models. It processes benchmark data from EpochAI, Scale AI, and RAND sources, fits hierarchical Harvey growth curves via PyMC, and generates forecast visualizations.
-
0_Process_benchmarks.ipynbCleans and standardizes benchmark data from multiple sources (EpochAI, Scale AI SEAL, RAND). Includes: selecting and formatting benchmark scores for modeling, harmonizing benchmark identifiers, handling missing/irregular data, loading per-benchmark lower bounds (random-chance baselines), and exporting cleaned outputs. -
1_Forecasts.ipynbMain analysis notebook. Loads the cleaned dataset and:- Fits retrodiction models (Harvey/Logistic × Joint/Independent) for temporal holdout validation;
- Fits the main Harvey hierarchical model and generates forecasts;
- Produces all figures (forecasts by category, saturation proportion, Harvey asymmetry, calibration curves);
- Runs sensitivity analyses (skew vs normal likelihood, joint vs independent, threshold sensitivity, conformal prediction intervals);
- Exports numerical results to JSON.
Almost every figure in
Plots/comes from this notebook; the posterior diagnostics inPlots/1-High_level/and the long-horizon calibration curves come from2_Revision_analyses.pyinstead. -
2_Revision_analyses.py(jupytext percent format — opens as a notebook in Jupyter, and VS Code reads its# %%cells natively) Robustness and sensitivity analyses that go beyond the ablations of notebook 1: per-benchmark posterior saturation dates and how they shift across the 8 model variants, long-horizon retrodiction (cutoffs 2022–2025), prior sensitivity on the upper asymptote$L$ , cross-benchmark residual dependence, hyperparameter and per-benchmark$L$ posterior figures, and an audit of the random-chance lower bounds. Results are written toPlots/4-Sensitivity/as CSV/JSON, and LaTeX versions of the tables to$TABLES_DIR(see below). Runs in selectable stages so the expensive refits can be skipped:Stage What it does Cost cheapSaturation dates and variant shifts, posterior figures, residual dependence, lower-bound audit cached fits only figuresRedraws the 11 category forecast panels 1 cached fit retroLong-horizon retrodiction (cutoffs 2022–2024) 3 new MCMC fits priorsAsymptote-prior sensitivity 3 new MCMC fits retro8All 8 variants at the 2025 cutoff (CRPS, RMSE, coverage, calibration curves) 8 new MCMC fits cqrGrouped repeated CQR at the main cutoff, 100 random benchmark splits × 8 variants 8 new MCMC fits uv run python 2_Revision_analyses.py cheap # one stage uv run python 2_Revision_analyses.py cheap figures # or several at once
Each stage writes
Plots/4-Sensitivity/revision_analyses_<stage>_<cutoff>.json. With no argument,cheapruns by default. -
forecasting.pyCore modeling utilities: model construction (build_model), MCMC fitting (fit), temporal holdout validation (temporal_holdout), scoring (CRPS, RMSE, MAE), forecast generation, and conformal prediction coverage (CQR). Alsosaturation_datesandsaturated_proportion(posterior saturation timing, by analytic inversion of the fitted sigmoid) andresidual_diagnostics(cross-benchmark residual correlation, paired by model release). -
plotting.pyMatplotlib plotting utilities with centralized styling, supporting both English (paper/PDF) and French (note/PNG) output, includingplot_L_intervalsandplot_hyperparametersfor posterior diagnostics.
.
├── 0_Process_benchmarks.ipynb # Data loading and normalization
├── 1_Forecasts.ipynb # Model fitting, validation, plotting, and sensitivity analyses
├── 2_Revision_analyses.py # Robustness analyses (saturation dates, retrodiction, priors, residuals)
├── forecasting.py # Core modeling utilities
├── plotting.py # Matplotlib plotting utilities
├── Data/
│ ├── benchmark_data/ # Raw CSV files from EpochAI (~47 files)
│ ├── benchmark_data_RAND/ # RAND Corporation benchmark data
│ ├── benchmark_data_processed/ # Processed/normalized data (output of notebook 0)
│ ├── benchmarks_lower_bounds.csv # Random-chance baselines per benchmark
│ └── human_baselines.csv # Human performance baselines
├── Plots/
│ ├── 0-Note-figures/ # FR note figures (PNG)
│ ├── 1-High_level/ # Saturation proportion, Harvey asymmetry, hyperparameter and L-interval posteriors
│ ├── 2-Forecasts/ # Main forecast trajectories per category (EN paper + FR note)
│ ├── 3-Calibration/ # Calibration curves for all model variants and retrodiction cutoffs
│ └── 4-Sensitivity/ # Ablation figures, plus CSV/JSON results from notebooks 1 and 2
│ └── tables/ # LaTeX tables (default TABLES_DIR; see 2_Revision_analyses.py)
├── Fits/ # Saved model posteriors (NetCDF, gitignored)
├── Paper/ # Bibliography and arXiv preprint sources; other manuscript
│ # working material is kept local and gitignored
└── tmp/ # Jupytext conversions (gitignored)
Only Paper/Benchmark_forecasting.bib, Paper/Arxiv/ and Paper/.latexmkrc are tracked.
2_Revision_analyses.py writes its LaTeX tables to Plots/4-Sensitivity/tables/ by default; point
TABLES_DIR at a manuscript directory to regenerate them in place:
TABLES_DIR=path/to/manuscript/tables uv run python 2_Revision_analyses.py cheapData/benchmarks_lower_bounds.csv— Per-benchmark random-chance performance lower bounds (semicolon-delimited, European decimal notation)Data/human_baselines.csv— Human performance reference points for plotting (columns:benchmark,group,score,note,source)
Let
The score is modeled as a sigmoidal growth curve
where skew=False in the model configuration, a symmetric Normal likelihood is used instead.
The sigmoidal curves model the latent mean performance
The sigmoids are defined on the range
The lower bound Data/benchmarks_lower_bounds.csv for details. It is not necessarily 0, as some benchmarks may have non-zero random-chance performance (e.g. 25% for questions with 4 choices).
The upper bound
The latent mean performance on benchmark
where
The logistic function is defined as:
where
The Harvey curve generalizes the logistic with a shape parameter
where
The observation noise
peaking near the inflection point and shrinking near the bounds, where
The joint models define hierarchical versions where benchmarks share hyperpriors over parameters, allowing benchmarks to borrow statistical strength from each other while keeping benchmark-specific trajectories. When joint=False, each benchmark gets fully independent priors.
Upper asymptotes
where
Growth rates
where
Inflection times
Noise scales
where
Skewness parameters
where skew=False, this parameter is omitted and the likelihood uses a symmetric Normal.
Harvey shape parameters
where
# Install dependencies
uv sync
# Run the data processing notebook
uv run jupyter nbconvert --execute --inplace 0_Process_benchmarks.ipynb
# Run the main analysis as a Python script (recommended over nbconvert,
# which can hit IOPub timeouts on long MCMC sampling cells)
mkdir -p tmp
uv run jupytext --to py:percent 1_Forecasts.ipynb -o tmp/1_Forecasts_run.py
uv run python tmp/1_Forecasts_run.pyOr run interactively in Jupyter / VS Code.
- Run
0_Process_benchmarks.ipynbto generateData/benchmark_data_processed/all_normalized_updated_benchmarks.csv. TheDATA_CUTOFF_DATEparameter (default: 2026-01-01) excludes model results released after that date, ensuring reproducibility even if new data is added to the CSVs. - Open
1_Forecasts.ipynband verify the settings at the top:LANGUAGE/DOCUMENT_TYPE: controls the main figures. Default is"en"/"paper"(PDF output).ALSO_GENERATE_FR: whenTrue(default), the notebook also generates French note figures (PNG) at the end, reusing already-fitted models (no extra MCMC).SAVEFIGS:Trueto save all figures toPlots/.
- Run all cells. The notebook will:
- Fit 4 retrodiction models and produce calibration curves →
Plots/3-Calibration/ - Fit the main model and produce forecasts, saturation, and asymmetry figures →
Plots/1-High_level/andPlots/2-Forecasts/ - Run 4 ablation models (skew/normal × joint/independent) with forecasts, saturation, and calibration →
Plots/4-Sensitivity/ - Compute CQR conformal prediction intervals on all variants →
Plots/4-Sensitivity/ablation_results.json - Generate French (note/PNG) versions of all main figures →
Plots/0-Note-figures/andPlots/2-Forecasts/
- Fit 4 retrodiction models and produce calibration curves →
Runtime: expect 30–60 minutes total (12 MCMC models, ~100 figures).
Note on execution method: jupyter nbconvert --execute may fail on this notebook due to IOPub timeouts during long MCMC sampling steps. The recommended approach is to convert to a Python script with jupytext and run directly (see Quick start above). For interactive use, Jupyter Lab / VS Code handles long-running cells without issue.
MODEL_CONFIG = forecasting.ModelConfig(
sigmoid="harvey", # or "logistic"
joint=True, # hierarchical (True) or independent (False)
top_n=3, # track top-N frontier models
skew=True, # skew-normal (True) or normal (False) likelihood
)The sensitivity analyses section always runs all 4 combinations of joint × skew and produces English paper figures (PDF), regardless of the main LANGUAGE/DOCUMENT_TYPE settings.