Instructions to use hanemay/smartsightCoach with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- LiteRT-LM
How to use hanemay/smartsightCoach with LiteRT-LM:
# LiteRT-LM runs on various platforms (Android, iOS, Windows, Linux, macOS, IoT, Web/WASM) # and supports many APIs (C++, Python, Kotlin, Swift, JavaScript, Flutter). # For platform-specific integration guides, please refer to the official developer website: # https://ai.google.dev/edge/litert-lm # To try LiteRT-LM, the easiest way is to use our CLI tool. # 1. Install the LiteRT-LM CLI tool: pip install -U litert-lm # 2. Download and run this model locally: # See: https://ai.google.dev/edge/litert-lm/cli litert-lm run \ --from-huggingface-repo=hanemay/smartsightCoach \ --prompt="Write me a poem"
- Notebooks
- Google Colab
- Kaggle
SmartSight Coach LoRA fine-tunes
LoRA fine-tunes for the SmartSight AI coach — an on-device fitness and nutrition coach that
runs entirely on the phone, no account and no server round-trip. Converted to .litertlm for
Android/iOS inference. → smartsight.app/ai-coach
Built and maintained by Niclas Bade.
Base model changed at v42 (2026-08-12). v27–v38 were fine-tuned from google/gemma-4-E2B-it.
Everything from v42 on is fine-tuned from Google's quantization-aware-trained checkpoint
google/gemma-4-E2B-it-qat-q4_0-unquantized, whose weights are conditioned to survive 4-bit
rounding. The frontmatter above reflects the CURRENT parent, so the model tree matches what actually
shipped. This repo keeps the current best checkpoints plus earlier superseded milestones for
history — not every candidate tested each round. Rounds that lose are documented internally with
their real failure cases; they are never uploaded here.
More coming. The vision tower is being trained surface by surface — body fat, meal photos and nutrition-label reading — each measured against held-out data before anything ships. Progress and honest limitations for every round are written up below and at smartsight.app/ai-coach.
smart-coach-vision.litertlm — CURRENT CHAMPION (v221)
Promoted 2026-09-25. sha256 a3e1f3cbcffe562d, 2,795,655,584 bytes.
Lineage: v27 → v31 → v34 → v38 → v42 → v44 → v46 → v47 → v48 → v51 → v54 → v55 → v69 → v85 →
v127 → v134 → v137 → v138 → v139 → v158 → v178 → v201 → v208 → v211 → v215 → v220 → v221.
It answers "I forgot to log it" correctly, reads lean bodies better, and reads nutrition labels worse. All three are in the table below.
Both models measured on the same frozen surfaces (176 real photographs with measured body fat, 32 nutrition labels, 30 non-body photographs), same prompt, same backend. The shipped file is the int4 export the numbers were measured on. Coaching text is HAND-READ by a blind reader who saw both models' answers side by side without knowing which was which.
| surface | v220 | v221 |
|---|---|---|
| within 2 points, 176 real photographs | 101/176 | 108/176 |
| within 2 points, 46 lean photographs (10% or under) | 22/46 | 31/46 |
| mean error, 176 real photographs | 2.31 | 2.27 pp |
| bias (negative = reads low) | +0.55 | -0.28 pp |
| regression slope (1.0 = tracks truth) | 0.69 | 0.71 |
| widest attractor span | 16.9 | 16.9 pp |
| declines non-body photographs | 30/30 | 30/30 |
| nutrition labels, kcal correct of 32 | 19 | 12 |
| coaching text, hand-read of 160, same reader | 140 | 157.5 |
| counted total across every surface | 290 | 307.5 |
The text gain is the unlogged-day answer, now fixed. Told "I trained Monday but I don't think I logged it", v220 stated the blank day plainly on 15 of 32 cases and answered with a conditional ("if it's not in the log, add it") on most of the rest; on four cases it claimed a blank day was already logged or moved a session to the wrong day. v221 states the blank day plainly on 32 of 32 and invents no session. It still reads "what did I train yesterday" right on 32 of 32.
Lean bodies read better. Within 2 points at 10% body fat or under rises 22 to 31 of 46, and on the 21 newest of those 4 to 10. The DEXA-measured 7% subject reads 6.5 on the reference photo and on one of the three new shots, 8.5 on the other two (v220: 7.5, then 8.5 on all three). Lean bodies are still read about 2.6 points too fat on average on the 21 newest, and four photographs between 7 and 10% read 12.5 to 21 on every model this project has measured.
Nutrition labels fall 19 to 12 of 32, and that is printed beside the gains. The same recipe on a second seed reads 17, so part of this is seed spread, but the shipped file reads 12.
The promotion is NOT attributable to what the round tested. v221 is a control model: it did not receive the round's variable, a re-judged set of body-fat labels for about 4,000 training photographs. The four models that did receive it scored lower on average on both totals (text 145.0 against 155.75, photographs 144.25 against 150.0). What every model of the round received is new coaching-text training data on logged and unlogged days, and that is what moved the text score.
smart-coach-vision.litertlm — previous champion (v220)
Promoted 2026-09-24, superseded by v221 on 2026-09-25. sha256 e36d6a0dd7e75e98, 2,795,655,584 bytes.
Lineage: v27 → v31 → v34 → v38 → v42 → v44 → v46 → v47 → v48 → v51 → v54 → v55 → v69 → v85 →
v127 → v134 → v137 → v138 → v139 → v158 → v178 → v201 → v208 → v211 → v215 → v220.
It reads nutrition labels better and answers "I forgot to log it" more plainly, and it reads lean bodies worse. All three are in the table below.
The photograph surface grew on 2026-09-23 from 49 to 176 real photographs with measured body fat (the first 49 unchanged), so the numbers below are not comparable with the previous section's. Both models measured on the same frozen surfaces, same prompt, same backend. The shipped file is the int4 export the numbers were measured on. Coaching text is HAND-READ by a blind reader who saw both models' answers side by side without knowing which was which.
| surface | v215 | v220 |
|---|---|---|
| within 2 points, 176 real photographs | 103/176 | 101/176 |
| within 2 points, 46 lean photographs (10% or under) | 29/46 | 22/46 |
| mean error, 176 real photographs | 2.41 | 2.31 pp |
| bias (negative = reads low) | +0.45 | +0.55 pp |
| regression slope (1.0 = tracks truth) | 0.71 | 0.69 |
| widest attractor span | 12.3 | 16.9 pp |
| declines non-body photographs | 30/30 | 30/30 |
| nutrition labels, kcal correct of 32 | 15 | 19 |
| coaching text, hand-read of 160, same reader | 126.5 | 138 |
| counted total across every surface | 274.5 | 288 |
The text gain is the unlogged-day answer. Told "I trained Monday but I don't think I logged it", v215 answered with a conditional ("if it's not in the log, add it") and never said what the log shows; in the same reading it stated the blank day plainly on 3 of 32 cases. v220 does so on 15 of 32. It also reads "what did I train yesterday" right on 32 of 32 (v215: 30). It is not clean: on three of those cases it claims a blank Wednesday is already logged, and it still answers with the conditional on most of the rest.
Nutrition labels go 15 to 19 of 32.
The lean end got worse, and that is printed beside the gains. Within 2 points on photographs at 10% body fat or under falls 29 to 22 of 46, and on the 21 newest of those 9 to 3. Three new photographs of one DEXA-measured 7% subject read 8.5. On 6 of the 46 lean photographs the answer cites the jawline and cheeks as its reason, which is not where body fat is read. The widest attractor span widens 12.3 to 16.9 points and the slope stays under this project's 0.955 floor (0.69, against 0.71): the binning defect is not fixed.
The promotion is NOT attributable to what the round tested. v220 is a control model: it did not receive the round's variable, which doubled the share of one source of lean training photographs. The four models that did receive it scored lower on average on both totals (text 115.0 against 131.75, photographs 143.5 against 148.0). v220 is the best model of its round, not evidence that a recipe works.
Champion history — what each round actually fixed
Every entry here was a promoted champion, verified against the previous one on a held-out suite with a full read of every answer. Rejected rounds (v28-v30, v32, v33, v35-v37, v39, v40, v41) are not listed — they are documented internally with their real failure cases.
| Round | Beat | What it fixed | Base |
|---|---|---|---|
| v27 | baseline | first winning fine-tune — shorter, equally accurate general advice | gemma-4-E2B-it |
| v31 | v27 | exercise-form answers reached the untouched baseline's zero-error record (v27 was wrong on 4/5 direct form questions); no more garbled or duplicated plan output. The unlock was the export recipe, not data — three consecutive data-only rounds failed first, then Hadamard-rotation int4 fixed it with zero retraining | gemma-4-E2B-it |
| v31 export update | — | same weights, AlgorithmName.HADAMARD_ROTATION custom op instead of the decomposed variant: 88% faster decode, ~85 MB smaller, quality statistically unchanged (5.8% vs 6.4% defect rate over 312 generations) |
— |
| v34 | v31 | dietary-rule compliance (a "vegetarian, no nuts" request had served peanut butter); first correct full examples for face pull and plank; squat-vs-hip-thrust contrast cases | gemma-4-E2B-it |
| v38 | v34 | AI challenges: unrealistic targets for low-frequency goals (150 progress photos in six weeks from zero) and non-English requests answering in English. Won over its own alternate seed on a Danish grammar defect — plural "jeres/jer" where the app addresses one person | gemma-4-E2B-it |
| v42 | v38 | see above — QAT base, blockwise export, and the fenced-JSON data fix. Won over its own alternate seed, which produced a confident wrong number (subtracting a 78 kg bodyweight goal from a 106.7 kg squat 1RM) | gemma-4-E2B-it-qat-q4_0-unquantized |
| v44 | v42 | Danish macro vocabulary and challenge titles. Measured cause: of 7,288 corpus rows, 13 contained any Danish/Norwegian, zero taught "kulhydrat", and ten demonstrated exactly the wrong behaviour — English macro words inside Danish prose. Localising those ten rows fixed it; /nutrition emission went 5/7 → 7/7 |
gemma-4-E2B-it-qat-q4_0-unquantized |
| v46 | v44 | avoid-list violations eliminated (0/36 vs 5/36) by matching the corpus to the prompt format production actually sends | gemma-4-E2B-it-qat-q4_0-unquantized |
| v47 | v46 | no retraining — the vision export ran at 140 soft tokens instead of the 280 the checkpoint specifies, so every shipped build saw 48.9% of the pixel area. The asymmetry proved the mechanism: re-exporting at 280 moved body-fat rank correlation in men +0.492 → +0.704 while women were unchanged, because what separates adjacent bands in men is fine texture only a few pixels tall and downscaling is a low-pass filter | gemma-4-E2B-it-qat-q4_0-unquantized |
| v48 | v47 | conversational follow-ups: the coach dropped the app's own numbers as soon as a user pushed back. Failures 16/24 → 8/24 | gemma-4-E2B-it-qat-q4_0-unquantized |
| v51 | v48 | stopped abandoning the app's numbers on a user contradiction, and stopped inventing plausible detail it could not see ("right in the middle of where it usually sits" → "I can't tell what your usual is") | gemma-4-E2B-it-qat-q4_0-unquantized |
| v54 | v51 | read the wrong cell of the 7-day history line: asked "what did I train yesterday?" it answered about TODAY, 18 times out of 32 | gemma-4-E2B-it-qat-q4_0-unquantized |
| v55 | v54 | the body-fat read was a CONSTANT — 18% for all 42 test photos, and also for a grey rectangle, for pure noise, and for no image at all. Cause was the training data, not the vision tower: a text-only LoRA destroys vision the base model already has (sensitivity fell 0.1164 → 0.0405 across v51→v54 with ZERO vision tensors in the adapter — the language layers consume the image tokens). Mixing ~17% of the vision surface's rows back into the text corpus restored it: MAE 9.13 → 3.42, sensitivity 0.0405 → 0.2183, grey rectangle finally separating from real photos. ⚠️ It also lost the base model's striation detection while gaining the percentage read — capabilities traded, not accumulated, which is why every surface is probed at promotion now | gemma-4-E2B-it-qat-q4_0-unquantized |
| v69 | v55 | relative-date reads ("what did I train yesterday") 24/32 → 32/32. v55 had a consistent off-by-one — it treated the last day in the 7-day line as yesterday instead of today, then described the wrong row accurately: fluent, confident, wrong. Six earlier rounds tried to train it away and every one made it worse. What worked was teaching the model to STATE THE ANCHOR BEFORE USING IT ("the line ends with Sun, so today is Sun; one back is Sat"), turning an indexing problem into two lookups it could already do. Body fat on 37 unseen ordinary phone photos (bathroom mirrors, kitchens, garages — not studio imagery) 2.88 → 1.88 pp, and the most common single answer fell 43% → 19% of photos. ⚠️ It also introduced a regression, fixed by addition not retreat: 100% of the new rows ask the model to locate a day BEHIND today, so it over-generalised to "behind today = not current" and started saying a logged past session doesn't count (32/32 → 27/32, identical on all three seeds) | gemma-4-E2B-it-qat-q4_0-unquantized |
| v85 | v69 | body-fat reads on real photographs stopped compressing the range: slope 0.815 → 1.043, mean error 1.99 → 1.69 pp, and the high end went from reading 24% as 21 to reading it as 24. Coach text and follow-ups level on two seeds. ⚠️ the lean end did not move at all — 5.9%, 8.8% and 10.0% all still read 8, exactly as in v69 | gemma-4-E2B-it-qat-q4_0-unquantized |
| v127 | v85 | gained a category for "this is not a person", the open defect since v55. A plain grey rectangle went from a confident "12%" to "I cannot see a person in this image"; real bodyless photographs — walls, sofas, pets, food — went from 0/30 declined to 14/30. Also fixed background-swap instability: the same body could be moved 10 points by changing the background in v85, worst case 4.0 in v127. The measured cause is the training set, not the objective: arms trained on synthetic greys alone scored 0/30 on real photographs, identical to v85, while arms given 15 real bodyless photographs fabricated 31.6 pp less (seed-paired, bar set in advance at 22 pp). ⚠️ Still fabricates on 16 of 30 real bodyless photographs, and the promoted seed is not the strongest of the three on this surface | gemma-4-E2B-it-qat-q4_0-unquantized |
| v134 | v127 | Shipped as the downloadable weights on 2026-08-29 but NEVER GIVEN A CARD ROW UNTIL NOW - this entry is added retrospectively so the lineage is not missing a link. Measured on the current evaluation set at promotion time of its successor: composite error 2.58 pp across three photo sets, bodyless fabrication 12 of 58, background-robustness 46 of 58. Its gain over v127 is NOT restated here because v127 was never re-measured on this evaluation set, and a number that was not measured does not go on a public card. | gemma-4-E2B-it-qat-q4_0-unquantized |
| v137 | v134 | mean error across three photo sets 2.58 -> 2.08 pp and invented readings on non-body photos 12/58 -> 3/58. Cause was the training labels, not the recipe: 163 photographs re-judged by a single stronger judge with anchors packed inside the band being judged, plus new real people. The round's own experiment (real-photo share) was REJECTED - the gain came from label quality | gemma-4-E2B-it-qat-q4_0-unquantized |
| v138 | v137 | invented readings on non-body photos 3/58 -> 2/58, and background instability cut threefold - the same body on a different background moved 10 points worst-case in v137, 4 in v138. WARNING it REGRESSED on body-fat accuracy: within 2 points on 64% -> 54% of photographs, and the 47-photo set went 2.12 -> 2.99 pp reading about 1.9 low. Promoted on a saturated matrix by a one-image margin | gemma-4-E2B-it-qat-q4_0-unquantized |
| v139 | v138 | half points, and the lean end — the open defect since v69. v138 answers the 7.5% DEXA reference photo as 6 or 10 and cannot say 7.5 under any prompt, because the capability was never trained; v139 answers 7.5 exactly on 4 of 9 encodings, mean error on that photo 2.39 → 1.22 pp and bias +2.06 → +0.78. Also declines 58/58 non-body photographs against v138's 56/58, and takes the counted vision total 131/133 → 133/133 with no surface regressing. Ranking correlation over 12 distinct men +0.688 → +0.806 with the regression slope 0.777 → 0.930. ⚠️ its training data contradicts itself — 889 rows say "ONE WHOLE NUMBER" and answer "7.5%" — so it is unusually prompt-sensitive and needs the prompt printed above | gemma-4-E2B-it-qat-q4_0-unquantized |
| v158 | v139 | stopped collapsing distinct bodies onto one answer — widest attractor span 11.9 → 6.1 pp on the 49-photograph surface, mean error 2.11 → 1.76 pp, within-2pp 30/49 → 32/49, ranking correlation +0.939 → +0.958 (Spearman +0.926 → +0.941), and coaching text 116 → 125/126 of 128 across two seeds with non-body refusals held at 30/30. Won on the TOTALS and chiefly on text: the 0.35 pp accuracy gain is inside the measured 0.902 pp two-sigma floor. WARNING its own tested variable FAILED its precommit (−0.160 against a 0.553 bar), so this was a better draw and not a demonstrated cause; bias also went −0.78 → −0.87 pp and distinct values emitted fell 16 → 12 | gemma-4-E2B-it-qat-q4_0-unquantized |
| v178 | v158 | label reading, and the photograph slice that had resisted every axis since v158: within 2 points 35/49 to 36/49 at slope 0.993, MAE 1.68 to 1.75, bias -0.89 to -0.48, non-body refusals held 30/30, and label fields read correctly 7/32 to 12/32 - every arm in the round beat the old champion on labels by 5 to 8 against a measured seed spread of 1.45, so the label gain is a real effect and not a draw. Counted total 197.5 to 201.0. WARNING coaching text REGRESSED 125.5 to 123.0 of 128, the round's own tested variable FAILED its precommit (+2.25 against a 9.63 bar, properly powered, manipulation check passed), and a CONTROL arm tied this one at 201.0 - so the promotion is a better draw on the totals, not a demonstrated cause, and the +1 photograph and +3.5 total sit inside the measured seed band | gemma-4-E2B-it-qat-q4_0-unquantized |
| v201 | v178 | nutrition labels 12/32 → 16/32 and coaching text 123 → 152 of 160 over five hand-read suites; widest attractor span 11.0 → 10.0 pp and bias −0.48 → −0.08 pp. Counted total 201 → 231. WARNING the body-fat read REGRESSED — within-2pp 36/49 → 33/49, MAE 1.75 → 1.82, correlation +0.954 → +0.941 — and the regression slope fell 0.99 → 0.88, below this project's 0.955 binning floor, on five of the round's six arms. Its own tested variable FAILED its precommit (+2.75 against a 5.0 bar that was itself below the 5.39 minimum detectable effect, so the bar was invalid), and BOTH controls also beat the old champion at 227 and 226 — a better draw on the totals, not a demonstrated cause | gemma-4-E2B-it-qat-q4_0-unquantized |
| v211 | v208 | body-fat reads within 2 points 33/49 -> 36/49 and bias +0.12 -> -0.01 pp; hand-read coaching text 144 -> 149 of 160, carried by the fix to unlogged-day answers, which EVERY arm of the round made and which is therefore attributable to the recipe rather than the draw. Counted total 225 -> 232, both models re-measured in the same batch. WARNING mean error 1.71 -> 1.86 pp, nutrition labels 18 -> 17 of 32, and the binning defect got WORSE: regression slope 0.95 -> 0.88 and widest attractor span 9.0 -> 11.0 pp, with the rows that span swallows under 20% going 2 -> 5. Its own tested variable - uninformative photograph framing - was a NULL (+3.25 treated vs -1.00 control on two controls) and a CONTROL arm also beat the old champion, so this is the best model of its round and not a demonstrated cause. A different arm of the same round cleared the 0.955 slope floor at 0.9982 but regressed on text and was not shipped | gemma-4-E2B-it-qat-q4_0-unquantized |
| v208 | v201 | the binning defect narrowed: regression slope 0.88 → 0.95 (still just under the 0.955 floor), mean error 1.82 → 1.71 pp, correlation +0.941 → +0.954 and widest attractor span 10.0 → 9.0 pp; nutrition labels 16 → 18 of 32 and hand-read coaching text 142 → 143 of 160. Counted total 221 → 224, both models re-measured in the same batch. WARNING answers about an unlogged day fell 32 → 27 of 32 and the reading bias went −0.08 → +0.12 pp. Its own tested variable (a third training epoch) FAILED its precommit flat, and treated and control arms averaged the same total — the best model of its round, not a demonstrated cause | gemma-4-E2B-it-qat-q4_0-unquantized |
| v215 | v211 | Body fat 39/49 within 2 points (was 36), mean error 1.50 pp (was 1.86); stops reading today as yesterday in the training log. Regressions: labels 15/32 (was 17), hedges on unlogged-session questions | gemma-4-E2B-it-qat-q4_0-unquantized |
| v220 | v215 | nutrition labels 15 -> 19 of 32 and hand-read coaching text 126.5 -> 138 of 160 in the same blind pair, carried by stating the blank day plainly on unlogged-day questions (3 -> 15 of 32) and reading yesterday right 32 of 32. Counted total 274.5 -> 288 on the 176-photograph surface. WARNING lean photographs within 2 points 29 -> 22 of 46, widest attractor span 12.3 -> 16.9 pp, slope 0.69 still under the 0.955 floor. A CONTROL arm: the round's variable (doubling one source of lean photographs) lowered the treated mean on both totals, so this is not a demonstrated cause | gemma-4-E2B-it-qat-q4_0-unquantized |
| v221 | v220 | unlogged-day answers fixed: states the blank day plainly on 32 of 32 (was 15) and invents no session; hand-read coaching text 140 -> 157.5 of 160 in the same blind pair; lean photographs within 2 points 22 -> 31 of 46. Counted total 290 -> 307.5. WARNING nutrition labels 19 -> 12 of 32; slope 0.71 still under the 0.955 floor. A CONTROL arm: the round's variable (re-judged body-fat labels) lowered the treated mean on both totals, so this is not a demonstrated cause | gemma-4-E2B-it-qat-q4_0-unquantized |
Recipe constant across every round since v22c: LoRA r=16 / alpha=32 / dropout=0.1, 2 epochs,
lr 6e-5, NEFTune noise_alpha=5, completion-only loss masking (train_on_responses_only),
per-task validation shards, two seeds per round with the winner chosen on behaviour rather than
validation loss. Only the training data, the base, and the export recipe have moved.
Honest current weaknesses
Documented rather than hidden, because they are the targets for the next rounds:
NUTRITION LABELS FELL (v221). kcal read correctly on 12 of 32, down from 19. The same recipe on a second seed reads 17. Every model reads one label (gold 376 kcal) as 1572.
A FEW LEAN BODIES STILL READ FAR TOO FAT (v221). Lean reading recovered (31 of 46 within 2 points, from 22), but on the 21 newest lean photographs the average read is still 2.6 points too high, and four photographs between 7 and 10% read 12.5 to 21 on every model measured so far, each described as "the lower abdomen is soft and rounded". The slope is 0.71, under the 0.955 floor, and the widest attractor span is still 16.9 points.
FIXED IN v221: unlogged-day answers. v220 stated the blank day plainly on 15 of 32 and claimed a blank day was logged on four; v221 states it on 32 of 32 and invents none.
Definition questions (v221). Asked "what is DASH" or "what is weekly undulating periodisation", it sometimes answers from the training log instead of defining the term, and it defines a tri set as three sets of one exercise.
Binning is unchanged (v215). Slope 0.89 against the 0.955 floor, widest attractor span 11 pp, and bodies above 18 percent are still read about 2 points low on average.
THE BINNING FLOOR GOT FURTHER AWAY, NOT CLOSER (v211). The champion's regression slope is 0.88, against this project's 0.955 floor - worse than v208's 0.95, and the widest attractor span widened 9.0 to 11.0 pp, with five of the rows it swallows sitting under 20% where most users are. A different arm of the same round measured 0.9982, clearing the floor for the first time ever, so the defect is now known to be fixable by this recipe on some seeds. That arm regressed on coaching text and was not shipped. This is the oldest open defect on the model and it is getting the next round's attention.
Superseded note (v208). The regression slope of predicted against true body fat is 0.9538 against this project's 0.955 floor, up from v201's 0.88. Below that floor the model compresses distinct bodies toward a middle value. v208 is within two thousandths of the floor, but the round's control arms sat at 0.83 and 0.70, so the recipe has not fixed it — this seed landed near the line.
Lean bodies in tall, narrow photographs read too high (v208). Among photographs under 9% body fat, the ones framed tall and narrow (width under 0.60 of height) read +2.58 pp high on average, while wider framings read −0.39. The cause is the training set: tall framings of lean bodies are rare in it and tall framings of higher body fat are common, so frame shape became a cue for body fat. This is the IMAGE's proportions, not the person's height. The next round adds re-framed lean photographs to break that link.
A single photo source is a shortcut for "lean". One batch of competition photographs, all carrying the same event watermarks and stage backdrop, makes up about half of the sub-8% training photographs and contains nothing above 8%. The model can learn "stage photo means lean" instead of reading the body. New additions are drawn so they do not increase that share; fixing it needs processed or new photographs spread across every body-fat band.
FIXED IN v211: answers about an unlogged day. v208 would assert a session existed on a blank day, or count it on feeling. v211 answers these correctly, as did every other arm of its round. The original v208 defect is kept below for history.
Superseded note (v208). Asked about a day with no session in the 7-day history, v208 answers correctly 27 of 32 times against v201's 32 of 32, while it improved on the neighbouring history-reading questions. The gain and the loss came from the same model.
A pet photograph still reads as a body (v201). Of 30 real bodyless photographs the champion declines 30, but one specific pet image returns a confident body-fat percentage on other arms of the same round, in near-identical wording across two independently trained models. That makes it a property of that photograph rather than of a seed. The denial set holds 537 images and evidently none of them look like that one; more real bodyless photographs remains the lever.
Body fat at the lean end: LARGELY FIXED IN v139, and the fix was half points. Through v138 this read as a bucket — DEXA-measured 5.9%, 8.8% and 10.0% photographs all returned 8, three truths and one answer, unchanged from v69 to v85. The cause turned out to be partly the OUTPUT ALPHABET: a model that can only answer in whole numbers cannot express 7.5, and prompting it to do so changes nothing because the capability was never trained. v139 was trained with half-point targets and answers 7.5 exactly on 4 of 9 encodings of the DEXA reference photograph, cutting mean error there 2.39 → 1.22 pp. Remaining gap: this is demonstrated on ONE subject at nine encodings. More DEXA-measured lean subjects is still the lever for proving it generalises.
Images that are not bodies: LARGELY FIXED IN v127, not yet solved. This was listed here as unfixable-by-prompting through v85, and it was: a variant instructing the model to reply NOT_A_BODY was ignored, returning byte-identical output. What fixed it was training data — specifically real bodyless photographs, not synthetic ones. A plain grey rectangle now reads "I cannot see a person in this image" rather than "12%". Remaining gap: v127 still returns a percentage for 16 of 30 real bodyless photographs (walls, sofas, pets, plates of food), so the behaviour is much better and still not dependable. More real bodyless photographs is the known lever; synthetic ones were measured to buy almost nothing. v139 update: it now declines all 58 of the bodyless probe set, answering "no person visible" every time, against v138's 56/58. Two cautions: the probe set is largely SYNTHETIC (grey ramps and noise), which is exactly the imagery measured to prove little, and the behaviour depends on the prompt carrying an explicit refusal clause. Real bodyless photographs remain the outstanding fix.
The training prompt contradicts the training targets (v139). Half-point targets were added without updating the instruction the model is trained against, so 889 of 4,494 rows pair "ONE WHOLE NUMBER" with an answer of "7.5%". One row in five teaches the model to disobey its own instruction, which is why v139's readings move by more than a point on small prompt edits. The next round tests the repair directly, treated against its own control.
Meal-plan portions are sized by habit, not arithmetic. The model anchors on ~100 g portions rather than solving the prompt's stated calorie budget. Mostly invisible in the app, which rescales a day to its target (
MealPlanScaler, clamped 0.6x–2.0x) — but one case per model is still off after that clamp, and the underlying arithmetic is unsolved.Avoid-lists are not always respected — foods explicitly banned for variety reappear (2/29 held-out cases on v44, v42 and v38 alike; this is the single defect class that has survived every round so far).
Nordic follow-ups about an UNLOGGED past activity regressed in v44. Asked in Norwegian about a hike "yesterday" that is not in the app, v42 correctly said the gap was only a logging omission; v44 answers as though advising about today. 26 Nordic follow-up rows were added to fix exactly this and did not move it — the cause is not simply coverage.
Occasional Danish/Norwegian word-formation slips in v44 — "vækning" (not a word) and the hybrid "fat-mål". The macro vocabulary itself is now correct, but morphology is not reliable.
The
/nutritioncommand line is improvised. The corpus contains ZERO examples of it; the format lives only in the prompt. v44 emits the line on 7/7 applicable cases (v42 omitted it entirely on 2/7) but drops the trailingfatvalue on 3/7, so the app applies three of the four fields. Harmless by design —NutritionCommandParseraccepts any subset — but the fat target silently stays stale.Within-day duplicate or misplaced exercises still appear occasionally in generated routines (e.g. a chest isolation movement landing in a Legs day). Lower real-world impact than it sounds, since the app's own parser drops duplicate slots.
Confabulation-despite-coverage on a few specific lifts (squat/hip-thrust blending, farmer's carry) that does not reliably respond to more training data.
Superset pairing — avoiding two competing-muscle compounds back to back — is imperfect.
Tight macro-budget precision (±8–10%) is unsolved across every model tested, including the untouched baseline.
Evaluation discipline
Every promote/reject decision reads every row of the eval suite, never a sample — an early round reported a verdict from ~12 of 52 rows and missed hard timeout loops entirely. Prose quality is judged as its own axis alongside structural correctness, because a structurally clean answer can still be flat, templated, or subtly wrong in a second language. Candidates are always compared against both the previous champion and the untouched baseline.
Files
Which file the app fetches
Two files are published. The app decides which one to fetch based on its build version; there is nothing to select and nothing to configure.
| file | who gets it | size |
|---|---|---|
smart-coach-vision.litertlm |
⭐ current champion — text coaching AND vision (body-fat photos, meal photos, nutrition labels) in one model. Fetched by the next app release. | 2.99 GB |
smart-coach.litertlm |
text-only, fetched by app builds already installed. Unchanged on purpose. | 2.63 GB |
Both carry the same v46 coach weights (v47 changes only the vision export, not the weights), so an older build is not stuck on an older coach. They exist side by side because installed builds also fetch a separate 3.66 GB vision model — handing them the larger consolidated file would raise their total download on devices already tight on RAM. See the current-champion section above for what the consolidation actually changes.
smart-coach-vision.litertlm— ⭐ current champion, fetched by the next app release. The v46 coach WITH a working vision tower: one model for text coaching, body-fat photos, meal photos and nutrition labels (2.99 GB, int8 output layer). The next app release points both the coach and vision URLs here and stops downloading the separate 3.66 GB vision model.smart-coach.litertlm— STABLE, text-only (2.63 GB). The file app builds already in the wild download at runtime on Android and iOS, and the one they keep using. Deliberately left unchanged: those builds also fetch the separate vision model, so giving them the larger consolidated file would raise their total download on devices that are already RAM-constrained. Same v46 coach weights, so nobody is stuck on an older coach for stability's sake.coach.litertlm— the original working int8 build from the v1 era (2.59 GB), kept as the historical starting point.coach-finetuned-int4.litertlm— the first int4 conversion (2.56 GB), kept because it is the artifact that exposed the LiteRT-LM chat-template.get()incompatibility.model.safetensors+config.json+ tokenizer files — HF-format artifacts for reference.
- Downloads last month
- 107
Model tree for hanemay/smartsightCoach
Base model
google/gemma-4-E2B