NateRunsA-LIST/alist-food-vision-so400m384
01.7k
A-LIST Food Vision — SigLIP2 SO400M-384 (all-data v1, k-means INT8)
On-device food-photo model for the A-LIST iOS app: one Core ML inference turns a meal photo into estimated macros (calories, protein, carbohydrates, fat, fiber) and a set of recognised food tokens.
- Backbone: SigLIP2 SO400M, 384 px input
- Compression: per-tensor 8-bit k-means weight palettization (~430 MB)
- Minimum deployment target: iOS 17
- Format: source
.mlpackage— clients compile on device withMLModel.compileModel
Versions
- `v2/` (current, 2026-08-24): the same SigLIP2 SO400M tower finetuned end-to-end on the sol-relabeled dataset. The nutrition vector widens from 5 to 24 fields (adds sugar, saturated fat, waterml, glycemicindex, and a 15-nutrient micronutrient vector) and the token vocabulary is retrained on sol meal titles (3,536 tokens, threshold 0.6). Its
v2/model-manifest.jsonis schema 2: a newnutrition_transformsarray marks every field"log1p", meaning decode isexpm1(softplus(z * std + mean)). On the frozen held-out-user eval it beats the v1 artifact on every shared field: calories 63.7% vs 48.9%, protein 63.3% vs 57.0%, carbohydrates 54.6% vs 49.2%, fat 59.8% vs 54.6%, fiber 76.3% vs 74.9% (within ±25% or small slack), at the same ~432 MB footprint. - Root files (v1, all-data): trained on historical stored labels; kept resolvable for rollback. Fields decode as plain
softplus(z * std + mean).
Runtime contract
Input food_image (RGB image): resize the oriented photo so its short edge is 439 px, center-crop to 384×384. Pixel normalization is embedded in the model — feed plain 0–255 RGB.
Outputs:
nutrition_normalizedfloat32 [1, 5] — decode element z assoftplus(z * std + mean); field order, means and standard deviations are inmodel-manifest.jsonlexical_logitsfloat32 [1, 4096] — apply sigmoid, keep tokens at or above the threshold recorded inmodel-manifest.json(0.8); vocabulary is in the same file
model-manifest.json is the decoding contract and ships alongside the weights — do not hardcode its constants.
Integrity
The app pins these hashes and refuses a download that does not match.
