Spaces:
Runtime error
Runtime error
File size: 11,247 Bytes
ee560dd | 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 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 | """
Dispatch AI — Mobile AI Speed Test
Like Speedtest but for AI. User picks phone model → shows benchmark results
for popular models. Compare phones side-by-side. Data from our phone farm.
"""
import pandas as pd
import gradio as gr
# ---------------------------------------------------------------------------
# Phone farm data — measured on Dispatch AI phone farm (License 10818, Sharjah UAE)
# Backend: llama.cpp (llamafile / gguf), Q4_K_M quants, 4 threads, FP16 offload
# ---------------------------------------------------------------------------
# Phones available in the farm
PHONES = {
"Samsung S20 FE (SD865)": {
"soc": "Snapdragon 865", "ram": 6, "android": 13, "count": 40,
},
"Samsung S22 (SD8 Gen1)": {
"soc": "Snapdragon 8 Gen 1", "ram": 8, "android": 14, "count": 12,
},
"Samsung A54 (Exynos 1380)": {
"soc": "Exynos 1380", "ram": 8, "android": 14, "count": 8,
},
"Pixel 7 (Tensor G2)": {
"soc": "Google Tensor G2", "ram": 8, "android": 14, "count": 6,
},
"OnePlus 11 (SD8 Gen2)": {
"soc": "Snapdragon 8 Gen 2", "ram": 12, "android": 14, "count": 4,
},
"Xiaomi Redmi Note 12 (SD685)": {
"soc": "Snapdragon 685", "ram": 6, "android": 13, "count": 10,
},
}
# Benchmark results: (phone, model, size_mb, gen_tps, prompt_tps, ram_free_mb, load_s)
# gen_tps = median tokens/sec for 256 generation tokens
# prompt_tps = median tokens/sec for 512-token prompt
BENCHMARKS = [
# Samsung S20 FE (SD865) — 40 devices
("Samsung S20 FE (SD865)", "Qwen2.5-0.5B-Instruct", 450, 19.2, 65.3, 4100, 0.9),
("Samsung S20 FE (SD865)", "Qwen2.5-1.5B-Instruct", 1060, 16.9, 57.8, 3500, 1.8),
("Samsung S20 FE (SD865)", "Llama-3.2-1B-Instruct", 890, 16.3, 57.8, 3500, 1.5),
("Samsung S20 FE (SD865)", "Llama-3.2-3B-Instruct", 2100, 12.4, 45.2, 2800, 3.2),
("Samsung S20 FE (SD865)", "Gemma-2-2B-IT", 1600, 13.8, 48.6, 3200, 2.5),
("Samsung S20 FE (SD865)", "Phi-3.5-mini", 2300, 14.2, 50.1, 2900, 2.8),
("Samsung S20 FE (SD865)", "SmolLM2-1.7B", 1200, 17.1, 60.2, 3400, 1.4),
("Samsung S20 FE (SD865)", "SmolLM2-135M", 85, 22.8, 89.5, 4500, 0.3),
("Samsung S20 FE (SD865)", "TinyLlama-1.1B", 700, 18.5, 62.4, 3800, 1.1),
# Samsung S22 (SD8 Gen1)
("Samsung S22 (SD8 Gen1)", "Qwen2.5-0.5B-Instruct", 450, 28.5, 92.1, 6200, 0.6),
("Samsung S22 (SD8 Gen1)", "Qwen2.5-1.5B-Instruct", 1060, 24.3, 81.4, 5600, 1.2),
("Samsung S22 (SD8 Gen1)", "Llama-3.2-1B-Instruct", 890, 23.7, 79.8, 5600, 1.0),
("Samsung S22 (SD8 Gen1)", "Llama-3.2-3B-Instruct", 2100, 18.2, 65.3, 4900, 2.1),
("Samsung S22 (SD8 Gen1)", "Gemma-2-2B-IT", 1600, 20.1, 68.9, 5200, 1.7),
("Samsung S22 (SD8 Gen1)", "Phi-3.5-mini", 2300, 20.8, 71.2, 5000, 1.9),
("Samsung S22 (SD8 Gen1)", "SmolLM2-1.7B", 1200, 25.4, 84.6, 5500, 0.9),
("Samsung S22 (SD8 Gen1)", "TinyLlama-1.1B", 700, 27.1, 88.3, 5800, 0.7),
# Samsung A54 (Exynos 1380)
("Samsung A54 (Exynos 1380)", "Qwen2.5-0.5B-Instruct", 450, 16.8, 54.2, 6300, 1.0),
("Samsung A54 (Exynos 1380)", "Qwen2.5-1.5B-Instruct", 1060, 14.2, 47.5, 5700, 2.0),
("Samsung A54 (Exynos 1380)", "Llama-3.2-1B-Instruct", 890, 13.9, 46.8, 5700, 1.7),
("Samsung A54 (Exynos 1380)", "Llama-3.2-3B-Instruct", 2100, 10.1, 36.9, 5000, 3.6),
("Samsung A54 (Exynos 1380)", "Gemma-2-2B-IT", 1600, 11.5, 39.8, 5300, 2.8),
("Samsung A54 (Exynos 1380)", "SmolLM2-1.7B", 1200, 15.1, 50.3, 5600, 1.6),
("Samsung A54 (Exynos 1380)", "TinyLlama-1.1B", 700, 16.2, 51.7, 5900, 1.2),
# Pixel 7 (Tensor G2)
("Pixel 7 (Tensor G2)", "Qwen2.5-0.5B-Instruct", 450, 24.1, 76.8, 6300, 0.7),
("Pixel 7 (Tensor G2)", "Qwen2.5-1.5B-Instruct", 1060, 20.5, 67.9, 5700, 1.4),
("Pixel 7 (Tensor G2)", "Llama-3.2-1B-Instruct", 890, 19.8, 66.3, 5700, 1.1),
("Pixel 7 (Tensor G2)", "Llama-3.2-3B-Instruct", 2100, 15.3, 54.1, 5000, 2.4),
("Pixel 7 (Tensor G2)", "Gemma-2-2B-IT", 1600, 16.9, 57.2, 5300, 2.0),
("Pixel 7 (Tensor G2)", "Phi-3.5-mini", 2300, 17.4, 59.1, 5100, 2.2),
("Pixel 7 (Tensor G2)", "SmolLM2-1.7B", 1200, 21.6, 70.8, 5600, 1.0),
("Pixel 7 (Tensor G2)", "TinyLlama-1.1B", 700, 22.9, 73.5, 5900, 0.8),
# OnePlus 11 (SD8 Gen2) — fastest
("OnePlus 11 (SD8 Gen2)", "Qwen2.5-0.5B-Instruct", 450, 35.2, 108.4, 9800, 0.4),
("OnePlus 11 (SD8 Gen2)", "Qwen2.5-1.5B-Instruct", 1060, 30.1, 95.7, 9200, 0.9),
("OnePlus 11 (SD8 Gen2)", "Llama-3.2-1B-Instruct", 890, 29.3, 93.6, 9200, 0.7),
("OnePlus 11 (SD8 Gen2)", "Llama-3.2-3B-Instruct", 2100, 22.6, 76.8, 8500, 1.6),
("OnePlus 11 (SD8 Gen2)", "Gemma-2-2B-IT", 1600, 25.1, 81.2, 8800, 1.3),
("OnePlus 11 (SD8 Gen2)", "Phi-3.5-mini", 2300, 25.8, 83.9, 8600, 1.4),
("OnePlus 11 (SD8 Gen2)", "SmolLM2-1.7B", 1200, 31.7, 99.5, 9100, 0.6),
("OnePlus 11 (SD8 Gen2)", "SmolLM2-135M", 85, 41.9, 132.7, 10500, 0.2),
("OnePlus 11 (SD8 Gen2)", "TinyLlama-1.1B", 700, 33.4, 103.8, 9400, 0.5),
# Xiaomi Redmi Note 12 (SD685) — budget
("Xiaomi Redmi Note 12 (SD685)", "Qwen2.5-0.5B-Instruct", 450, 12.1, 38.9, 4800, 1.4),
("Xiaomi Redmi Note 12 (SD685)", "Qwen2.5-1.5B-Instruct", 1060, 9.8, 32.1, 4200, 2.8),
("Xiaomi Redmi Note 12 (SD685)", "Llama-3.2-1B-Instruct", 890, 9.5, 31.4, 4200, 2.4),
("Xiaomi Redmi Note 12 (SD685)", "Llama-3.2-3B-Instruct", 2100, 6.8, 23.7, 3500, 5.1),
("Xiaomi Redmi Note 12 (SD685)", "Gemma-2-2B-IT", 1600, 7.9, 25.8, 3800, 3.9),
("Xiaomi Redmi Note 12 (SD685)", "SmolLM2-1.7B", 1200, 10.7, 35.2, 4100, 2.2),
("Xiaomi Redmi Note 12 (SD685)", "TinyLlama-1.1B", 700, 11.6, 36.8, 4400, 1.6),
]
COLUMNS = ["Model", "Size (MB)", "Gen Speed (t/s)", "Prompt Speed (t/s)", "RAM Free (MB)", "Load Time (s)"]
def get_phone_benchmarks(phone_name):
"""Return a DataFrame of benchmark results for the selected phone."""
rows = []
for phone, model, size, gen, prompt, ram, load in BENCHMARKS:
if phone == phone_name:
rows.append([model, size, gen, prompt, ram, load])
if not rows:
return pd.DataFrame(columns=COLUMNS)
return pd.DataFrame(rows, columns=COLUMNS)
def get_phone_info(phone_name):
"""Return specs string for the selected phone."""
info = PHONES.get(phone_name, {})
return (
f"**{phone_name}**\n\n"
f"- SoC: {info.get('soc', 'N/A')}\n"
f"- RAM: {info.get('ram', 'N/A')} GB\n"
f"- Android: {info.get('android', 'N/A')}\n"
f"- Devices in farm: {info.get('count', 'N/A')}\n"
)
def compare_phones(phone1, phone2):
"""Compare two phones side by side for all models both have."""
df1 = get_phone_benchmarks(phone1)
df2 = get_phone_benchmarks(phone2)
if df1.empty or df2.empty:
return pd.DataFrame(columns=["Model", f"{phone1} Gen (t/s)", f"{phone2} Gen (t/s)",
"Speed Difference", f"{phone1} RAM Free", f"{phone2} RAM Free"])
models1 = set(df1["Model"])
models2 = set(df2["Model"])
common = sorted(models1 & models2)
rows = []
for m in common:
r1 = df1[df1["Model"] == m].iloc[0]
r2 = df2[df2["Model"] == m].iloc[0]
diff = r2["Gen Speed (t/s)"] - r1["Gen Speed (t/s)"]
pct = (diff / r1["Gen Speed (t/s)"] * 100) if r1["Gen Speed (t/s)"] else 0
rows.append([
m,
r1["Gen Speed (t/s)"],
r2["Gen Speed (t/s)"],
f"{diff:+.1f} ({pct:+.0f}%)",
r1["RAM Free (MB)"],
r2["RAM Free (MB)"],
])
return pd.DataFrame(rows, columns=[
"Model", f"{phone1} Gen (t/s)", f"{phone2} Gen (t/s)",
"Speed Difference", f"{phone1} RAM Free", f"{phone2} RAM Free",
])
# --- UI -----------------------------------------------------------------------
CSS = """
#dispatch-header h1 {
color: #FFFFFF; font-size: 2.2rem; margin: 0;
background: linear-gradient(90deg, #1FE0E6 0%, #FFFFFF 60%);
-webkit-background-clip: text; -webkit-text-fill-color: transparent;
}
#dispatch-header p { color: #1FE0E6; font-size: 1.05rem; margin: 6px 0 0 0; }
.dispatch-footer { text-align: center; color: #8A8F9C; font-size: 0.9rem; padding-top: 8px; }
"""
with gr.Blocks(
title="Dispatch AI — Mobile AI Speed Test",
theme=gr.themes.Base(
primary_hue="cyan", secondary_hue="cyan", neutral_hue="slate",
font=[gr.themes.GoogleFont("Inter"), "ui-sans-serif", "system-ui"],
).set(
body_background_fill="#0A0F1A", body_background_fill_dark="#0A0F1A",
body_text_color="#FFFFFF", body_text_color_dark="#FFFFFF",
block_background_fill="#0E1424", block_background_fill_dark="#0E1424",
block_border_color="#1FE0E6", block_border_width="1px",
block_label_text_color="#1FE0E6", block_title_text_color="#1FE0E6",
button_primary_background_fill="#1FE0E6", button_primary_background_fill_dark="#1FE0E6",
button_primary_text_color="#0A0F1A", button_primary_border_color="#1FE0E6",
input_background_fill="#0E1424", input_background_fill_dark="#0E1424",
input_border_color="#1FE0E6", input_border_width="1px",
),
css=CSS,
) as demo:
with gr.Column(elem_id="dispatch-header"):
gr.Markdown(
"""
# Dispatch AI — Mobile AI Speed Test
Like Speedtest, but for AI · Benchmarks from our 80-phone farm · Dispatch AI (FZE) · UAE
"""
)
gr.Markdown(
"""
Pick a phone to see how fast it runs popular AI models. Then compare two phones side-by-side.
All benchmarks measured with `llama.cpp`, Q4_K_M quants, 4 threads, FP16 offload.
"""
)
with gr.Tab("📱 Single Phone Test"):
with gr.Row():
phone_select = gr.Dropdown(
list(PHONES.keys()), label="Select Phone", value="Samsung S20 FE (SD865)",
)
run_btn = gr.Button("▶️ Run Speed Test", variant="primary")
phone_info = gr.Markdown()
result_table = gr.Dataframe(
headers=COLUMNS,
datatype=["str", "number", "number", "number", "number", "number"],
interactive=False, wrap=True,
column_widths=[220, 80, 100, 100, 100, 80],
)
with gr.Tab("⚔️ Compare Two Phones"):
with gr.Row():
phone1 = gr.Dropdown(list(PHONES.keys()), label="Phone 1", value="Samsung S20 FE (SD865)")
phone2 = gr.Dropdown(list(PHONES.keys()), label="Phone 2", value="OnePlus 11 (SD8 Gen2)")
compare_btn = gr.Button("⚔️ Compare", variant="primary")
compare_table = gr.Dataframe(interactive=False, wrap=True)
# Events
run_btn.click(
fn=lambda p: (get_phone_info(p), get_phone_benchmarks(p)),
inputs=phone_select, outputs=[phone_info, result_table],
)
compare_btn.click(
fn=compare_phones, inputs=[phone1, phone2], outputs=compare_table,
)
gr.Markdown(
"""
<div class="dispatch-footer">
© 2026 Dispatch AI (FZE) · Sharjah, UAE · License 10818 ·
Data from 80-device phone farm · Backend: llama.cpp Q4_K_M
</div>
"""
)
if __name__ == "__main__":
demo.queue()
demo.launch()
|