🧠 Open EEG Bench
Benchmark any EEG foundation model with one function call.
✨ Why Open EEG Bench?
- 🎯 One function, all results — Call
benchmark()with your model and get a full evaluation across 12 datasets - 📦 Zero preprocessing — All datasets are pre-windowed and hosted on HuggingFace Hub, ready to use
- ⚡ 8 fine-tuning strategies — Frozen linear probing, ridge probing, LoRA, IA3, AdaLoRA, DoRA, OFT, and full fine-tuning
- 🔌 Bring your own model — Any PyTorch model that takes EEG input and returns features works out of the box
- 🔒 Reproducible by design — A single config object fully describes a run. No YAML files, no hidden state
🚀 Installation
pip install open-eeg-bench
🏁 Benchmark your model
import open_eeg_bench as oeb
results = oeb.benchmark(
model_cls="my_package.MyModel", # import path to your model class
checkpoint_url="https://my-weights.pth",
)
print(results) # pd.DataFrame
This runs linear probing on all 12 datasets and returns a DataFrame with one row per result.
You can pick specific datasets, fine-tuning strategies, classification heads and number of initialization seeds:
results = oeb.benchmark(
model_cls="my_package.MyModel",
checkpoint_url="https://my-weights.pth",
datasets=["arithmetic_zyma2019", "bcic2a", "physionet"],
finetuning_strategies=["frozen", "lora"],
peft_target_modules=[ # necessary for LoRA, IA3, AdaLoRA, OFT, and DoRA
"encoder.linear1",
"encoder.linear2"
],
heads=["linear_head", "mlp_head"],
n_seeds=5,
)
Need to run on a SLURM cluster? No sbatch scripts needed — see Running on a cluster.
📐 Model requirements
Your model only needs to:
- Accept input of shape
(batch, n_chans, n_times) - Return output of shape
(batch, n_outputs) - Have a named module for the classification head (default:
self.final_layer)
⚙️ benchmark() parameters
| Parameter | Required | Description |
|---|---|---|
model_cls |
Yes | Dotted import path to your model class |
hub_repo |
One of three | HuggingFace Hub repo ID for weights |
checkpoint_url |
One of three | URL to pretrained weights |
checkpoint_path |
One of three | Local path to pretrained weights |
peft_target_modules |
For PEFT | Module names to adapt (e.g. ["to_q", "to_k", "to_v"]) |
peft_ff_modules |
For IA3 | Feedforward module names for IA3 adapter |
model_kwargs |
No | Extra kwargs for the model constructor |
head_module_name |
No | Name of the head module (default: "final_layer") |
normalization |
No | Post-window normalization |
datasets |
No | Dataset names to evaluate on (default: all 12) |
heads |
No | Head names: "linear_head", "mlp_head", "original_head" (default: ["linear_head"]) |
finetuning_strategies |
No | Strategy names: "frozen", "ridge_probe", "lora", "ia3", "adalora", "dora", "oft", "full_finetune", "two_stages" (default: ["frozen"]) |
n_seeds |
No | Number of random seeds (default: 3) |
device |
No | "cpu", "cuda", etc. (default: "cpu") |
infra |
No | Infrastructure config for caching and cluster submission (see cluster docs) |
max_workers |
No | Max simultaneous SLURM jobs (default: 256) |
📊 Available datasets
All 12 datasets are pre-windowed and hosted on HuggingFace Hub:
| Dataset | HF ID | Classes | Window size | Task |
|---|---|---|---|---|
| Arithmetic (Zyma 2019) | braindecode/arithmetic_zyma2019 |
2 | 5 s | Mental arithmetic vs. rest |
| BCI Competition IV 2a | braindecode/bcic2a |
4 | 4 s | Motor imagery |
| BCI Competition 2020-3 | braindecode/bcic2020-3 |
5 | 3 s | Imagined speech |
| PhysioNet MI | braindecode/physionet |
4 | 3 s | Motor imagery |
| CHB-MIT | braindecode/chbmit |
2 | 10 s | Seizure detection |
| FACED | braindecode/faced |
9 | 10 s | Emotion recognition |
| ISRUC-Sleep | braindecode/isruc-sleep |
5 | 30 s | Sleep staging |
| MDD (Mumtaz 2016) | braindecode/mdd_mumtaz2016 |
2 | 5 s | Depression detection |
| SEED-V | braindecode/seed-v |
5 | 1 s | Emotion recognition |
| SEED-VIG | braindecode/seed-vig |
regression | 8 s | Vigilance estimation |
| TUAB | braindecode/tuab |
2 | 10 s | Abnormal EEG detection |
| TUEV | braindecode/tuev |
6 | 5 s | EEG event classification |
Preprocessing: Window lengths are dataset-dependant (see table above). All datasets are high-pass filtered at 0.1 Hz, except for tasks with short trial windows (2 s or less), where we use 0.5 Hz. All datasets are resampled to 100 Hz. Model-specific normalization (e.g. z-scoring) can be applied via the normalization parameter.
🧩 Available fine-tuning strategies
| Strategy | Description | Trainable params |
|---|---|---|
Frozen() |
Freeze encoder, train only the head | ~0.01% |
"ridge_probe" |
Closed-form ridge regression probing (no hyperparameter tuning needed) | ~0.01% |
LoRA(r, alpha) |
Low-Rank Adaptation | ~1-5% |
IA3() |
Inhibiting and Amplifying Inner Activations | ~0.1% |
AdaLoRA(r, target_r) |
Adaptive rank allocation | ~1-5% |
DoRA(r, alpha) |
Weight-Decomposed LoRA | ~1-5% |
OFT(block_size) |
Orthogonal Fine-Tuning | ~1-10% |
FullFinetune() |
Train all parameters | 100% |
TwoStages() |
Frozen head for 10 epochs, then unfreeze and train all | 100% |
📄 License
BSD-3-Clause (see LICENSE.txt)
📣 Citation
If you use Open EEG Bench in your research, please cite it. Machine-readable metadata is provided in CITATION.cff — used by GitHub's "Cite this repository" button, reference managers, and Zenodo when archiving releases.
@software{open_eeg_bench,
title = {Open EEG Bench: Benchmarking parameter-efficient fine-tuning of EEG foundation models},
author = {Guetschel, Pierre and Aristimunha, Bruno and Truong, Dung and Kokate, Kuntal and Moreau, Thomas and Tangermann, Michael and Delorme, Arnaud},
year = {2026},
url = {https://github.com/braindecode/OpenEEGBench},
doi = {10.5281/zenodo.19698863}
}
You may also be interested in the following articles which use Open EEG Bench:
@inproceedings{guetschel2026openeegbench,
title = {Toward {OpenEEG-Bench}: A Live Community-Driven Benchmark for {EEG} Foundation Models},
author = {Guetschel, Pierre and Aristimunha, Bruno and Truong, Dung and Kokate, Kuntal and Tangermann, Michael and Delorme, Arnaud},
booktitle = {Proceedings of the 34th European Signal Processing Conference (EUSIPCO 2026)},
year = {2026},
address = {Bruges, Belgium},
month = aug,
pages = {1--5},
organization = {EURASIP},
}
📚 Further reading
- Running on a cluster — SLURM submission,
infraoptions, caching, execution modes - Running with Benchopt — Alternative CLI-based workflow using the Benchopt framework
- Advanced usage —
Experimentclass, architecture overview, braindecode integration - Built-in backbones — Pretrained models shipped with the benchmark
- Contributing — How to add backbones, datasets, or fine-tuning strategies
- References — Citations and key libraries
Metadata
Release files for open-eeg-bench 0.6.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 | Provenance | Actions |
|---|---|---|---|---|
| open_eeg_bench-0.6.0.tar.gz | 50.3 kB | With provenance | Details for open_eeg_bench-0.6.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| open_eeg_bench-0.6.0-py3-none-any.whl | Python 3 | none | any | Details for open_eeg_bench-0.6.0-py3-none-any.whl |
Total release size: 94.8 kB
Release files / open_eeg_bench-0.6.0.tar.gz
| Download URL | open_eeg_bench-0.6.0.tar.gz |
|---|---|
| Size | 50.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
2252ae17e137cecf50ccc07850f66acbf400d78c1c76a02edab0b66bcac8bf14
|
|
BLAKE2b-256 checksum How to use checksums |
0749cdbbd40a9efb8b2ee244792ffb0ca2900f0de86fc8231187e68e0c0032c3
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jun 2, 2026.
Transparency logRelease files / open_eeg_bench-0.6.0-py3-none-any.whl
| Download URL | open_eeg_bench-0.6.0-py3-none-any.whl |
|---|---|
| Size | 44.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
40c0a8fed3b01c282df11e761dd983ab745970d654d3e33786cfd44b829b8043
|
|
BLAKE2b-256 checksum How to use checksums |
0afdd1285e515d65566d587d0c45117d0b597e53c6cf8a7c745cfb51df2cfc7e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jun 2, 2026.
Transparency logSecurity for open-eeg-bench 0.6.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for open_eeg_bench-0.6.0.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jun 2, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.