Text Classification
Transformers
Safetensors
fela-ecg
fela
fourier-neural-operator
fno
cpu
on-device
ecg
biosignal
healthcare
time-series
custom_code
Eval Results (legacy)
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
| license: other | |
| license_name: lowdown-labs-lovely-license-1.0 | |
| license_link: LICENSE | |
| tags: | |
| - fela | |
| - fourier-neural-operator | |
| - fno | |
| - cpu | |
| - on-device | |
| - ecg | |
| - biosignal | |
| - healthcare | |
| - time-series | |
| library_name: transformers | |
| model-index: | |
| - name: fela-ecg | |
| results: | |
| - task: | |
| type: time-series-classification | |
| name: ECG diagnostic classification | |
| dataset: | |
| type: ptb-xl | |
| name: PTB-XL superdiagnostic | |
| metrics: | |
| - type: auroc | |
| value: 0.9248 | |
| name: macro AUROC | |
| # 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: | |
| ```python | |
| 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: | |
| ```python | |
| 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 | |
| ```bibtex | |
| @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](https://gimmelowdown.com/pricing). |