File size: 3,682 Bytes
3db154f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8c1102d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3db154f
 
 
 
8c1102d
 
3db154f
 
 
8c1102d
3db154f
 
 
 
 
 
8c1102d
 
 
3db154f
8c1102d
3db154f
8c1102d
 
 
 
3db154f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8c1102d
 
 
3db154f
 
8c1102d
 
 
 
 
3db154f
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
---
license: mit
tags:
  - matrix-factorization
  - preference-model
  - recommendation
  - cloud-local
  - numpy
library_name: custom
pipeline_tag: text-classification
metrics:
  - accuracy: 0.677
  - AUC: 0.734
---

# Cloud vs Local β€” MF preference model

Simple Matrix Factorization model that predicts **which model to use for a prompt**:
`cloud` or `local`. Trained on preference data of the form *(user, prompt, chosen)*
where `chosen ∈ {cloud, local}`.

![MF pipeline diagram](mf_model_diagram.png)

## 🚨 Use real preference data for better results

This model is **trained on synthetic demo data** (12,000 generated ratings) β€” it exists
to validate the pipeline and the tooling, **not** to be the final product. For a model
that actually routes your traffic, retrain on your **real preference logs**:

1. Export a CSV with at least three columns: `user_id`, `prompt`, `chosen`
   (values `cloud` or `local`).
2. Open `mf_cloud_vs_local.ipynb` in Jupyter and run the last code cell:
   `train_on(load_preference_data("your_real_data.csv"))`.
3. The whole pipeline β€” EDA, stratified train/val/test split, MF training,
   evaluation, bundle export β€” runs unchanged on your file.

Real data gives you: trustworthy metrics, per-topic routing insights from your own
prompts, and a cleaner cold-start story (see Limitations).

## Model

`rΜ‚(u,i) = ΞΌ + b_u + b_i + ⟨p_u, q_i⟩` β€” user bias + prompt bias + dot product of latent
factor vectors (k = 8), trained with binary cross-entropy + L2 regularization via
minibatch SGD (NumPy), early-stopped on validation AUC.

Decision rule: `p(cloud) = Οƒ(rΜ‚) β‰₯ 0.5 β†’ cloud`, else `local`.

## Metrics (held-out test, n = 1,200 β€” synthetic data)

| metric    | value   | baseline (always cloud) |
|-----------|---------|--------------------------|
| accuracy  | 0.677   | 0.483                    |
| AUC       | 0.734   | 0.500                    |

The model recovers the latent topic structure: privacy-sensitive and
latency-sensitive prompts are routed to `local`; complex-reasoning and long-context
prompts to `cloud`.

## Files in this repo

- `README.md` β€” this model card
- `mf_cloud_vs_local.ipynb` β€” full source notebook (data gen, EDA, training, eval, bundle, diagram, inference demo)
- `mf_inference.py` β€” sample inference script (CLI, loads the bundle with `SimpleMF.from_pretrained`)
- `mf_model_diagram.png` β€” training + inference pipeline diagram
- `config.json` β€” hyperparameters + metrics
- `mf_params.npz` β€” `mu, bu, bi, P, Q, user_ids, prompt_ids` (weights + vocab)
- `test_predictions.csv` β€” per-pair predictions on the held-out test set

## Usage

```bash
pip install numpy datasets huggingface_hub

# score specific (user, prompt) pairs
python mf_inference.py --model_dir mf_bundle --user_id U0007 \
    --prompt_ids P0001,P0400,P0572 --csv preference_data_synthetic.csv

# rank all known prompts for a user
python mf_inference.py --model_dir mf_bundle --user_id U0007 --top_k 5 \
    --csv preference_data_synthetic.csv
```

Clone this repo and run `mf_inference.py` locally, or open `mf_cloud_vs_local.ipynb`
to retrain on your own preference data.

## Limitations

- **Cold start**: prompts not seen in training have no `q_i` embedding β€” the model
  cannot score brand-new prompt text. Extend with a text encoder (e.g. embed prompt
  text into the latent space) for production cold start.
- **Synthetic data**: metrics above are on synthetic ratings; expect different numbers
  on real preference logs β€” see "Use real preference data" above.
- No leakage checks were needed for synthetic data; run a near-duplicate check between
  train/val/test when real data arrives.