NutriPlan AI β Embedding Model Selection
This repo documents the embedding model comparison for the NutriPlan AI recommendation engine (final project, Introduction to Data Science, Reichman University). It does not host new model weights β it hosts the precomputed embeddings produced by the winning model, plus the comparison that led to that choice.
Dataset: avivtor/nutriplan-menus
Models Compared
Three general-purpose sentence embedding models were evaluated, per the project requirement to compare 3 HF models on time, effort, size, and performance:
| Model | Load time | Encode 500 (sample) | Encode 10,013 (full) | Dimensions |
|---|---|---|---|---|
| sentence-transformers/all-MiniLM-L6-v2 | 5.0s | 13.8s | 4.8 min | 384 |
| BAAI/bge-small-en-v1.5 | 6.3s | 26.4s | 9.4 min | 384 |
| sentence-transformers/all-mpnet-base-v2 | 6.4s | 95.0s | 35.3 min | 768 |
All three are established, well-documented general-purpose sentence embedding models. They are not 2026's state-of-the-art (the MTEB leaderboard is currently led by much larger models such as Qwen3-Embedding-8B and Gemini Embedding, most requiring paid APIs or heavy GPU resources) β these three were chosen deliberately for being lightweight enough to run for free on CPU, appropriate for this project's resource constraints.
Performance Evaluation
Each menu was converted to a text representation (goal, diet type, cuisine, prep time, calories, meal names β see the dataset's EDA notebook for details), embedded with each model, and tested with 2 independent example user-profile queries. For each, the top-3 most similar menus (cosine similarity) were compared against the target calorie value in the query:
| Query | Target calories | MiniLM avg. deviation | bge-small avg. deviation | mpnet avg. deviation |
|---|---|---|---|---|
| muscle gain, standard, Italian, quick | 2,200 | 1,253 cal | 850 cal | 97 cal |
| weight loss, vegan, Asian, moderate | 1,200 | 212 cal | 218 cal | 177 cal |
| weight maintenance, keto, Mexican, no time limit | 1,800 | (not tested on all 3 models) | (not tested on all 3 models) | 400 cal |
All three models correctly matched the categorical fields (goal, diet, cuisine) in every test, including a third query tested only on the winning model as a final sanity check. mpnet-base-v2's calorie sensitivity varied notably across queries (97β400 cal deviation) β strong but not perfectly uniform across all category combinations. This is a known characteristic worth noting rather than a failure: the categorical match was 100% consistent across all 3 test queries.
Decision: sentence-transformers/all-mpnet-base-v2
Chosen for its consistently stronger performance on the criterion the guide weights most heavily ("most importantly performance"), despite being the slowest and largest of the three (768 dimensions vs. 384). For a menu-recommendation use case where numeric fields (calories, macros) meaningfully affect what counts as a "similar" menu, this trade-off was judged worthwhile β encoding the full dataset was a one-time ~35-minute cost on free CPU compute, not a recurring one.
File
menu_embeddings.pkl β a pickled dict with:
model_id:"sentence-transformers/all-mpnet-base-v2"embeddings: NumPy array, shape(10013, 768)menu_texts: the text representation used to generate each embedding
To use: download this file, load with pickle, and load the actual model weights directly from sentence-transformers/all-mpnet-base-v2 (not re-hosted here) to embed new queries at inference time.