You need to agree to share your contact information to access this model

This repository is publicly accessible, but you have to accept the conditions to access its files and content.

Log in or Sign Up to review the conditions and access this model content.

DISCLAIMER

This model is a research preview. The license for the dataset may prohibit commercial use. Please respect this. Lowdown Labs has put together this model in the interest of advancing public science.

FELA-ECG: On device 12 lead ECG classifier

FELA-ECG reads a 10 second 12 lead electrocardiogram and returns the probability of five diagnostic groups: normal, myocardial infarction (which could be a heart attack, past or acute), ST/T wave change, conduction disturbance, and hypertrophy (which is a thickened heart muscle). It is a small model that runs on a plain CPU with no GPU, so it can sit inside a wearable patch, a Holter recorder, a bedside monitor, or in an on premises hospital tool and score ECGs without sending the recording to the cloud with respect for low computing power. Ideally, this model could be used to help improve consumer electronics to monitor user health and safety. This does not provide medical diagnoses.

What goes in, what comes out

  • Input: one 10 second 12 lead ECG sampled at 100 Hz, shape (1, 1000, 12) (1000 time samples, 12 leads), in the standard lead order I, II, III, aVR, aVL, aVF, V1 - V6, in millivolts. Each lead is z scored (centered and scaled) with the training set statistics that ship in config.json. The preprocess helper in modeling.py can help do this for you.
  • Output: five independent probabilities, one per diagnostic superclass (NORM, MI, STTC, CD, HYP). The head uses a sigmoid, so this is multi label: one ECG can carry more than one finding, and the five numbers do not sum to one. A clinician sets the alert threshold per class to trade sensitivity against specificity for the use.
  • In plain terms: "this 10 second strip looks like an inferior myocardial infarction with a conduction problem" comes out as high MI and CD probabilities.

Why we built it this way

The main sequence mixer is a Fourier Neural Operator, a filter the model learns and applies in the frequency domain. An ECG is a periodic signal, which is exactly what a Fourier operator is good at reading, so the architecture fits the data.

There is a second branch that reads the short time Fourier transform (the spectrogram) directly, and learned attention pooling summarizes both branches into the five class decision. The model has no long range all pair attention, so its working memory is small and fixed no matter how long the monitor has been running.

That is what lets it run continuously on a low power CPU next to the patient, with no cloud connection and the recording never leaving the device.

The shipped model is a single ~15.2M parameter student, distilled from a three member ensemble (different seeds, mixer patterns, and patch sizes), then quantized to int8 for deployment.

Performance

Speed and footprint, measured on CPU (AMD EPYC 9555, batch size 1, median of 20 runs).

Format Size on disk Peak working RAM
fp32 60.64 MB 0.03 MB
bf16 30.32 MB 0.03 MB
int8 16.47 MB 0.03 MB

The model classifies a full 10 second 12 lead ECG in 17.0 ms on one CPU core and 10.3 ms on four cores (fp32 profile), and its working RAM is 0.03 MB, which is why the whole thing could fit in a small single board computer. Throughput on one core is 58.71 windows per second. int8 dynamic quantization brings the model to 16.47 MB on disk (the shipped size is 16.5 MB) and holds accuracy (see below).

Latency and size were measured on an x86 server CPU (AMD EPYC 9555).

Continuous stream numbers (real time factor and RAM drift over a multi hour stream) are not in the standardized profile yet and are marked pending final evaluation. A separate stream benchmark (8 threads, int8) reported flat RAM (drift about +0.0 MB over two hours of streamed ECG) and a high real time factor; those are from the stream test, not the standardized single window profile, so they are not quoted as a headline figure here.

What the standardized profile does show is a 0.03 MB working set and a 17.0 ms single window latency, and the architecture carries no KV cache and keeps O(1) state per window.

Accuracy

Protocol: PTB-XL v1.0.3, 100 Hz, the official recommended split (folds 1 - 8 train, fold 9 validation, fold 10 test, n=2158), diagnostic superclass setting (5 classes), metric is macro AUROC (the unweighted mean of the per class area under the ROC curve). The checkpoint is selected on the validation fold only; the test fold is scored once. This is the same protocol as the PTB-XL benchmark paper, so the numbers are directly comparable.

Benchmark Metric This model (fp32) This model (int8) Baseline (named) Source
PTB-XL superdiagnostic (5-class) macro AUROC 0.9248 0.9243 xresnet1d101 (published) 0.925 AUDIT_ecg.json

The shipped int8 student reaches 0.9243 macro AUROC, within 0.001 of the xresnet1d101 CNN specialist at 0.925 on the same protocol, and the fp32 student is 0.9248. In other words, the v3 model essentially matches the strong published CNN baseline, at 15.2M parameters and CPU real time speed. int8 dynamic quantization on the linear layers is close to lossless: 0.9243 versus 0.9248 fp32, a change of -0.0005.

Per Class test AUROC

Format NORM MI STTC CD HYP
fp32 0.946 0.928 0.936 0.926 0.888
int8 (shipped) 0.946 0.927 0.936 0.925 0.887

NORM (normal) is the easiest class and HYP (hypertrophy) is the hardest, which matches the pattern in the published PTB-XL benchmarks. The distilled student slightly exceeds the source ensemble, because during distillation it also sees the hard labels and fresh augmentation.

How to run it

See quickstart/ for a runnable example. The short version:

