Joseph Pollack commited on
Commit
8bc23ce
·
unverified ·
1 Parent(s): ea25b4a

adds actually more interface improvements, language toggles , cpu fallbacks

Browse files
Files changed (3) hide show
  1. README.md +1 -1
  2. app.py +152 -77
  3. ui_strings.py +110 -2
README.md CHANGED
@@ -64,5 +64,5 @@ python download_bundles.py --inspect-only --infer # inspect existing downloads
64
 
65
  ## Deployment
66
 
67
- - **Hugging Face Spaces:** Set hardware to **Zero GPU** (or standard GPU). The app uses `@spaces.GPU` when available.
68
  - **Local:** Run `python app.py`; requires a GPU with ~10 GB VRAM for all 6 models.
 
64
 
65
  ## Deployment
66
 
67
+ - **Hugging Face Spaces:** Set hardware to **Zero GPU** (or standard GPU). The app uses `@spaces.GPU` when available. If Zero GPU workers fail with *"No CUDA GPUs are available"* (e.g. no free GPU in the pool), set the **CPU_FALLBACK** secret or environment variable to `1` so inference runs on CPU in-process instead of in GPU workers.
68
  - **Local:** Run `python app.py`; requires a GPU with ~10 GB VRAM for all 6 models.
app.py CHANGED
@@ -7,58 +7,29 @@ import gradio as gr
7
 
8
  from inference import BAGUETTOTRON_ID, run_all
9
  from model_config import (
10
- TIER_LABELS,
11
  combined_footprint,
12
  footprint_table_data,
13
  get_models_by_tier,
14
  MODELS,
15
  )
16
- from ui_strings import (
17
- BTN_GENERATE,
18
- COL_BAGUETTOTRON_HEADING,
19
- COL_LUTH_HEADING,
20
- FOOTPRINT_HEADERS,
21
- FOOTPRINT_INTRO,
22
- FOOTPRINT_SUMMARY_TEMPLATE,
23
- HEADING_FOOTPRINT,
24
- HEADING_GENERATION,
25
- HEADING_HOW_TO_USE,
26
- HEADING_LIVE_INFERENCE,
27
- HOW_TO_USE,
28
- INFO_REP_LUTH,
29
- INFO_TEMP_BAGUETTOTRON,
30
- JOIN_US,
31
- LABEL_MAX_TOKENS,
32
- LABEL_OUT_BAGUETTOTRON,
33
- LABEL_OUT_LUTH_06,
34
- LABEL_OUT_LUTH_07,
35
- LABEL_OUT_LUTH_12,
36
- LABEL_OUT_LUTH_17,
37
- LABEL_OUT_LUTH_350,
38
- LABEL_PROMPT,
39
- LABEL_REPEAT_PENALTY,
40
- LABEL_SYSTEM_PROMPT,
41
- LABEL_TEMPERATURE,
42
- LABEL_TOP_K,
43
- LABEL_TOP_P,
44
- PLACEHOLDER_PROMPT,
45
- PLACEHOLDER_SYSTEM_PROMPT,
46
- SUBTITLE,
47
- TITLE,
48
- )
49
 
50
  # Example run once on startup and cached for initial display (no system prompt)
51
  STARTUP_EXAMPLE_PROMPT = "dites moi en plus sur les jardins japonnais a paris :"
52
  STARTUP_EXAMPLE_SYSTEM = ""
53
 
54
- # Optional: use @spaces.GPU for ZeroGPU deployment
 
 
 
 
55
  try:
56
  import spaces
57
 
58
- GPU_DECORATOR = spaces.GPU
 
59
  except ImportError:
60
  GPU_DECORATOR = lambda f: f # no-op when not on Spaces
61
- # remove the lines above when using this code
62
 
