Downloads · 30 days
0
sfourdrinier/opencgm-stateevent
opencgm-stateevent is a feature extraction model from sfourdrinier. Use it when you need embeddings to search or compare text. It is set up for onnx. The card lists the license as other.
See LICENSE-WEIGHTS for the full text and LICENSENOTES.md for the decision record. A commercial license for the weights can be negotiated with the maintainer (@sfourdrinier on GitHub).
Downloads · 30 days
0
Access
Public
Updated Aug 30, 2026
Repo size
2 MB
Likes
0
Public
Click a slice to open those files.
.onnx2 MB · 92%
From the Hugging Face model README
opencgm_stateevent encoder (v0.1.0)| Component | License |
|---|---|
Encoder (glucofm_encoder.onnx) | CC-BY-NC-4.0 (research / non-commercial) |
Probe heads (glucofm_heads.json) | CC-BY-NC-SA-4.0 — share-alike inherited from CGMacros (D025) |
| Source code (this repo, the Python trainer, the Next.js demo) | Apache-2.0 |
HF Hub license: tag | other — the repo holds two artefacts under two licences |
See LICENSE-WEIGHTS for the full text and LICENSE_NOTES.md for the decision record.
A commercial license for the weights can be negotiated with the maintainer
(@sfourdrinier on GitHub).
A 435,633-parameter dual-stream JEPA-style encoder for 24-hour continuous glucose
monitoring windows. Trained on a public-data corpus; not derived from any Google
implementation or checkpoint. See LICENSE_NOTES.md for weights licensing and
manifests/sources/registry.yaml for the data record.
n_days = 1..7) for cohort-level phenotypes.The encoder was pretrained on Lane A only — the four public cohorts the GlucoFM paper names. These are the windows that are actually inside the released weights.
| Source | Windows | Subjects | Hours | Licence |
|---|---|---|---|---|
| stanford | 171,140 | 56 | 8,761 | source repository states none |
| shanghai_t2dm | 159,119 | 100 | 12,414 | CC-BY-4.0 |
| big_ideas | 13,167 | 16 | 3,017 | ODC-By-1.0 |
| colas | 9,701 | 68 | 9,544 | CC-BY-4.0 |
| total | 353,127 | 240 | 33,736 | 30.9% of the paper's 109,066 h |
Windows overlap, so the window count is much larger than hours ÷ 24; hours are the non-overlapping quantity and are what the 30.9% refers to.
No other lane entered pretraining. Hall (Lane B) and the Lane C and D cohorts are used for downstream evaluation and for the PPG teacher-student pilot, not for training the encoder. Lane E — cgmacros, uchtt1dm, glucofm_bench — is evaluation-only under non-commercial, share-alike or no-derivatives terms.
The full corpus audit is in manifests/sources/registry.yaml; the lane rules are in
DECISIONS.md D002 and bundle/BLUEPRINT_AMENDMENTS.md A4.
| value | |
|---|---|
| Parameters | 435,633 in this released encoder; 732,593 trainable in the full pretraining model (encoder + predictor + transition heads) |
| Input | 24 h × 5 min grid (288 positions, 24 hourly patches × 12 steps) |
| Streams | state + event (causal Gaussian decomposition, learnable σ) |
| Embedding | 64 → 128-d fused physiological token, gated with circadian time embedding |
| Backbone | 3-layer, 4-head Transformer (paper §3.3; our D019) |
| Training objective | JEPA-style masked-token prediction + temporal-dynamics loss |
| Masking | 50-60 % of patches, sampled uniformly per window, masked before normalisation and filtering |
| EMA target | linear ramp 0.997 → 0.9994 per epoch |
| Reported in paper | 0.72 M — within 1.7 % |
The weights in this repository are one checkpoint, not the five-seed ensemble the evaluation below is computed over. Read this section before quoting a number against the file you downloaded.
| value | |
|---|---|
| Checkpoint | runs_5090/rawstats120/ckpt_ep040.pt |
| Seed | 17 |
| Epoch | 40, not 120 |
zero_empty_patches | false — as trained (see below) |
| Exported file | glucofm_encoder.onnx, opset 17, 1,991,782 bytes |
| SHA-256 | b1349deffd15ab62a5a98d7c7c4a7e143bcf1dee7ad745b1e05533ff54f34768 |
Why epoch 40 and not 120. Epoch 40 is the measured transfer peak at 30.9 % of the paper's
corpus; epoch 120 is mildly worse (−0.005 ROC, about 1 sd of the seed spread). That is the
expected consequence of giving a model more capacity than a reduced corpus can use, and it is
reported rather than hidden. See D024 and findings/results_section.md.
Why zero_empty_patches is false here. D020 — an empty patch emits nothing rather than a
learned bias — is tagged PAPER_EXACT and is now the repo default (True). This checkpoint
predates that change, so it was trained with the learned bias and is exported faithfully as
such. D020 was measured to be neutral (0.6780 vs 0.6818, well inside the seed sd), so the
released weights are not disadvantaged by it — but if you rebuild the architecture from the
current repo defaults, you will not get an architecture that matches this file. Construct it
with zero_empty_patches=False, or read the flags from glucofm_encoder.onnx.meta.json, which
records the exact architecture this artifact was exported under.
All 18 probe heads are published; 14 clear the signal floor. The bundle
(glucofm_heads.json) is licensed CC-BY-NC-SA-4.0, one step stricter than the encoder.
Eight heads are fitted on CGMacros, whose registry entry reads CC-BY-NC-SA-4.0 with
license_confidence: unverified (open question Q4). Share-alike obliges an adapted work to be
offered under the same licence, so the bundle carries it. Keeping the heads as a separate
artefact from the encoder stops that term reaching the encoder, which never saw CGMacros and
stays CC-BY-NC-4.0.
Three heads are fitted on Stanford. They are published: Stanford is Lane A and already inside the encoder, so withholding classifiers fitted on its labels would protect nothing.
Anything fitted on UCHTT1DM would stay out permanently — its no-derivatives term has no labelling remedy. No such head exists today; the filter enforces it regardless.
See D025. Enforced by
tests/unit/test_source_rights.py::test_published_heads_bundle_declares_the_licence_its_sources_impose.
The table below is the five-seed, 120-epoch protocol — the scientific result of the project. It characterises the method, not the single file above. A single ep40 checkpoint will land near, but not exactly on, these numbers.
5 seeds × 120 epochs, subject-disjoint 5×10-fold probe, macro across 14 dataset-task probes (18 task-source combinations — two cohorts are measured on two sensors each):
| Method | ROC-AUC (mean ± sd) | PR-AUC (mean ± sd) |
|---|---|---|
clinical_metrics baseline | 0.643 | — |
raw_masked baseline | 0.607 | — |
opencgm_mean (this model) | 0.670 ± 0.003 | 0.588 ± 0.003 |
| CGM-JEPA (the paper's central comparator) | 0.643 ± 0.004 | 0.566 ± 0.003 |
The paper reports 0.74 ROC across 14 tasks on its full corpus; we measure 0.670 on
30.9 % of the corpus. Direction and ordering of effects survive; absolute magnitude
is smaller. See findings/results_section.md §8–§9 for the gap analysis.
The 30-run Tier-1 ablation (3 seeds × 10 conditions × 40 epochs) confirms the
load-bearing role of the dual-stream decomposition: removing the event stream costs
−0.050 ROC (largest single ablator), removing the state stream costs −0.014, and, the
circadian embedding costs −0.015. Single-stream baselines (abl_raw, abl_event,
abl_state) are the only ablations beyond −0.02.
The abl_dense arm (forced interpolation, which the production rule forbids) is
statistically indistinguishable from the observed mask at 40 epochs (+0.0005). The
never-interpolate rule is not a hair-shirt; it is the principled choice that does not
also need ablation to defend it.
manifests/sources/registry.yaml.findings/results_section.md and will gain error bars when the
multi-seed sweep finishes.@software{opencgm_stateevent_2026,
title = {OpenCGM-StateEvent: independent public-data reconstruction of GlucoFM},
author = {Fourdrinier, Stephane},
year = {2026},
url = {https://github.com/sfourdrinier/opencgm-stateevent},
note = {Apache-2.0; see CITATION.cff}
}
Plus cite the original method:
@article{glucofm_2026,
title = {GlucoFM: A Dual-Stream Foundation Model for Continuous Glucose Monitoring},
url = {https://arxiv.org/abs/2605.30865v2}
}