Skip to main content
The MRL model is a Matryoshka-distilled version of EPI-250k. It maps a 30-second multi-channel EEG epoch to an L2-normalized vector. The 768d output can be truncated to any prefix of [768, 384, 192, 48, 16] dimensions without re-running the model.

Loading the model

The model auto-downloads from HuggingFace on first call (~215 MB cached locally). Pass token=... for explicit authentication, or run huggingface-cli login once. From a local Lightning checkpoint:

One-call usage

model.embed chains preprocessing + prediction and returns a numpy array — the most common shape users want for downstream sklearn / FAISS work.

Step-by-step

model.predict() returns L2-normalized embeddings as a torch tensor on the model’s device — cosine similarity reduces to a dot product. Valid dimensions: 768, 384, 192, 48, 16. See Benchmarks for accuracy at each dimension. Input is auto-moved to the model device.

Matryoshka

Compute once at full resolution, truncate later:
model.predict() normalizes for you. Manual truncation requires re-normalization for cosine distance to work correctly.

Classification

Similarity / retrieval

For large corpora the 48d embeddings work well with FAISS / HNSW.

Batch processing

Preprocessing details

ne.preprocess matches the exact pipeline used to train the model:
  1. Bandpass filter (1-100 Hz, 4th-order Butterworth)
  2. Notch filter (50 Hz and 100 Hz)
  3. Resample to 250 Hz
  4. Segment into 30-second epochs (pad if shorter)
  5. Average channels into 8 canonical brain regions: Frontal, Central, Temporal Left, Temporal Right, Parietal, Occipital, EOG, ECG
  6. Convert to the temporal matrix representation (224x224 image per channel)
Channels are matched to regions from 10-20 names (Fp1, C3, O2, …). Unmatched channels are silently dropped. Missing regions are zero-filled. This works on any montage — 4-channel frontal, 19-channel 10-20, 64-channel HD-EEG, intracranial.
The default is a 1-second sliding window of 30s epochs — 30x denser than non-overlapping, gives smooth trajectories in the embedding space. Pass stride_seconds=30.0 for non-overlapping epochs (typical when each 30s window has its own classification label).