Instructions to use lowdown-labs/fela-ecg with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use lowdown-labs/fela-ecg with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("text-classification", model="lowdown-labs/fela-ecg", trust_remote_code=True)# Load model directly from transformers import AutoModelForSequenceClassification model = AutoModelForSequenceClassification.from_pretrained("lowdown-labs/fela-ecg", trust_remote_code=True, dtype="auto") - Notebooks
- Google Colab
- Kaggle
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 inconfig.json. Thepreprocesshelper inmodeling.pycan 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.safetensorsplusconfig.jsonfor the safetensors load path (fp32, wired at push).verify.pyruns 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(--smokerebuilds 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
- PTB-XL: Wagner et al. (2020), Scientific Data 7, 154. https://doi.org/10.1038/s41597-020-0495-6 . PhysioNet project (v1.0.3): https://physionet.org/content/ptb-xl/1.0.3/ (project DOI https://doi.org/10.13026/kfzx-aw45 ). Also cite PhysioNet: Goldberger, A. L., et al. (2000). PhysioBank, PhysioToolkit, and PhysioNet. Circulation, 101(23), e215-e220. https://doi.org/10.1161/01.CIR.101.23.e215 . License: CC-BY-4.0 ( https://physionet.org/content/ptb-xl/view-license/1.0.3/ ). Commercial use is allowed with attribution.
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
- Fourier Neural Operator: Li, Z., et al. (2021). Fourier Neural Operator for Parametric Partial Differential Equations. ICLR. https://arxiv.org/abs/2010.08895
- PyTorch: Paszke, A., et al. (2019). NeurIPS. https://arxiv.org/abs/1912.01703
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
Papers for lowdown-labs/fela-ecg
PyTorch: An Imperative Style, High-Performance Deep Learning Library
Evaluation results
- macro AUROC on PTB-XL superdiagnosticself-reported0.925