DeepECG-SSL-CLSA-CVD

Fine-tuned DeepECG-SSL (self-supervised 12-lead ECG transformer; Nolin-Lapalme et al., Eur Heart J 2026, doi:10.1093/eurheartj/ehaf1119) to predict incident cardiovascular disease over a median 5.8 years in the Canadian Longitudinal Study on Aging (CLSA). The model accompanies the manuscript "A Lab-Free ECG Foundation Model Versus Guideline Risk Scores for Incident Cardiovascular Disease: Development in CLSA and External Validation at the Montreal Heart Institute".

What is in this repository

  • weights/deepecg_ssl_clsa_cvd_fold{0-4}.safetensors: the five cross-validation fold models (full fine-tuning; ECG only).
  • model_params.json:
    • per-fold Platt calibration parameters;
    • the Model A+ logistic equation (DeepECG-SSL score + age + sex + hypertension; no blood test).
  • inference.py: a loader and prediction functions. It needs fairseq-signals and the matching DeepECG-SSL v2 (amplitude-preserved) encoder checkpoint for the architecture.

Input

  • 12-lead resting ECG, 10 s, resampled to 250 Hz: an array of shape (12, 2500).
  • Units are millivolts, with no per-lead normalisation.
  • Standard lead order: I, II, III, aVR, aVL, aVF, V1โ€“V6.

Performance (from the manuscript)

CLSA held-out test set (n = 3,906; 394 events). The guideline scores need a blood test; Model A+ does not.

Model AUROC
Model A+ 0.733 (95% CI 0.707โ€“0.759)
PREVENT 0.715
PCE 0.709
SCORE2/OP 0.708
FRS 0.689
  • Where the gain comes from: it is driven by the non-specific self-reported "heart disease" outcome item.
  • Endpoints the gain does not cover: for hard atherosclerotic endpoints, PREVENT and SCORE2 are as good or better.

External validation at the Montreal Heart Institute (n = 21,647; 6-year hard MACE; DeepECG-SSL + age + sex with CLSA coefficients):

Model AUROC
DeepECG-SSL + age + sex 0.761
Age + sex 0.728
  • By component: the gain is in heart failure and stroke, not in myocardial infarction.
  • Calibration: absolute risks need local recalibration before use.

Intended use and limitations

  • Research use only. This is not a medical device and has not been prospectively validated.
  • Training data: CLSA, a mostly White community cohort aged 45โ€“85, with GE CardioSoft ECGs.
  • Other populations and devices: performance may differ.
  • No CLSA participant data are included in this repository.

Citation

Please cite the manuscript (citation to be added on publication) and DeepECG-SSL (Nolin-Lapalme A, et al. Eur Heart J 2026;47:2174โ€“2186).

Strict inference package

The clsa_cvd package adds strict five-fold checkpoint loading, explicit raw-source mV conversion, full-precision logistic coefficients and the external age/sex variant. It uses the same five fold weights already staged in this repository. The existing root inference.py API remains present for compatibility; use this package for the external variant and strict input/checkpoint validation.

from clsa_cvd.model import CLSACVDModel

model = CLSACVDModel(
    weights_dir="weights",
    base_checkpoint="/approved/models/deepecg-ssl-v2-wcr-amp-preserved-encoder.pt",
    params_path="clsa_cvd/model_params.json",
    device="cuda:0",
    precision="float32",
)
# ecg_mv: finite float32 (N, 12, 2500), 10 seconds at 250 Hz in mV.
# age/female/hypertension: one numeric value per ECG; female/HTN are binary.
pred = model.predict(ecg_mv, age, female, hypertension, batch_size=32)
# p_ecg, risk_Aplus, ecg_logit_uncal, risk_ecg_age_sex

Lead order: I, II, III, aVR, aVL, aVF, V1โ€“V6. For raw NPY inputs use clsa_cvd.preprocessing.prepare_waveform or load_waveform with an explicit format: clsa = 500-Hz CardioSoft ADC ร—0.005 then polyphase resampling; muse = 250-Hz MUSE ADC ร—0.00488; mv250 = already in mV at 250 Hz. No spectral-power normalization or per-lead z-scoring is applied.

risk_ecg_age_sex uses the logit of the mean uncalibrated fold probabilities. It is the transported MHI variant, not A+ with hypertension set to zero, and its absolute risks require local recalibration. A+ uses the mean of Platt-calibrated fold probabilities with age, female and physician-diagnosed hypertension.

The new package defaults to IEEE float32 with TF32 disabled. Historical test predictions used CUDA bfloat16, batch 128. Select precision="bfloat16" and batch size 128 to reproduce that arithmetic. On all 3,906 CLSA test participants, historical-mode predictions matched the archive within 9e-8. Float32 is stable under the tested single/batch ordering but differs from the historical ECG probabilities by up to 0.001780 and A+ by 0.000998. Full-precision equation coefficients reproduce archived A+ outputs within 2.3e-16 when supplied stored ECG probabilities. Do not assume bit-identical results across precision modes.

Validated Python environment: PyTorch NVIDIA 26.08, CUDA 13.4, Python 3.12; fairseq-signals Jwoo5/fairseq-signals commit f8f0ff1c788a82c2059cb452cd5462898867489e. requirements-clsa.txt records the observed direct dependency versions. The matching encoder checkpoint is still required to define the architecture; its SHA-256 and fold artifact hashes are in clsa_cvd/artifacts.json. Container build/run has not yet been verified.

synthetic_validation.json describes non-participant sinusoidal fixtures and expected outputs. No participant-level data are included in this update.

Pretraining overlap and subgroup reporting

No patient crosswalk between the encoder pretraining sources and the MHI validation cohort is available. Patient-level pretraining/validation overlap has therefore not been independently verified. This repository does not claim a reproduced zero-overlap audit.

Exploratory racial/cultural subgroup reporting is limited by small event counts and disclosure restrictions; suppressed results do not establish fairness in those groups. Disclosure and fairness review were confirmed complete by the project owner on 23 October 2026.

Environment setup

The reference environment uses the NVIDIA PyTorch 26.08 container. In that environment, install the direct dependencies and use the pinned fairseq source:

python -m pip install -r requirements-clsa.txt
git clone https://github.com/Jwoo5/fairseq-signals.git
git -C fairseq-signals checkout f8f0ff1c788a82c2059cb452cd5462898867489e
export PYTHONPATH="$PWD/fairseq-signals${PYTHONPATH:+:$PYTHONPATH}"

Download this repository (including weights/) using the Hugging Face client. Supply the matching encoder checkpoint separately; its public download location has not been verified. Verify its SHA-256 against clsa_cvd/artifacts.json. The fine-tuned fold weights are included here; the separate base encoder is not.

Downloads last month

-

Downloads are not tracked for this model. How to track
Inference Providers NEW
This model isn't deployed by any Inference Provider. ๐Ÿ™‹ Ask for provider support