GauravGosain commited on
Commit
528f974
·
verified ·
1 Parent(s): ad960b8

Gemma 4 12B brain on ZeroGPU (transformers)

Browse files
Files changed (3) hide show
  1. README.md +18 -6
  2. app.py +95 -0
  3. requirements.txt +5 -0
README.md CHANGED
@@ -1,13 +1,25 @@
1
  ---
2
- title: Small Talk Llm
3
- emoji: 🐠
4
- colorFrom: blue
5
  colorTo: indigo
6
  sdk: gradio
7
- sdk_version: 6.17.3
8
- python_version: '3.13'
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: Small Talk LLM Brain
3
+ emoji: 🧠
4
+ colorFrom: yellow
5
  colorTo: indigo
6
  sdk: gradio
 
 
7
  app_file: app.py
8
  pinned: false
9
+ suggested_hardware: zero-a10g
10
+ short_description: Gemma 4 12B brain for the Small Talk robot podcast
11
  ---
12
 
13
+ # Small Talk · LLM Brain
14
+
15
+ The live-banter brain for [**Small Talk**](https://huggingface.co/spaces/build-small-hackathon/small-talk),
16
+ an AI-to-AI robot podcast hosted by Reachy Mini robots.
17
+
18
+ - **Model:** [`google/gemma-4-12b-it`](https://huggingface.co/google/gemma-4-12b-it)
19
+ — the QAT-trained Gemma 4 12B, run in bf16.
20
+ - **Hardware:** ZeroGPU.
21
+ - **Use:** pass a character description as the system prompt to voice a persona;
22
+ the podcast backend calls this Space as an API to generate in-character lines.
23
+
24
+ The int4-QAT GGUF + `llama.cpp` (`llama-server`) deployment runs separately on
25
+ Modal — this Space is the always-on ZeroGPU brain.
app.py ADDED
@@ -0,0 +1,95 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Small Talk · LLM brain — Gemma 4 12B on ZeroGPU via 🤗 transformers.
2
+
3
+ A separate Space from the main Small Talk app: it exposes a chat endpoint the
4
+ podcast backend can call to generate live, in-character robot banter. We run the
5
+ QAT-trained Gemma 4 12B in bf16 here (the canonical, rock-solid ZeroGPU path);
6
+ the int4-QAT GGUF + llama.cpp deployment lives on Modal later.
7
+
8
+ `import spaces` MUST come before torch so ZeroGPU can patch CUDA.
9
+ """
10
+ import os
11
+ from threading import Thread
12
+
13
+ import spaces
14
+ import gradio as gr
15
+ import torch
16
+ from transformers import AutoModelForCausalLM, AutoTokenizer, TextIteratorStreamer
17
+
18
+ MODEL_ID = os.environ.get("MODEL_ID", "google/gemma-4-12b-it")
19
+
20
+ tokenizer = AutoTokenizer.from_pretrained(MODEL_ID)
21
+ model = AutoModelForCausalLM.from_pretrained(
22
+ MODEL_ID,
23
+ torch_dtype=torch.bfloat16,
24
+ device_map="auto",
25
+ )
26
+ model.eval()
27
+
28
+ DEFAULT_SYSTEM = (
29
+ "You are a host on 'Small Talk', a live AI-to-AI robot podcast hosted by "
30
+ "Reachy Mini robots. Stay fully in character. Keep every reply short, witty "
31
+ "and conversational — one or two punchy sentences, like talk-show banter. "
32
+ "No stage directions, no emoji spam, no markdown."
33
+ )
34
+
35
+
36
+ def _messages(message, history, system_prompt):
37
+ """Build the chat list. Gemma has no system role, so we fold the persona
38
+ into the earliest user turn."""
39
+ sys = (system_prompt or DEFAULT_SYSTEM).strip()
40
+ msgs = [{"role": m["role"], "content": m["content"]} for m in (history or [])]
41
+ msgs.append({"role": "user", "content": message})
42
+ for m in msgs:
43
+ if m["role"] == "user":
44
+ m["content"] = f"{sys}\n\n{m['content']}"
45
+ break
46
+ return msgs
47
+
48
+
49
+ @spaces.GPU(duration=120)
50
+ def chat(message, history, system_prompt, temperature, max_new_tokens):
51
+ msgs = _messages(message, history, system_prompt)
52
+ input_ids = tokenizer.apply_chat_template(
53
+ msgs, add_generation_prompt=True, return_tensors="pt"
54
+ ).to(model.device)
55
+
56
+ streamer = TextIteratorStreamer(tokenizer, skip_prompt=True, skip_special_tokens=True)
57
+ gen_kwargs = dict(
58
+ input_ids=input_ids,
59
+ streamer=streamer,
60
+ max_new_tokens=int(max_new_tokens),
61
+ do_sample=temperature > 0,
62
+ temperature=float(temperature) if temperature > 0 else None,
63
+ top_p=0.95,
64
+ repetition_penalty=1.05,
65
+ )
66
+ Thread(target=model.generate, kwargs=gen_kwargs).start()
67
+
68
+ out = ""
69
+ for piece in streamer:
70
+ out += piece
71
+ yield out
72
+
73
+
74
+ demo = gr.ChatInterface(
75
+ chat,
76
+ type="messages",
77
+ additional_inputs=[
78
+ gr.Textbox(value=DEFAULT_SYSTEM, label="System / persona", lines=3),
79
+ gr.Slider(0.0, 1.5, value=0.9, step=0.05, label="Temperature"),
80
+ gr.Slider(16, 1024, value=384, step=8, label="Max new tokens"),
81
+ ],
82
+ title="Small Talk · Gemma 4 12B brain",
83
+ description=(
84
+ "The live-banter brain for the Small Talk robot podcast — Gemma 4 12B "
85
+ "(QAT-trained, bf16) on ZeroGPU. Pass a persona as the system prompt to "
86
+ "voice a character. Callable as an API by the podcast backend."
87
+ ),
88
+ examples=[
89
+ ["Is a hot dog a sandwich? Defend your answer.", "You are Batman: terse, brooding, weirdly into encased meats."],
90
+ ["Pitch me your dream podcast episode.", "You are a chill surfer robot. Everything is vibes, brah."],
91
+ ],
92
+ )
93
+
94
+ if __name__ == "__main__":
95
+ demo.queue(max_size=16).launch()
requirements.txt ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ # torch is preinstalled on ZeroGPU — do NOT pin it here (pinning breaks ZeroGPU).
2
+ spaces
3
+ transformers
4
+ accelerate
5
+ sentencepiece