63
  def build_params_by_model(
64
  temp_baguettotron: float,
@@ -136,9 +107,54 @@ def generate_all(
136
  return tuple(outputs)
137
 
138
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
139
  def create_ui():
 
140
  total_disk, total_vram = combined_footprint()
141
- footprint_md = FOOTPRINT_SUMMARY_TEMPLATE.format(total_disk=total_disk, total_vram=total_vram)
142
 
143
  # Run startup example once and cache for initial output display
144
  default_params = build_params_by_model(
@@ -156,97 +172,112 @@ def create_ui():
156
  for m in models_by_tier[tier]:
157
  startup_outputs.append(startup_results.get(m.repo_id, ""))
158
 
159
- with gr.Blocks(title=TITLE) as demo:
160
- gr.Markdown(f"# {TITLE}")
161
- gr.Markdown(SUBTITLE)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
162
 
163
  # Row 1: Single consolidated comparison table
164
- gr.Markdown(HEADING_FOOTPRINT)
165
- gr.Markdown(FOOTPRINT_INTRO)
166
  footprint_df = gr.Dataframe(
167
  value=footprint_table_data(),
168
- headers=FOOTPRINT_HEADERS,
169
  interactive=False,
170
  )
171
- gr.Markdown(footprint_md)
172
 
173
  # Row 2: Generation settings — two columns (Baguettotron | Luth)
174
- gr.Markdown(HEADING_GENERATION)
175
  with gr.Row():
176
  with gr.Column():
177
- gr.Markdown(COL_BAGUETTOTRON_HEADING)
178
- temp_baguettotron = gr.Slider(0, 2, value=0.5, label=LABEL_TEMPERATURE, info=INFO_TEMP_BAGUETTOTRON)
179
- max_tok_baguettotron = gr.Number(value=512, label=LABEL_MAX_TOKENS, minimum=64, maximum=2048)
180
- top_p_baguettotron = gr.Slider(0, 1, value=0.9, label=LABEL_TOP_P)
181
- top_k_baguettotron = gr.Number(value=40, label=LABEL_TOP_K)
182
- rep_baguettotron = gr.Slider(1.0, 1.5, value=1.1, label=LABEL_REPEAT_PENALTY)
183
  with gr.Column():
184
- gr.Markdown(COL_LUTH_HEADING)
185
- temp_luth = gr.Slider(0, 2, value=0.7, label=LABEL_TEMPERATURE)
186
- max_tok_luth = gr.Number(value=256, label=LABEL_MAX_TOKENS, minimum=64, maximum=2048)
187
- top_p_luth = gr.Slider(0, 1, value=0.9, label=LABEL_TOP_P)
188
- top_k_luth = gr.Number(value=40, label=LABEL_TOP_K)
189
- rep_luth = gr.Slider(1.0, 1.5, value=1.05, label=LABEL_REPEAT_PENALTY, info=INFO_REP_LUTH)
190
 
191
  # Row 3: Live inference — outputs above inputs
192
- gr.Markdown(HEADING_LIVE_INFERENCE)
193
  models_by_tier = get_models_by_tier()
194
- with gr.Tabs():
195
- with gr.Tab(TIER_LABELS["small"]):
196
  with gr.Row():
197
  out_baguettotron = gr.Textbox(
198
- label=LABEL_OUT_BAGUETTOTRON,
199
  lines=12,
200
  max_lines=24,
201
  value=startup_outputs[0],
202
  )
203
  out_luth_350 = gr.Textbox(
204
- label=LABEL_OUT_LUTH_350,
205
  lines=12,
206
  max_lines=24,
207
  value=startup_outputs[1],
208
  )
209
- with gr.Tab(TIER_LABELS["medium"]):
210
  with gr.Row():
211
  out_luth_06 = gr.Textbox(
212
- label=LABEL_OUT_LUTH_06,
213
  lines=12,
214
  max_lines=24,
215
  value=startup_outputs[2],
216
  )
217
  out_luth_07 = gr.Textbox(
218
- label=LABEL_OUT_LUTH_07,
219
  lines=12,
220
  max_lines=24,
221
  value=startup_outputs[3],
222
  )
223
- with gr.Tab(TIER_LABELS["large"]):
224
  with gr.Row():
225
  out_luth_12 = gr.Textbox(
226
- label=LABEL_OUT_LUTH_12,
227
  lines=12,
228
  max_lines=24,
229
  value=startup_outputs[4],
230
  )
231
  out_luth_17 = gr.Textbox(
232
- label=LABEL_OUT_LUTH_17,
233
  lines=12,
234
  max_lines=24,
235
  value=startup_outputs[5],
236
  )
237
 
238
  system_prompt_in = gr.Textbox(
239
- label=LABEL_SYSTEM_PROMPT,
240
- placeholder=PLACEHOLDER_SYSTEM_PROMPT,
241
  lines=2,
242
  )
243
  prompt_in = gr.Textbox(
244
- label=LABEL_PROMPT,
245
- placeholder=PLACEHOLDER_PROMPT,
246
  lines=3,
247
  value=STARTUP_EXAMPLE_PROMPT,
248
  )
249
- gen_btn = gr.Button(BTN_GENERATE, variant="primary")
250
 
251
  all_inputs = [
252
  prompt_in,
@@ -278,9 +309,53 @@ def create_ui():
278
  )
279
 
280
  # How to use & join us
281
- gr.Markdown(HEADING_HOW_TO_USE)
282
- gr.Markdown(HOW_TO_USE)
283
- gr.Markdown(JOIN_US)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
284
 
285
  return demo
286
 
 
7
 
8
  from inference import BAGUETTOTRON_ID, run_all
9
  from model_config import (
 
10
  combined_footprint,
11
  footprint_table_data,
12
  get_models_by_tier,
13
  MODELS,
14
  )
15
+ from ui_strings import get_strings
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
16
 
17
  # Example run once on startup and cached for initial display (no system prompt)
18
  STARTUP_EXAMPLE_PROMPT = "dites moi en plus sur les jardins japonnais a paris :"
19
  STARTUP_EXAMPLE_SYSTEM = ""
20
 
21
+ # Optional: use @spaces.GPU for ZeroGPU deployment.
22
+ # Set CPU_FALLBACK=1 (or any non-empty value) to skip ZeroGPU and run inference on CPU
23
+ # when no GPU is available (avoids "RuntimeError: No CUDA GPUs are available" in workers).
24
+ import os
25
+
26
  try:
27
  import spaces
28
 
29
+ _use_cpu_fallback = os.environ.get("CPU_FALLBACK", "").strip().lower() in ("1", "true", "yes")
30
+ GPU_DECORATOR = (lambda f: f) if _use_cpu_fallback else spaces.GPU
31
  except ImportError:
32
  GPU_DECORATOR = lambda f: f # no-op when not on Spaces
 
33
 
34
  def build_params_by_model(
35
  temp_baguettotron: float,
 
107
  return tuple(outputs)
108
 
109
 
110
+ def _ui_updates_for_locale(locale: str) -> tuple:
111
+ """Return (title, subtitle, heading_footprint, ...) for language toggle; order must match _LANG_OUTPUTS."""
112
+ s = get_strings(locale)
113
+ total_disk, total_vram = combined_footprint()
114
+ footprint_summary = s["FOOTPRINT_SUMMARY_TEMPLATE"].format(total_disk=total_disk, total_vram=total_vram)
115
+ return (
116
+ f"# {s['TITLE']}",
117
+ s["SUBTITLE"],
118
+ s["HEADING_FOOTPRINT"],
119
+ s["FOOTPRINT_INTRO"],
120
+ gr.update(headers=s["FOOTPRINT_HEADERS"]),
121
+ footprint_summary,
122
+ s["HEADING_GENERATION"],
123
+ s["COL_BAGUETTOTRON_HEADING"],
124
+ s["COL_LUTH_HEADING"],
125
+ gr.update(label=s["LABEL_TEMPERATURE"], info=s["INFO_TEMP_BAGUETTOTRON"]),
126
+ gr.update(label=s["LABEL_MAX_TOKENS"]),
127
+ gr.update(label=s["LABEL_TOP_P"]),
128
+ gr.update(label=s["LABEL_TOP_K"]),
129
+ gr.update(label=s["LABEL_REPEAT_PENALTY"]),
130
+ gr.update(label=s["LABEL_TEMPERATURE"]),
131
+ gr.update(label=s["LABEL_MAX_TOKENS"]),
132
+ gr.update(label=s["LABEL_TOP_P"]),
133
+ gr.update(label=s["LABEL_TOP_K"]),
134
+ gr.update(label=s["LABEL_REPEAT_PENALTY"], info=s["INFO_REP_LUTH"]),
135
+ s["HEADING_LIVE_INFERENCE"],
136
+ gr.update(label=s["TIER_SMALL"]),
137
+ gr.update(label=s["TIER_MEDIUM"]),
138
+ gr.update(label=s["TIER_LARGE"]),
139
+ gr.update(label=s["LABEL_OUT_BAGUETTOTRON"]),
140
+ gr.update(label=s["LABEL_OUT_LUTH_350"]),
141
+ gr.update(label=s["LABEL_OUT_LUTH_06"]),
142
+ gr.update(label=s["LABEL_OUT_LUTH_07"]),
143
+ gr.update(label=s["LABEL_OUT_LUTH_12"]),
144
+ gr.update(label=s["LABEL_OUT_LUTH_17"]),
145
+ gr.update(label=s["LABEL_SYSTEM_PROMPT"], placeholder=s["PLACEHOLDER_SYSTEM_PROMPT"]),
146
+ gr.update(label=s["LABEL_PROMPT"], placeholder=s["PLACEHOLDER_PROMPT"]),
147
+ gr.update(value=s["BTN_GENERATE"]),
148
+ s["HEADING_HOW_TO_USE"],
149
+ s["HOW_TO_USE"],
150
+ s["JOIN_US"],
151
+ )
152
+
153
+
154
  def create_ui():
155
+ s = get_strings("en")
156
  total_disk, total_vram = combined_footprint()
157
+ footprint_md = s["FOOTPRINT_SUMMARY_TEMPLATE"].format(total_disk=total_disk, total_vram=total_vram)
158
 
159
  # Run startup example once and cache for initial output display
160
  default_params = build_params_by_model(
 
172
  for m in models_by_tier[tier]:
173
  startup_outputs.append(startup_results.get(m.repo_id, ""))
174
 
175
+ with gr.Blocks(title=s["TITLE"]) as demo:
176
+ # Language (🇫🇷 / 🇺🇸) and theme (light / dark) toggles
177
+ with gr.Row(elem_classes="toggle-row"):
178
+ lang_radio = gr.Radio(
179
+ choices=[("🇺🇸 English", "en"), ("🇫🇷 Français", "fr")],
180
+ value="en",
181
+ label="Language",
182
+ scale=0,
183
+ min_width=180,
184
+ )
185
+ theme_btn = gr.Button("🌙 Dark mode", variant="secondary", scale=0, min_width=120)
186
+ theme_btn.click(
187
+ None,
188
+ js="() => { document.body.classList.toggle('dark'); }",
189
+ )
190
+
191
+ title_md = gr.Markdown(f"# {s['TITLE']}")
192
+ subtitle_md = gr.Markdown(s["SUBTITLE"])
193
 
194
  # Row 1: Single consolidated comparison table
195
+ heading_footprint_md = gr.Markdown(s["HEADING_FOOTPRINT"])
196
+ footprint_intro_md = gr.Markdown(s["FOOTPRINT_INTRO"])
197
  footprint_df = gr.Dataframe(
198
  value=footprint_table_data(),
199
+ headers=s["FOOTPRINT_HEADERS"],
200
  interactive=False,
201
  )
202
+ footprint_summary_md = gr.Markdown(footprint_md)
203
 
204
  # Row 2: Generation settings — two columns (Baguettotron | Luth)
205
+ heading_generation_md = gr.Markdown(s["HEADING_GENERATION"])
206
  with gr.Row():
207
  with gr.Column():
208
+ col_baguettotron_md = gr.Markdown(s["COL_BAGUETTOTRON_HEADING"])
209
+ temp_baguettotron = gr.Slider(0, 2, value=0.5, label=s["LABEL_TEMPERATURE"], info=s["INFO_TEMP_BAGUETTOTRON"])
210
+ max_tok_baguettotron = gr.Number(value=512, label=s["LABEL_MAX_TOKENS"], minimum=64, maximum=2048)
211
+ top_p_baguettotron = gr.Slider(0, 1, value=0.9, label=s["LABEL_TOP_P"])
212
+ top_k_baguettotron = gr.Number(value=40, label=s["LABEL_TOP_K"])
213
+ rep_baguettotron = gr.Slider(1.0, 1.5, value=1.1, label=s["LABEL_REPEAT_PENALTY"])
214
  with gr.Column():
215
+ col_luth_md = gr.Markdown(s["COL_LUTH_HEADING"])
216
+ temp_luth = gr.Slider(0, 2, value=0.7, label=s["LABEL_TEMPERATURE"])
217
+ max_tok_luth = gr.Number(value=256, label=s["LABEL_MAX_TOKENS"], minimum=64, maximum=2048)
218
+ top_p_luth = gr.Slider(0, 1, value=0.9, label=s["LABEL_TOP_P"])
219
+ top_k_luth = gr.Number(value=40, label=s["LABEL_TOP_K"])
220
+ rep_luth = gr.Slider(1.0, 1.5, value=1.05, label=s["LABEL_REPEAT_PENALTY"], info=s["INFO_REP_LUTH"])
221
 
222
  # Row 3: Live inference — outputs above inputs
223
+ heading_live_md = gr.Markdown(s["HEADING_LIVE_INFERENCE"])
224
  models_by_tier = get_models_by_tier()
225
+ with gr.Tabs() as tabs_root:
226
+ with gr.Tab(s["TIER_SMALL"], id="tab_small") as tab_small:
227
  with gr.Row():
228
  out_baguettotron = gr.Textbox(
229
+ label=s["LABEL_OUT_BAGUETTOTRON"],
230
  lines=12,
231
  max_lines=24,
232
  value=startup_outputs[0],
233
  )
234
  out_luth_350 = gr.Textbox(
235
+ label=s["LABEL_OUT_LUTH_350"],
236
  lines=12,
237
  max_lines=24,
238
  value=startup_outputs[1],
239
  )
240
+ with gr.Tab(s["TIER_MEDIUM"], id="tab_medium") as tab_medium:
241
  with gr.Row():
242
  out_luth_06 = gr.Textbox(
243
+ label=s["LABEL_OUT_LUTH_06"],
244
  lines=12,
245
  max_lines=24,
246
  value=startup_outputs[2],
247
  )
248
  out_luth_07 = gr.Textbox(
249
+ label=s["LABEL_OUT_LUTH_07"],
250
  lines=12,
251
  max_lines=24,
252
  value=startup_outputs[3],
253
  )
254
+ with gr.Tab(s["TIER_LARGE"], id="tab_large") as tab_large:
255
  with gr.Row():
256
  out_luth_12 = gr.Textbox(
257
+ label=s["LABEL_OUT_LUTH_12"],
258
  lines=12,
259
  max_lines=24,
260
  value=startup_outputs[4],
261
  )
262
  out_luth_17 = gr.Textbox(
263
+ label=s["LABEL_OUT_LUTH_17"],
264
  lines=12,
265
  max_lines=24,
266
  value=startup_outputs[5],
267
  )
268
 
269
  system_prompt_in = gr.Textbox(
270
+ label=s["LABEL_SYSTEM_PROMPT"],
271
+ placeholder=s["PLACEHOLDER_SYSTEM_PROMPT"],
272
  lines=2,
273
  )
274
  prompt_in = gr.Textbox(
275
+ label=s["LABEL_PROMPT"],
276
+ placeholder=s["PLACEHOLDER_PROMPT"],
277
  lines=3,
278
  value=STARTUP_EXAMPLE_PROMPT,
279
  )
280
+ gen_btn = gr.Button(s["BTN_GENERATE"], variant="primary")
281
 
282
  all_inputs = [
283
  prompt_in,
 
309
  )
310
 
311
  # How to use & join us
312
+ heading_how_to_use_md = gr.Markdown(s["HEADING_HOW_TO_USE"])
313
+ how_to_use_md = gr.Markdown(s["HOW_TO_USE"])
314
+ join_us_md = gr.Markdown(s["JOIN_US"])
315
+
316
+ # Language toggle: update all visible strings
317
+ _lang_outputs = [
318
+ title_md,
319
+ subtitle_md,
320
+ heading_footprint_md,
321
+ footprint_intro_md,
322
+ footprint_df,
323
+ footprint_summary_md,
324
+ heading_generation_md,
325
+ col_baguettotron_md,
326
+ col_luth_md,
327
+ temp_baguettotron,
328
+ max_tok_baguettotron,
329
+ top_p_baguettotron,
330
+ top_k_baguettotron,
331
+ rep_baguettotron,
332
+ temp_luth,
333
+ max_tok_luth,
334
+ top_p_luth,
335
+ top_k_luth,
336
+ rep_luth,
337
+ heading_live_md,
338
+ tab_small,
339
+ tab_medium,
340
+ tab_large,
341
+ out_baguettotron,
342
+ out_luth_350,
343
+ out_luth_06,
344
+ out_luth_07,
345
+ out_luth_12,
346
+ out_luth_17,
347
+ system_prompt_in,
348
+ prompt_in,
349
+ gen_btn,
350
+ heading_how_to_use_md,
351
+ how_to_use_md,
352
+ join_us_md,
353
+ ]
354
+ lang_radio.change(
355
+ fn=_ui_updates_for_locale,
356
+ inputs=[lang_radio],
357
+ outputs=_lang_outputs,
358
+ )
359
 
360
  return demo
361
 
ui_strings.py CHANGED
@@ -3,6 +3,10 @@ UI text strings for the Baguettotron vs Luth Gradio app.
3
  Centralized for reuse and easier i18n.
4
  """
5
 
 
 
 
 
6
  # App identity
7
  TITLE = "Is a government-backed darling any better than a highschoolers' project?"
8
  SUBTITLE = "Baguettotron vs Luth models : one is a fully subsidized project with priority access to public compute infrastructure , the other is a highschooler's project"
@@ -48,6 +52,11 @@ LABEL_OUT_LUTH_07 = "Luth-LFM2-700M"
48
  LABEL_OUT_LUTH_12 = "Luth-LFM2-1.2B"
49
  LABEL_OUT_LUTH_17 = "Luth-1.7B-Instruct"
50
 
 
 
 
 
 
51
  # How to use & context
52
  HEADING_HOW_TO_USE = "## How to use this demo"
53
  HOW_TO_USE = """
@@ -60,8 +69,6 @@ HOW_TO_USE = """
60
  4. the ultimate judge of quality is the user's ability to use the model to achieve their goals
61
 
62
  Results are grouped by parameter size so you can compare Baguettotron with Luth-LFM2-350M in the Small tab, and the larger Luth models in the Medium and Large tabs.
63
-
64
- *Console:* If you see `lm_head.weight | MISSING` when loading Luth-0.6B or Luth-1.7B, that’s expected (tied embeddings); the models run correctly.
65
  """
66
 
67
  # Join us (TeamTonic community)
@@ -73,3 +80,104 @@ On 🤗Huggingface: [MultiTransformer](https://huggingface.co/MultiTransformer)
73
  On 🌐Github: [Tonic-AI](https://github.com/tonic-ai) & contribute to🌟 [Build Tonic](https://git.tonic-ai.com/contribute)
74
  🤗Big thanks to Yuvi Sharma and all the folks at huggingface for the community grant 🤗
75
  """
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3
  Centralized for reuse and easier i18n.
4
  """
5
 
6
+ # ---------------------------------------------------------------------------
7
+ # English (default) — also used as key names
8
+ # ---------------------------------------------------------------------------
9
+
10
  # App identity
11
  TITLE = "Is a government-backed darling any better than a highschoolers' project?"
12
  SUBTITLE = "Baguettotron vs Luth models : one is a fully subsidized project with priority access to public compute infrastructure , the other is a highschooler's project"
 
52
  LABEL_OUT_LUTH_12 = "Luth-LFM2-1.2B"
53
  LABEL_OUT_LUTH_17 = "Luth-1.7B-Instruct"
54
 
55
+ # Tab tier labels
56
+ TIER_SMALL = "~0.3–0.4B (Small)"
57
+ TIER_MEDIUM = "~0.6–0.7B (Medium)"
58
+ TIER_LARGE = "~1–2B (Large)"
59
+
60
  # How to use & context
61
  HEADING_HOW_TO_USE = "## How to use this demo"
62
  HOW_TO_USE = """
 
69
  4. the ultimate judge of quality is the user's ability to use the model to achieve their goals
70
 
71
  Results are grouped by parameter size so you can compare Baguettotron with Luth-LFM2-350M in the Small tab, and the larger Luth models in the Medium and Large tabs.
 
 
72
  """
73
 
74
  # Join us (TeamTonic community)
 
80
  On 🌐Github: [Tonic-AI](https://github.com/tonic-ai) & contribute to🌟 [Build Tonic](https://git.tonic-ai.com/contribute)
81
  🤗Big thanks to Yuvi Sharma and all the folks at huggingface for the community grant 🤗
82
  """
83
+
84
+ # ---------------------------------------------------------------------------
85
+ # Translations: en + fr (for language toggle)
86
+ # ---------------------------------------------------------------------------
87
+
88
+ TRANSLATIONS = {
89
+ "en": {
90
+ "TITLE": TITLE,
91
+ "SUBTITLE": SUBTITLE,
92
+ "HEADING_FOOTPRINT": HEADING_FOOTPRINT,
93
+ "FOOTPRINT_HEADERS": FOOTPRINT_HEADERS,
94
+ "FOOTPRINT_SUMMARY_TEMPLATE": FOOTPRINT_SUMMARY_TEMPLATE,
95
+ "FOOTPRINT_INTRO": FOOTPRINT_INTRO,
96
+ "HEADING_GENERATION": HEADING_GENERATION,
97
+ "COL_BAGUETTOTRON_HEADING": COL_BAGUETTOTRON_HEADING,
98
+ "COL_LUTH_HEADING": COL_LUTH_HEADING,
99
+ "LABEL_TEMPERATURE": LABEL_TEMPERATURE,
100
+ "LABEL_MAX_TOKENS": LABEL_MAX_TOKENS,
101
+ "LABEL_TOP_P": LABEL_TOP_P,
102
+ "LABEL_TOP_K": LABEL_TOP_K,
103
+ "LABEL_REPEAT_PENALTY": LABEL_REPEAT_PENALTY,
104
+ "INFO_TEMP_BAGUETTOTRON": INFO_TEMP_BAGUETTOTRON,
105
+ "INFO_REP_LUTH": INFO_REP_LUTH,
106
+ "HEADING_LIVE_INFERENCE": HEADING_LIVE_INFERENCE,
107
+ "LABEL_SYSTEM_PROMPT": LABEL_SYSTEM_PROMPT,
108
+ "PLACEHOLDER_SYSTEM_PROMPT": PLACEHOLDER_SYSTEM_PROMPT,
109
+ "LABEL_PROMPT": LABEL_PROMPT,
110
+ "PLACEHOLDER_PROMPT": PLACEHOLDER_PROMPT,
111
+ "BTN_GENERATE": BTN_GENERATE,
112
+ "LABEL_OUT_BAGUETTOTRON": LABEL_OUT_BAGUETTOTRON,
113
+ "LABEL_OUT_LUTH_350": LABEL_OUT_LUTH_350,
114
+ "LABEL_OUT_LUTH_06": LABEL_OUT_LUTH_06,
115
+ "LABEL_OUT_LUTH_07": LABEL_OUT_LUTH_07,
116
+ "LABEL_OUT_LUTH_12": LABEL_OUT_LUTH_12,
117
+ "LABEL_OUT_LUTH_17": LABEL_OUT_LUTH_17,
118
+ "TIER_SMALL": TIER_SMALL,
119
+ "TIER_MEDIUM": TIER_MEDIUM,
120
+ "TIER_LARGE": TIER_LARGE,
121
+ "HEADING_HOW_TO_USE": HEADING_HOW_TO_USE,
122
+ "HOW_TO_USE": HOW_TO_USE,
123
+ "JOIN_US": JOIN_US,
124
+ },
125
+ "fr": {
126
+ "TITLE": "Un chouchou subventionné vaut-il mieux qu'un projet de lycéen ?",
127
+ "SUBTITLE": "Baguettotron vs Luth : l'un est un projet subventionné avec accès prioritaire au calcul public, l'autre est un projet de lycéen.",
128
+ "HEADING_FOOTPRINT": "## Comparaison des modèles",
129
+ "FOOTPRINT_HEADERS": [
130
+ "Modèle",
131
+ "Params",
132
+ "Disque/VRAM brut (Mo)",
133
+ "Visible sur téléphone",
134
+ "GGUF Q4_K_M (Mo)",
135
+ "Source",
136
+ ],
137
+ "FOOTPRINT_SUMMARY_TEMPLATE": "**Empreinte totale —** VRAM (est.) : {total_vram:.2f} Go",
138
+ "FOOTPRINT_INTRO": "Transformers (BF16) disque/VRAM ; tailles GGUF depuis PleIAs/Baguettotron-GGUF (HF) et bundles LEAP.",
139
+ "HEADING_GENERATION": "## Réglages de génération (par famille de modèle)",
140
+ "COL_BAGUETTOTRON_HEADING": "**Baguettotron (321M)** — *raisonnement*",
141
+ "COL_LUTH_HEADING": "**Luth (0,4B–1,7B)** — *instruct*",
142
+ "LABEL_TEMPERATURE": "Température",
143
+ "LABEL_MAX_TOKENS": "Tokens max",
144
+ "LABEL_TOP_P": "Top p",
145
+ "LABEL_TOP_K": "Top k",
146
+ "LABEL_REPEAT_PENALTY": "Pénalité de répétition",
147
+ "INFO_TEMP_BAGUETTOTRON": "Plus bas pour un raisonnement plus déterministe",
148
+ "INFO_REP_LUTH": "Luth/LFM2 utilisent souvent ~1,05",
149
+ "HEADING_LIVE_INFERENCE": "## Inférence en direct",
150
+ "LABEL_SYSTEM_PROMPT": "Prompt système (optionnel)",
151
+ "PLACEHOLDER_SYSTEM_PROMPT": "ex. Tu es un assistant qui répond en français.",
152
+ "LABEL_PROMPT": "Prompt",
153
+ "PLACEHOLDER_PROMPT": "Saisissez votre prompt ici…",
154
+ "BTN_GENERATE": "Générer",
155
+ "LABEL_OUT_BAGUETTOTRON": "Baguettotron (321M)",
156
+ "LABEL_OUT_LUTH_350": "Luth-LFM2-350M (0,4B)",
157
+ "LABEL_OUT_LUTH_06": "Luth-0.6B-Instruct",
158
+ "LABEL_OUT_LUTH_07": "Luth-LFM2-700M",
159
+ "LABEL_OUT_LUTH_12": "Luth-LFM2-1.2B",
160
+ "LABEL_OUT_LUTH_17": "Luth-1.7B-Instruct",
161
+ "TIER_SMALL": "~0,3–0,4B (Petit)",
162
+ "TIER_MEDIUM": "~0,6–0,7B (Moyen)",
163
+ "TIER_LARGE": "~1–2B (Grand)",
164
+ "HEADING_HOW_TO_USE": "## Comment utiliser cette démo",
165
+ "HOW_TO_USE": """
166
+ **Contexte :** Cette app envoie le même prompt à **Baguettotron** (PleIAs, 321M) et aux **cinq modèles Luth** (kurakurai, 0,4B–1,7B) pour comparer les sorties côte à côte. Le tableau ci-dessus résume la taille, la VRAM et les options GGUF/LEAP.
167
+
168
+ **Étapes :**
169
+ 1. [Baguettotron-GGUF-321M](https://hf.co/PleIAs/Baguettotron-GGUF-321M) prétend des perfs hors du réel observable.
170
+ 2. le jeu [SYNTH](https://hf.co/datasets/pleias/synth) doit être audité pour contamination avant usage.
171
+ 3. la compression des modèles PleIAs sous-performe par rapport à une compression identique sur des modèles similaires.
172
+ 4. le critère final reste la capacité de l'utilisateur à atteindre ses objectifs avec le modèle.
173
+
174
+ Les résultats sont regroupés par taille pour comparer Baguettotron avec Luth-LFM2-350M dans l'onglet Petit, et les Luth plus gros dans Moyen et Grand.
175
+ """,
176
+ "JOIN_US": JOIN_US, # same as en (links + community)
177
+ },
178
+ }
179
+
180
+
181
+ def get_strings(locale: str) -> dict:
182
+ """Return the full dict of UI strings for the given locale. Fallback to 'en'."""
183
+ return TRANSLATIONS.get(locale, TRANSLATIONS["en"]).copy()