mlandia commited on
Commit
d077cfe
·
verified ·
1 Parent(s): 48b72af

Add Tiny Aya Global vs Earth ZeroGPU comparison app

Browse files
Files changed (3) hide show
  1. README.md +123 -6
  2. app.py +166 -0
  3. requirements.txt +2 -0
README.md CHANGED
@@ -1,13 +1,130 @@
1
  ---
2
  title: Tiny Aya Compare
3
- emoji: 🚀
4
- colorFrom: gray
5
- colorTo: pink
6
  sdk: gradio
7
  sdk_version: 6.18.0
8
- python_version: '3.12'
9
  app_file: app.py
10
- pinned: false
 
 
11
  ---
12
 
13
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  ---
2
  title: Tiny Aya Compare
3
+ emoji: 🌍
4
+ colorFrom: blue
5
+ colorTo: green
6
  sdk: gradio
7
  sdk_version: 6.18.0
 
8
  app_file: app.py
9
+ python_version: "3.12"
10
+ startup_duration_timeout: 30m
11
+ short_description: Compare Tiny Aya Global vs Earth side by side
12
  ---
13
 
14
+ # Tiny Aya Compare
15
+
16
+ Side-by-side comparison of [CohereLabs/tiny-aya-global](https://huggingface.co/CohereLabs/tiny-aya-global) and
17
+ [CohereLabs/tiny-aya-earth](https://huggingface.co/CohereLabs/tiny-aya-earth) on the same prompt.
18
+
19
+ **Live Space:** https://huggingface.co/spaces/build-small-hackathon/tiny-aya-compare
20
+
21
+ This Space runs on **ZeroGPU** using the PyTorch/safetensors checkpoints (not the GGUF builds).
22
+
23
+ ## Deploy to ZeroGPU (build-small-hackathon)
24
+
25
+ ### Prerequisites
26
+
27
+ - Hugging Face account with access to the `build-small-hackathon` org
28
+ - **PRO, Team, or Enterprise** plan (required to attach ZeroGPU to a Space you create)
29
+ - `hf` CLI installed and authenticated: `hf auth login`
30
+ - Access to the gated CohereLabs Tiny Aya models
31
+
32
+ ### 1. Create the Space
33
+
34
+ ```bash
35
+ hf repos create build-small-hackathon/tiny-aya-compare \
36
+ --type space \
37
+ --space-sdk gradio \
38
+ --flavor zero-a10g \
39
+ --public \
40
+ --exist-ok
41
+ ```
42
+
43
+ `--flavor zero-a10g` selects ZeroGPU. Hardware is **not** set via README frontmatter.
44
+
45
+ If the Space already exists on `cpu-basic`, switch hardware:
46
+
47
+ ```bash
48
+ hf spaces settings build-small-hackathon/tiny-aya-compare --hardware zero-a10g
49
+ ```
50
+
51
+ ### 2. Add the gated-model token
52
+
53
+ Both Tiny Aya checkpoints are gated. Add a Space secret so the runtime can download them:
54
+
55
+ ```bash
56
+ hf spaces secrets add build-small-hackathon/tiny-aya-compare \
57
+ --key HF_TOKEN \
58
+ --value "$(hf auth token)"
59
+ ```
60
+
61
+ Use a token with access to `CohereLabs/tiny-aya-global` and `CohereLabs/tiny-aya-earth`.
62
+
63
+ ### 3. Push the app
64
+
65
+ From this repo:
66
+
67
+ ```bash
68
+ git init
69
+ git add app.py README.md requirements.txt
70
+ git commit -m "Add Tiny Aya Global vs Earth ZeroGPU comparison app"
71
+ git remote add space https://huggingface.co/spaces/build-small-hackathon/tiny-aya-compare
72
+ git push space HEAD:main
73
+ ```
74
+
75
+ Or upload without git:
76
+
77
+ ```bash
78
+ hf upload build-small-hackathon/tiny-aya-compare . \
79
+ --include "app.py" \
80
+ --include "README.md" \
81
+ --include "requirements.txt"
82
+ ```
83
+
84
+ ### 4. Verify the deployment
85
+
86
+ ```bash
87
+ # Runtime stage and hardware
88
+ hf spaces info build-small-hackathon/tiny-aya-compare --expand runtime
89
+
90
+ # Build + startup logs
91
+ hf spaces logs build-small-hackathon/tiny-aya-compare --tail 200
92
+
93
+ # Smoke test (after RUNNING)
94
+ gradio predict build-small-hackathon/tiny-aya-compare /compare \
95
+ '{"prompt": "Explain photosynthesis simply.", "max_new_tokens": 128, "temperature": 0.7, "top_p": 0.9}'
96
+ ```
97
+
98
+ Expect `requested_hardware: zero-a10g` and both models loading at startup (~6 GB each in bf16).
99
+
100
+ ### 5. Update after changes
101
+
102
+ | Change | Action |
103
+ |--------|--------|
104
+ | `app.py`, `README.md` | `git push space main` (hot-reload) |
105
+ | `requirements.txt` | push → full Space rebuild |
106
+ | Hardware / secrets | `hf spaces settings` / `hf spaces secrets add` |
107
+
108
+ ## Local development (uv)
109
+
110
+ ZeroGPU Spaces require **Python 3.12** (not 3.14):
111
+
112
+ ```bash
113
+ uv python pin 3.12
114
+ uv sync --group dev
115
+ uv run python app.py
116
+ ```
117
+
118
+ Refresh `requirements.txt` after dependency changes (keep it minimal — Spaces preinstall `torch`, `gradio`, `spaces`, `huggingface_hub`):
119
+
120
+ ```bash
121
+ # Edit requirements.txt manually, e.g.:
122
+ # accelerate>=1.4.0
123
+ # transformers>=4.50.0
124
+ ```
125
+
126
+ ## Why not GGUF here?
127
+
128
+ ZeroGPU is built around PyTorch and `@spaces.GPU`. GGUF targets llama.cpp (Ollama, `llama-server`, local inference) and does not integrate with ZeroGPU's scheduler.
129
+
130
+ Use the Transformers checkpoints in this Space. The [GGUF repos](https://huggingface.co/CohereLabs/tiny-aya-global-GGUF) remain useful for local llama.cpp deployment.
app.py ADDED
@@ -0,0 +1,166 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import time
3
+
4
+ import spaces
5
+ import torch
6
+ import gradio as gr
7
+ from transformers import AutoModelForCausalLM, AutoTokenizer
8
+
9
+ MODELS = {
10
+ "global": {
11
+ "repo_id": "CohereLabs/tiny-aya-global",
12
+ "title": "Tiny Aya Global",
13
+ "subtitle": "Broad multilingual coverage (67+ languages).",
14
+ },
15
+ "earth": {
16
+ "repo_id": "CohereLabs/tiny-aya-earth",
17
+ "title": "Tiny Aya Earth",
18
+ "subtitle": "Grounded variant tuned for real-world context.",
19
+ },
20
+ }
21
+
22
+ HF_TOKEN = os.environ.get("HF_TOKEN")
23
+
24
+ tokenizers: dict[str, AutoTokenizer] = {}
25
+ models: dict[str, AutoModelForCausalLM] = {}
26
+
27
+ for key, meta in MODELS.items():
28
+ repo_id = meta["repo_id"]
29
+ tokenizers[key] = AutoTokenizer.from_pretrained(repo_id, token=HF_TOKEN)
30
+ models[key] = AutoModelForCausalLM.from_pretrained(
31
+ repo_id,
32
+ torch_dtype=torch.bfloat16,
33
+ token=HF_TOKEN,
34
+ ).to("cuda")
35
+
36
+ EXAMPLES = [
37
+ ["Explain photosynthesis in simple terms."],
38
+ ["¿Cuál es la capital de Perú y qué la hace especial?"],
39
+ ["Write a short haiku about rain."],
40
+ ["Quelles sont les différences entre le français québécois et le français de France?"],
41
+ ]
42
+
43
+
44
+ def _generate_one(
45
+ key: str,
46
+ prompt: str,
47
+ max_new_tokens: int,
48
+ temperature: float,
49
+ top_p: float,
50
+ ) -> tuple[str, float]:
51
+ tokenizer = tokenizers[key]
52
+ model = models[key]
53
+ inputs = tokenizer.apply_chat_template(
54
+ [{"role": "user", "content": prompt}],
55
+ add_generation_prompt=True,
56
+ return_tensors="pt",
57
+ ).to(model.device)
58
+
59
+ gen_kwargs: dict = {
60
+ "max_new_tokens": max_new_tokens,
61
+ "top_p": top_p,
62
+ "pad_token_id": tokenizer.eos_token_id,
63
+ }
64
+ if temperature > 0:
65
+ gen_kwargs["do_sample"] = True
66
+ gen_kwargs["temperature"] = temperature
67
+ else:
68
+ gen_kwargs["do_sample"] = False
69
+
70
+ started = time.perf_counter()
71
+ with torch.inference_mode():
72
+ output = model.generate(inputs, **gen_kwargs)
73
+ elapsed = time.perf_counter() - started
74
+
75
+ response = tokenizer.decode(
76
+ output[0, inputs.shape[-1] :],
77
+ skip_special_tokens=True,
78
+ ).strip()
79
+ return response, elapsed
80
+
81
+
82
+ def estimate_duration(
83
+ prompt: str,
84
+ max_new_tokens: int,
85
+ temperature: float,
86
+ top_p: float,
87
+ ) -> int:
88
+ _ = (prompt, temperature, top_p)
89
+ return int(10 + max_new_tokens * 0.2)
90
+
91
+
92
+ @spaces.GPU(duration=estimate_duration)
93
+ def compare(
94
+ prompt: str,
95
+ max_new_tokens: int,
96
+ temperature: float,
97
+ top_p: float,
98
+ ) -> tuple[str, str, str, str]:
99
+ if not prompt.strip():
100
+ message = "Enter a prompt to compare both models."
101
+ return message, message, "", ""
102
+
103
+ global_text, global_time = _generate_one(
104
+ "global", prompt, max_new_tokens, temperature, top_p
105
+ )
106
+ earth_text, earth_time = _generate_one(
107
+ "earth", prompt, max_new_tokens, temperature, top_p
108
+ )
109
+
110
+ global_stats = f"{global_time:.2f}s"
111
+ earth_stats = f"{earth_time:.2f}s"
112
+ return global_text, earth_text, global_stats, earth_stats
113
+
114
+
115
+ with gr.Blocks(title="Tiny Aya Compare") as demo:
116
+ gr.Markdown(
117
+ """
118
+ # Tiny Aya: Global vs Earth
119
+ Side-by-side comparison of [tiny-aya-global](https://huggingface.co/CohereLabs/tiny-aya-global)
120
+ and [tiny-aya-earth](https://huggingface.co/CohereLabs/tiny-aya-earth) on ZeroGPU.
121
+
122
+ Both models are gated. Set an `HF_TOKEN` Space secret with access to CohereLabs models.
123
+ """
124
+ )
125
+
126
+ prompt = gr.Textbox(
127
+ label="Prompt",
128
+ placeholder="Ask the same question in any supported language…",
129
+ lines=3,
130
+ )
131
+
132
+ with gr.Row():
133
+ max_new_tokens = gr.Slider(
134
+ 16, 512, value=256, step=16, label="Max new tokens"
135
+ )
136
+ temperature = gr.Slider(0, 1.5, value=0.7, step=0.05, label="Temperature")
137
+ top_p = gr.Slider(0.1, 1.0, value=0.9, step=0.05, label="Top-p")
138
+
139
+ compare_btn = gr.Button("Compare", variant="primary")
140
+
141
+ with gr.Row():
142
+ with gr.Column():
143
+ gr.Markdown(f"### {MODELS['global']['title']}")
144
+ gr.Markdown(MODELS["global"]["subtitle"])
145
+ global_out = gr.Textbox(label="Response", lines=12)
146
+ global_stats = gr.Textbox(label="Latency", interactive=False)
147
+ with gr.Column():
148
+ gr.Markdown(f"### {MODELS['earth']['title']}")
149
+ gr.Markdown(MODELS["earth"]["subtitle"])
150
+ earth_out = gr.Textbox(label="Response", lines=12)
151
+ earth_stats = gr.Textbox(label="Latency", interactive=False)
152
+
153
+ gr.Examples(
154
+ examples=EXAMPLES,
155
+ inputs=[prompt],
156
+ cache_examples=False,
157
+ )
158
+
159
+ compare_btn.click(
160
+ fn=compare,
161
+ inputs=[prompt, max_new_tokens, temperature, top_p],
162
+ outputs=[global_out, earth_out, global_stats, earth_stats],
163
+ )
164
+
165
+ if __name__ == "__main__":
166
+ demo.launch()
requirements.txt ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ accelerate>=1.4.0
2
+ transformers>=4.50.0