Minimal inference library for Hypnos: load an EDF, preprocess, and generate sleep embeddings from pretrained checkpoints.
Project description
Hypnos
Next-Token Prediction Learns Generalisable Representations of Sleep Physiology
Updates
June 2026
- Initial release: the pretrained Hypnos model is available on the HuggingFace Hub, together with a minimal inference library for generating sleep embeddings from EDF recordings. Paper: arXiv:2606.09605.
Installation
pip install hypnos # or: uv add hypnos
To work on the library itself, clone the repo and install from source:
uv sync # or: pip install -e .
Usage
Load an EDF, preprocess, and generate embeddings from the pre-trained Hypnos model:
from hypnos.embedding import embed_edf
emb = embed_edf("recording.edf")
# emb: dict {modality_name: np.ndarray [n_seconds, embed_dim] float16}
# e.g. emb["eeg_c3"], emb["ecg"], ... — one vector per second, per present modality
Embeddings are returned per modality (z^i_t) at the model's native 1 Hz resolution
(one vector per second). Only modalities present in the recording appear in the dict. The
model defaults to the released weights on the Hub (joncarter/hypnos); pass a repo id or
local path to override.
The pipeline runs: EDF → preprocess (resample / causal filter / normalize) → per-modality
tokenization → RQ-Transformer → 1 Hz per-modality embeddings. For US recordings
pass notch_freq=60.0 (the default is 50 Hz) to match the powerline frequency.
Reuse a loaded model across recordings with the step-by-step API:
from hypnos.embedding import load_model, preprocess_edf, tokenize, embed
model, tokenizers, meta = load_model(device="cpu")
signals = preprocess_edf("recording.edf", meta)
tokens, modality_mask, channel_ids = tokenize(tokenizers, meta, signals)
emb = embed(model, tokens, modality_mask, channel_ids, meta) # {name: [T, D]}
Pooling
Hypnos produces embeddings at 1 Hz for each modality. In our experiments, we found that simple pooling over modalities and timescales works well for downstream tasks. For example, to produce a single embedding per 30-second sleep epoch:
import numpy as np
emb = embed_edf("recording.edf")
# Average over modalities -> [n_seconds, embed_dim] (the summary vector z_t)
fused = np.mean(list(emb.values()), axis=0)
# Mean-pool over each 30-second epoch -> [n_epochs, embed_dim]
n_epochs = fused.shape[0] // 30
epochs = fused[: n_epochs * 30].reshape(n_epochs, 30, -1).mean(axis=1)
Generation
Hypnos is fully generative, and can be used to auto-regressively forecast physiological signals conditioned on input context:
from hypnos.embedding import load_model, synthesize
model, tokenizers, meta = load_model()
print([m.name for m in meta.modalities]) # available modality names
# Jointly generate three modalities from a cold start (no recording needed).
signals = synthesize(model, tokenizers, meta,
modalities=["eeg_c3", "ecg", "resp_thx"], num_steps=30)
# signals: {name: 1-D waveform at the modality's native rate}
# signals["ecg"] → 30 s @ 128 Hz = (3840,); signals["resp_thx"] → (960,)
Pass prompt_tokens (e.g. from tokenize(...)) to forecast a continuation of a real
recording.
EEG, ECG and respiration jointly generated by Hypnos from a cold start (30 s).
Pretrained checkpoints
The whole model — the RQ-Transformer and all 5 tokenizers — ships as a single
safetensors file, hypnos.safetensors. All weights live under namespaced keys
(model/…, tok/<name>/…) and the config (model + tokenizer construction kwargs, modality
layout) is a JSON string in the file's metadata, so loading is fully self-contained and needs
no config framework. safetensors is a pure-tensor format — no arbitrary-code unpickling.
load_model / embed_edf default to the released weights on the Hub, and also accept:
- a HuggingFace repo id, e.g.
"owner/hypnos"(downloads the bundle file), - a local path to the
.safetensorsbundle, - a local directory containing
hypnos.safetensors.
Devices: CUDA, CPU, and Apple Silicon (MPS) are all supported. On CUDA, windowed attention uses a fused
flex_attentionkernel.flex_attentionhas no Metal kernel, so on MPS — and in eager mode on CPU — the model falls back to a dense-mask SDPA path that materialises a full(chunk, chunk)score matrix per head: peak memory grows ~quadratically withchunk_tokens(≈8 GB at the default of 2048; ≈19 GB at 4096). Recording length itself does not raise peak memory — chunks run sequentially — so a full night works on CPU or MPS (a 3 h record takes ~50 s at ~11 GB RAM on CPU). On Apple Silicon this memory is shared with the system, so lowerchunk_tokensif constrained.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file hypnos-0.1.0.tar.gz.
File metadata
- Download URL: hypnos-0.1.0.tar.gz
- Upload date:
- Size: 578.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9fc02e73b7e1738abed8208b8217d1a59669d5749e4ba3c85b1309389f8088e9
|
|
| MD5 |
c1ea796ded6dbfe4fa064973412f92dd
|
|
| BLAKE2b-256 |
89ed87b028bb2fed28d43cd2f618f658b4d7c0d7ce0203bb32b650c96e058073
|
Provenance
The following attestation bundles were made for hypnos-0.1.0.tar.gz:
Publisher:
publish.yml on joncarter1/hypnos
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
hypnos-0.1.0.tar.gz -
Subject digest:
9fc02e73b7e1738abed8208b8217d1a59669d5749e4ba3c85b1309389f8088e9 - Sigstore transparency entry: 1924477719
- Sigstore integration time:
-
Permalink:
joncarter1/hypnos@7fc6c1c4a7a146b540e06d92a51441591860e82f -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/joncarter1
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@7fc6c1c4a7a146b540e06d92a51441591860e82f -
Trigger Event:
release
-
Statement type:
File details
Details for the file hypnos-0.1.0-py3-none-any.whl.
File metadata
- Download URL: hypnos-0.1.0-py3-none-any.whl
- Upload date:
- Size: 72.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
539f75f9309d4ef35700e6247b190325d889f64375bfb5189f546ae7b054cd7b
|
|
| MD5 |
ff8c37e4c84bd5fabb94973a9b8bbff9
|
|
| BLAKE2b-256 |
83af7c745b014e8360223a16450421a71ae3b497098ae9310823f30e46cc5aec
|
Provenance
The following attestation bundles were made for hypnos-0.1.0-py3-none-any.whl:
Publisher:
publish.yml on joncarter1/hypnos
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
hypnos-0.1.0-py3-none-any.whl -
Subject digest:
539f75f9309d4ef35700e6247b190325d889f64375bfb5189f546ae7b054cd7b - Sigstore transparency entry: 1924477828
- Sigstore integration time:
-
Permalink:
joncarter1/hypnos@7fc6c1c4a7a146b540e06d92a51441591860e82f -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/joncarter1
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@7fc6c1c4a7a146b540e06d92a51441591860e82f -
Trigger Event:
release
-
Statement type: