Inspiration
More than 1 in 3 US adults has prediabetes, and about 81% of them don't know it (CDC). The people who could benefit most from seeing how food affects their blood sugar are the least likely to own a continuous glucose monitor (CGM), and the ones who do get a number after the spike, not before.
Then two papers came out this year that made a "before" version feel possible:
- Google's GlucoFM (arXiv 2605.30865, May 29, 2026; blog post August 26, 2026) showed that a CGM foundation model can learn from unlabeled glucose traces by reading them as two streams: a slow trend and fast deviations around it.
- The TU Munich meal-photo paper (arXiv 2609.24453, September 2026) showed that a glucose response can be predicted starting from a photo of the meal.
We're a math & stats major, an electrical engineer and a finance major, and we wanted to take that research from a PDF to something you could hold. The question we built around: what if you could see your glucose spike before you take the first bite?
What it does
GlucoSnap turns a photo of your meal into a predicted 2-hour blood-sugar curve.
- Snap. A vision model (Gemma 4,
gemma-4-31b-it, through UF's NaviGator AI Toolkit) reads the photo into carbs, protein, fat and fiber. - See the curve. Our model predicts the rise every 15 minutes for 2 hours, with an 80% uncertainty band.
- Flatten it. GlucoSnap reruns the model on edited versions of the meal (swap half the starch for vegetables or beans, add a protein side, take a 15-minute walk) and shows only the changes that actually lower the predicted peak.
- Check yourself. The History tab draws your predicted curve next to measured CGM or finger-stick readings. With 3+ days of CGM, a Health snapshot estimates HbA1c and a normal / prediabetes / type 2 range.
- Play. GlucoSnap Quest turns healthy habits into XP, tokens, streaks, a customizable character and a pet that evolves along branching paths. There's an AI coach for custom quests and cheap anti-spike meal ideas, a Learn tab with quizzes and the ADA diabetes risk test, meal reminders, and a leaderboard.
It works for everyone, not just CGM owners: the model picks a tier based on what you have (CGM data, lab results, or just age, sex and BMI).
How we built it
The prediction target
For a meal eaten at time \(t\), with pre-meal baseline \(\bar{g}\) (the average of the last 5 minutes of glucose), we predict the rise at 8 horizons:
$$ \Delta g_{h} = g(t + h) - \bar{g}, \qquad h \in \lbrace 15, 30, \dots, 120 \rbrace \text{ min} $$
Gradient-boosted trees, one per horizon
Each horizon gets its own LightGBM model, a sum of \(K\) small regression trees:
$$ \Delta g_{h} \approx F_{h}(\mathbf{x}) = \sum_{k=1}^{K} \eta T_{hk}(\mathbf{x}) $$
where \(\mathbf{x}\) holds the meal's macros, time of day, activity, the last 6 hours of glucose (level, slope, wobble), a 3-day glucose summary, encoder features, and age, sex and BMI. We chose trees over a big neural network because ~2,100 meals is too little data for one, and trees handle missing inputs natively.
To keep the "flatten it" suggestions physiologically sane, we added monotone constraints:
$$ \frac{\partial F_{h}}{\partial \text{carbs}} \ge 0, \qquad \frac{\partial F_{h}}{\partial \text{fiber}} \le 0, \qquad \frac{\partial F_{h}}{\partial \text{walking}} \le 0 $$
More carbs can never lower the predicted curve; more fiber or walking can never raise it.
A GlucoFM-style CGM encoder
GlucoFM's weights aren't public, so we rebuilt a smaller version from the paper (170k parameters vs. GlucoFM's 0.72M) in PyTorch. A 6-hour window \(x\) sampled every 5 minutes is split into a trend (1-hour moving average) and a deviation stream:
$$ \tau(t) = \frac{1}{12} \sum_{k=0}^{11} x(t - k), \qquad \delta(t) = x(t) - \tau(t) $$
Each stream is cut into 30-minute patches and read by its own small transformer; a shared layer fuses them. It learns without labels by masked latent prediction: hide 40% of the patches and predict what a slowly updated copy of itself (an EMA target network) encodes there,
$$ \theta' \leftarrow 0.996 \theta' + 0.004 \theta $$
It was pre-trained on over 22,000 unlabeled 6-hour CGM windows, frozen, and its 256-number output squeezed to 16 numbers with PCA as features for the trees.
Data and honest testing
We trained on two open PhysioNet datasets: CGMacros (45 adults with CGM, meal photos and labs) and BIG IDEAs (16 adults with Dexcom CGM and food logs), giving about 2,100 meals from 59 people. Every number below is from subject-held-out cross-validation: people are split into 5 groups, and the model is always scored on people it has never seen, just like a brand-new user.
$$ \text{MAE} = \frac{1}{8N} \sum_{i=1}^{N} \sum_{h} \left| \Delta g_{ih} - F_{h}(\mathbf{x}^{(i)}) \right| $$
| Tier | Used when you have | Error on new people |
|---|---|---|
| Sensor | CGM readings | 17.8 mg/dL |
| Labs | HbA1c or fasting glucose | 19.9 mg/dL |
| Basic | Only age, sex, BMI | 21.5 mg/dL |
| Baseline | Same average curve for everyone | 24.2 mg/dL |
The 80% band comes from the model's own track record: the 10th and 90th percentiles of its held-out errors at each horizon. The Health snapshot uses a ridge regression on a 4-day CGM summary for HbA1c (within about 0.36 points) and a logistic regression over the ADA cut-offs (5.7% and 6.5%) for the risk range.
Game design with guardrails
Each quest has base XP \(b\). Base XP counts toward a cap of 80 a day, then gets multiplied by a streak bonus \(m(s)\) that grows with your streak \(s\): 1x to start, 1.25x at 3 days, 1.5x at 7 and 2x at 14. If you've already earned \(u\) base XP today,
$$ \text{XP gained} = m(s) \cdot \min(b, 80 - u) $$
Level \(n\) needs \(40 + 20(n-1)\) XP, so reaching level \(n\) takes
$$ \sum_{k=1}^{n-1} \big(40 + 20(k-1)\big) = 10(n-1)(n+2) \text{ XP} $$
A Legendary pet needs level 14 (2,080 XP) and a 14-day streak, which takes at least about 18 days of steady use. The cap means you can't binge your way there; you have to come back.
The rules we never broke: the game never rewards eating less. The AI coach's quests are filtered to drop anything about skipping meals, fasting, portions, calories, weight or medication; XP is set by category on the server, never by the model. Tokens only buy cosmetics, and the leaderboard shows name, level, streak and pet, never health data.
The stack
- Frontend: React + Vite + TypeScript, installable as a web app.
- Backend: FastAPI with LightGBM and scikit-learn. The encoder is exported to ONNX so the server runs without PyTorch.
- AI: Gemma 4 (
gemma-4-31b-it) on UF NaviGator for photo reading, coach quests and meal ideas, with a built-in fallback library when the AI is slow or off-script. - Hosting: one Docker container built by GitHub Actions, pushed to GitHub Container Registry and run on Azure Container Apps, with accounts stored in Azure Blob Storage.
Challenges we ran into
- No model to download. GlucoFM's weights aren't public, so we reimplemented the architecture from the paper at a size that trains on a laptop CPU.
- The neural network lost to simple features. On its own, the encoder scored 23.2 mg/dL, worse than plain trees at 20.3. With 45 people there wasn't enough data to train it end to end, so we turned it into a feature maker for the trees, where it helped.
- The trees learned noise. In our first fit, adding carbs sometimes lowered the predicted curve, which would have made every suggestion nonsense. Monotone constraints fixed it at no cost in accuracy.
- Training and the app saw different data. Pre-meal glucose came from 1-minute data in training but arrives in 5-minute steps in the app. We retrained on the app's exact inputs.
- Messy second dataset. In BIG IDEAs, two people's food logs were shifted months away from their CGM and two more couldn't be aligned at all, so we kept 540 meals from 14 people.
- Memory and hosting. PyTorch pushed the server to ~950 MB; ONNX cut it to ~300 MB with identical outputs. Our Azure for Students subscription blocked some regions and Azure's cloud builds, so we build the container on GitHub and let Azure pull it.
- Gamifying food without harm. It's easy to design a health game that rewards restriction. Every reward and every AI-generated quest goes through guardrails so the game pays for habits like walking, fiber and logging, never for eating less.
- Web apps can't wake themselves. Browsers can't fire a reminder from a closed web app, so we added an "Add to calendar" export alongside in-app notifications.
Accomplishments that we're proud of
- A model that predicts a stranger's 2-hour glucose curve to 17.8 mg/dL, versus 24.2 for a one-size-fits-all curve, tested honestly on people it never saw.
- Turning a May 2026 research paper into a working component in a live consumer app.
- A health game that's actually fun (the pet evolution is the team favorite) without crossing ethical lines.
What we learned
- Your own recent data beats your lab results. A person's last 3 days of CGM said more about their next meal than their HbA1c or fasting glucose did. Adding that 3-day summary was the single biggest gain (20.3 to 18.7 mg/dL), so the sensor tier drops labs entirely.
- Foundation-model ideas transfer even when the model doesn't. We couldn't use GlucoFM itself, but its trend/deviation split and label-free pre-training still gave us useful features.
- With small data, simple models plus good features win, and the only evaluation worth reporting is one on people the model has never seen.
- Incentive design is part of the safety design. Caps, cosmetic-only rewards and filters mattered as much as the model.
What's next for GlucoSnap
- Personalization. When a person's earlier meals are in training, error drops to about 15.6 mg/dL. Learning from each user's own meals is the obvious next step.
- Better portion estimates. Photo-to-macro errors stack on top of the model's error; we want to measure and shrink them.
- More data. 59 people over ~10 days each is a start. A larger, more varied group would make the results sturdier.
GlucoSnap is an educational tool, not medical advice. CGMacros is licensed CC BY-NC-SA 4.0, so our trained models are for non-commercial use.
Built With
- azure-blob-storage
- azure-container-apps
- cgmacros
- docker
- fastapi
- gemma
- github-actions
- lightgbm
- navigator-ai-toolkit
- numpy
- onnxruntime
- pandas
- physionet
- python
- pytorch
- react
- scikit-learn
- typescript
- uvicorn
- vite


Log in or sign up for Devpost to join the conversation.