import torch
from modeling import load_model, preprocess
m = load_model("model.safetensors")
# raw: a (1000, 12) or (12, 1000) array, 10 s of 12 lead ECG at 100 Hz, in millivolts

x = preprocess(raw, m.cfg)
probs = m.predict(x)

The loader detects the int8 checkpoint and applies dynamic quantization before loading. For an interactive playground, see the Hugging Face Space in space/.

Loading with standard tooling

The repo ships config.json (the architecture hyperparameters and the per lead normalization statistics) and a self-contained modeling.py with a load_model / from_pretrained entry point. A few lines load the model from a Hugging Face repo, a local directory, or a checkpoint:

from huggingface_hub import hf_hub_download
from modeling import load_model
m = load_model("/path/to/weights_dir") # OR
m = load_model("lowdown-labs/fela-ecg")

The fp32 weights are shipped as model.safetensors.

Serving artifacts

  • model.safetensors plus config.json for the safetensors load path (fp32, wired at push).
  • verify.py runs a fixed sample input and checks the output shape and a verification value.

For serving at scale, use the separate CPU native FELA server (https://github.com/Lowdown-Labs/fela_server). It runs this model on CPU with no GPU required. The quickstart here is the minimal single process path; on a Raspberry Pi the deploy path would be the ONNX or TFLite export above.

Training data

  • PTB-XL v1.0.3 (Wagner et al. 2020, Scientific Data; PhysioNet), the 100 Hz 12 lead records, superdiagnostic 5 class multi label setting (NORM, MI, STTC, CD, HYP). Official stratified folds: train 1 - 8 = 17,084 records, validation fold 9 = 2,146, test fold 10 = 2,158. Per lead z normalization uses training fold statistics only.
  • License: Creative Commons Attribution 4.0 International (CC-BY-4.0). Open access, no credentialed access, no data use agreement. Commercial use is permitted with attribution to the PTB-XL authors and PhysioNet. Full split, size assertions, and license details are reproduced in train.py (--smoke rebuilds the split and asserts the test count of 2158).

No teacher model outside the FELA family was distilled from; the student was distilled from a three member FELA-ECG ensemble trained on the same PTB-XL folds.

Intended use, limitations, and safety

What it is for: the inference core inside a clinical or consumer ECG product, running on device or on premises. Fit includes 24/7 wearable and patch monitoring (continuous abnormality flagging on a smartwatch or chest patch, no cloud round trip), Holter and ambulatory review (scan a long recording and surface superclass findings for a technician), ICU and bedside early warning (raise an alert when a class probability crosses a clinician set threshold), and integration with WFDB / PhysioNet tooling (it reads standard WFDB records).

What it is not for: FELA-ECG is not a medical device and is not a diagnosis. The outputs are probabilities for triage and decision support. Do not use it as the sole basis for a care decision, and do not deploy it in patient care without independent clinical validation and the regulatory clearance required in your jurisdiction. This is a medical adjacent model; treat its output as a flag for a clinician to review, not an answer. This is a research preview, that we are releasing as part of our mission to supercharge public science with responsible computing.

Privacy: the model runs on the device or on premises. The ECG does not have to leave the machine, which is the point for settings that cannot or will not send patient data off site.

Evaluated conditions and known failure modes:

  • Accuracy is at parity with, not ahead of, the strongest published CNN specialist (0.9243 int8 versus xresnet1d101 0.925 on the same protocol). We do not claim to beat it.
  • Single dataset: trained and evaluated only on PTB-XL. Generalization to other acquisition hardware, lead placements, populations, and noise profiles is not established and must be validated before any clinical use.
  • Five superclasses only. The finer subclass and full statement PTB-XL settings are not trained here.

How to cite

@misc{lowdownlabs_felaecg,
  title  = {FELA-ECG: On device Fourier Neural Operator classifier for 12 lead ECG},
  author = {Lowdown Labs},
  year   = {2026},
  note   = {Model card}
}

You must also cite the dataset used:

  • Wagner, P., Strodthoff, N., Bousseljot, R.-D., Kreiseler, D., Lunze, F. I., Samek, W., & Schaeffter, T. (2020). PTB-XL, a large publicly available electrocardiography dataset. Scientific Data, 7, 154. https://doi.org/10.1038/s41597-020-0495-6

Acknowledgements and references

Dataset

Baseline

  • Strodthoff, N., Wagner, P., Schaeffter, T., & Samek, W. (2021). Deep Learning for ECG Analysis: Benchmarks and Insights from PTB-XL. IEEE Journal of Biomedical and Health Informatics, 25(5), 1519-1528. https://doi.org/10.1109/JBHI.2020.3022989 (the xresnet1d101 superdiagnostic macro-AUROC of 0.925 is the reference).

Methods and code

Model family

This is part of the FELA family from Lowdown Labs: one Fourier Neural Operator architecture across many modalities, all CPU native and subquadratic. This repo is pushed as lowdown-labs/fela-ecg. Sibling repos share no weights, so none carries a base_model link.

License

Released under the Lowdown Labs Lovely License 1.0 (CC BY-NC 4.0 + Hippocratic License 3.0). See LICENSE. For most LL models, a commercial license may be available; contact Lowdown Labs.

Downloads last month
2
Safetensors
Model size
15.2M params
Tensor type
F32
·
Inference Providers NEW
This model isn't deployed by any Inference Provider. 🙋 Ask for provider support

Papers for lowdown-labs/fela-ecg

Evaluation results