Gogs commited on
Commit
29256c1
Β·
1 Parent(s): 6f78033

🌸 Professional Yuuki demo with full UI and stats

Browse files
Files changed (3) hide show
  1. README.md +44 -10
  2. app.py +287 -54
  3. requirements.txt +4 -0
README.md CHANGED
@@ -1,15 +1,49 @@
1
  ---
2
- title: Yuuki
3
- emoji: πŸ’¬
4
- colorFrom: yellow
5
- colorTo: purple
6
  sdk: gradio
7
- sdk_version: 5.42.0
8
  app_file: app.py
9
- pinned: false
10
- hf_oauth: true
11
- hf_oauth_scopes:
12
- - inference-api
 
 
 
 
13
  ---
14
 
15
- An example chatbot using [Gradio](https://gradio.app), [`huggingface_hub`](https://huggingface.co/docs/huggingface_hub/v0.22.2/en/index), and the [Hugging Face Inference API](https://huggingface.co/docs/api-inference/index).
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  ---
2
+ title: Yuuki - Mobile-Trained Code Generator
3
+ emoji: 🌸
4
+ colorFrom: purple
5
+ colorTo: pink
6
  sdk: gradio
7
+ sdk_version: 4.44.0
8
  app_file: app.py
9
+ pinned: true
10
+ license: apache-2.0
11
+ tags:
12
+ - code-generation
13
+ - mobile-training
14
+ - zero-budget
15
+ - edge-ml
16
+ - experimental
17
  ---
18
 
19
+ # 🌸 Yuuki - Mobile-Trained Code Generator
20
+
21
+ **First LLM trained entirely on mobile CPU with $0 budget.**
22
+
23
+ Try the live demo above!
24
+
25
+ ## Features
26
+
27
+ - βœ… Agda code generation (best performance: 55/100)
28
+ - ⚠️ Limited C, Assembly support
29
+ - πŸ“± Trained on Snapdragon 685 CPU
30
+ - πŸ’° Zero computational cost
31
+ - πŸ”¬ Fully documented research experiment
32
+
33
+ ## Model
34
+
35
+ - **Base:** DistilGPT-2 (82M parameters)
36
+ - **Training:** 2,000 steps (5.3% of v0.1)
37
+ - **Hardware:** Mobile CPU only
38
+ - **Time:** ~50 hours continuous
39
+ - **Cost:** $0.00
40
+
41
+ ## Links
42
+
43
+ - πŸ€— [Model Card](https://huggingface.co/OpceanAI/Yuuki-best)
44
+ - πŸ“„ Paper (coming soon)
45
+ - πŸ’» [Training Code](https://github.com/YuuKi-OS/yuuki-training)
46
+
47
+ ---
48
+
49
+ *Proving the barrier to AI is mindset, not money* 🌸
app.py CHANGED
@@ -1,70 +1,303 @@
1
  import gradio as gr
2
- from huggingface_hub import InferenceClient
 
3
 
 
 
 
4
 
5
- def respond(
6
- message,
7
- history: list[dict[str, str]],
8
- system_message,
9
- max_tokens,
10
- temperature,
11
- top_p,
12
- hf_token: gr.OAuthToken,
13
- ):
14
- """
15
- For more information on `huggingface_hub` Inference API support, please check the docs: https://huggingface.co/docs/huggingface_hub/v0.22.2/en/guides/inference
16
- """
17
- client = InferenceClient(token=hf_token.token, model="openai/gpt-oss-20b")
18
 
19
- messages = [{"role": "system", "content": system_message}]
 
 
 
 
 
 
 
 
 
 
 
20
 
21
- messages.extend(history)
 
 
22
 
23
- messages.append({"role": "user", "content": message})
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
24
 
25
- response = ""
 
 
26
 
27
- for message in client.chat_completion(
28
- messages,
29
- max_tokens=max_tokens,
30
- stream=True,
31
- temperature=temperature,
32
- top_p=top_p,
33
- ):
34
- choices = message.choices
35
- token = ""
36
- if len(choices) and choices[0].delta.content:
37
- token = choices[0].delta.content
 
 
 
38
 
39
- response += token
40
- yield response
 
41
 
 
 
 
 
 
 
 
 
 
 
42
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
43
  """
44
- For information on how to customize the ChatInterface, peruse the gradio docs: https://www.gradio.app/docs/chatinterface
45
- """
46
- chatbot = gr.ChatInterface(
47
- respond,
48
- type="messages",
49
- additional_inputs=[
50
- gr.Textbox(value="You are a friendly Chatbot.", label="System message"),
51
- gr.Slider(minimum=1, maximum=2048, value=512, step=1, label="Max new tokens"),
52
- gr.Slider(minimum=0.1, maximum=4.0, value=0.7, step=0.1, label="Temperature"),
53
- gr.Slider(
54
- minimum=0.1,
55
- maximum=1.0,
56
- value=0.95,
57
- step=0.05,
58
- label="Top-p (nucleus sampling)",
59
- ),
60
- ],
61
- )
62
-
63
- with gr.Blocks() as demo:
64
- with gr.Sidebar():
65
- gr.LoginButton()
66
- chatbot.render()
67
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
68
 
 
69
  if __name__ == "__main__":
70
  demo.launch()
 
1
  import gradio as gr
2
+ from transformers import AutoModelForCausalLM, AutoTokenizer
3
+ import torch
4
 
5
+ # ============================================================================
6
+ # 🌸 YUUKI - Mobile-Trained Code Generator
7
+ # ============================================================================
8
 
9
+ print("🌸 Loading Yuuki model...")
10
+ print("This may take a minute on first load...")
 
 
 
 
 
 
 
 
 
 
 
11
 
12
+ try:
13
+ model = AutoModelForCausalLM.from_pretrained(
14
+ "OpceanAI/Yuuki-best",
15
+ torch_dtype=torch.float32,
16
+ low_cpu_mem_usage=True
17
+ )
18
+ tokenizer = AutoTokenizer.from_pretrained("OpceanAI/Yuuki-best")
19
+ print("βœ… Model loaded successfully!")
20
+ except Exception as e:
21
+ print(f"❌ Error loading model: {e}")
22
+ model = None
23
+ tokenizer = None
24
 
25
+ # ============================================================================
26
+ # Generation Function
27
+ # ============================================================================
28
 
29
+ def generate_code(
30
+ prompt: str,
31
+ max_length: int = 100,
32
+ temperature: float = 0.7,
33
+ top_p: float = 0.9
34
+ ) -> str:
35
+ """Generate code completion using Yuuki."""
36
+
37
+ if model is None or tokenizer is None:
38
+ return "❌ Model failed to load. Please refresh the page."
39
+
40
+ if not prompt.strip():
41
+ return "⚠️ Please enter a code prompt."
42
+
43
+ try:
44
+ inputs = tokenizer(prompt, return_tensors="pt")
45
+
46
+ with torch.no_grad():
47
+ outputs = model.generate(
48
+ **inputs,
49
+ max_length=max_length,
50
+ temperature=temperature,
51
+ top_p=top_p,
52
+ do_sample=True,
53
+ pad_token_id=tokenizer.eos_token_id,
54
+ eos_token_id=tokenizer.eos_token_id
55
+ )
56
+
57
+ generated = tokenizer.decode(outputs[0], skip_special_tokens=True)
58
+ return generated
59
+
60
+ except Exception as e:
61
+ return f"❌ Generation error: {str(e)}"
62
 
63
+ # ============================================================================
64
+ # Examples
65
+ # ============================================================================
66
 
67
+ examples = [
68
+ # Agda (best language)
69
+ ["module Main where", 100, 0.7, 0.9],
70
+ ["open import Data.Nat", 80, 0.7, 0.9],
71
+ ["data Bool : Set where", 80, 0.7, 0.9],
72
+
73
+ # C (limited but improving)
74
+ ["int main() {", 80, 0.7, 0.9],
75
+ ["#include <stdio.h>", 60, 0.7, 0.9],
76
+
77
+ # Python (weak due to dataset ordering)
78
+ ["def hello():", 60, 0.8, 0.9],
79
+ ["import numpy as np", 60, 0.7, 0.9],
80
+ ]
81
 
82
+ # ============================================================================
83
+ # Custom CSS
84
+ # ============================================================================
85
 
86
+ custom_css = """
87
+ #title {
88
+ text-align: center;
89
+ background: linear-gradient(90deg, #667eea 0%, #764ba2 100%);
90
+ -webkit-background-clip: text;
91
+ -webkit-text-fill-color: transparent;
92
+ font-size: 3em;
93
+ font-weight: bold;
94
+ margin-bottom: 0.5em;
95
+ }
96
 
97
+ #subtitle {
98
+ text-align: center;
99
+ font-size: 1.3em;
100
+ color: #666;
101
+ margin-bottom: 1em;
102
+ }
103
+
104
+ #warning-box {
105
+ background: linear-gradient(135deg, #fff3cd 0%, #ffe8a1 100%);
106
+ border-left: 4px solid #ffc107;
107
+ border-radius: 8px;
108
+ padding: 20px;
109
+ margin: 20px 0;
110
+ box-shadow: 0 2px 4px rgba(0,0,0,0.1);
111
+ }
112
+
113
+ #stats-box {
114
+ background: linear-gradient(135deg, #e7f3ff 0%, #cfe7ff 100%);
115
+ border-left: 4px solid #2196F3;
116
+ border-radius: 8px;
117
+ padding: 20px;
118
+ margin: 20px 0;
119
+ box-shadow: 0 2px 4px rgba(0,0,0,0.1);
120
+ }
121
+
122
+ #achievement-box {
123
+ background: linear-gradient(135deg, #f0e8ff 0%, #e1d4ff 100%);
124
+ border-left: 4px solid #9c27b0;
125
+ border-radius: 8px;
126
+ padding: 20px;
127
+ margin: 20px 0;
128
+ box-shadow: 0 2px 4px rgba(0,0,0,0.1);
129
+ }
130
+
131
+ .gr-button-primary {
132
+ background: linear-gradient(90deg, #667eea 0%, #764ba2 100%) !important;
133
+ border: none !important;
134
+ font-weight: bold !important;
135
+ }
136
+
137
+ footer {
138
+ margin-top: 40px;
139
+ padding-top: 20px;
140
+ border-top: 1px solid #ddd;
141
+ }
142
  """
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
143
 
144
+ # ============================================================================
145
+ # Gradio Interface
146
+ # ============================================================================
147
+
148
+ with gr.Blocks(css=custom_css, title="🌸 Yuuki - Mobile-Trained Code Generator", theme=gr.themes.Soft()) as demo:
149
+
150
+ # Header
151
+ gr.Markdown("<h1 id='title'>🌸 Yuuki</h1>")
152
+ gr.Markdown("<p id='subtitle'>First LLM Trained Entirely on Mobile CPU | Zero-Budget ML Research</p>")
153
+
154
+ # Warning Box
155
+ gr.Markdown("""
156
+ <div id='warning-box'>
157
+ <h3 style='margin-top:0; color:#856404;'>⚠️ Experimental Research Model</h3>
158
+ <p style='margin-bottom:0;'>
159
+ Yuuki was trained on a <strong>smartphone CPU</strong> with <strong>$0 budget</strong>.
160
+ This is a <strong>proof-of-concept</strong> demonstrating mobile training feasibility,
161
+ not a production-ready code generator.
162
+ </p>
163
+ <br>
164
+ <p style='margin-bottom:0;'>
165
+ <strong>Best at:</strong> Agda (55/100) β€’
166
+ <strong>Limited:</strong> C (20/100), Assembly (15/100) β€’
167
+ <strong>Weak:</strong> Python (8/100)
168
+ </p>
169
+ </div>
170
+ """)
171
+
172
+ # Stats Box
173
+ gr.Markdown("""
174
+ <div id='stats-box'>
175
+ <h3 style='margin-top:0; color:#0d47a1;'>πŸ“Š Training Statistics</h3>
176
+ <p style='margin-bottom:5px;'><strong>Hardware:</strong> Snapdragon 685 (CPU only) | <strong>Steps:</strong> 2,000 / 37,500 (5.3%)</p>
177
+ <p style='margin-bottom:5px;'><strong>Training Time:</strong> ~50 hours continuous | <strong>Speed:</strong> ~86 sec/step</p>
178
+ <p style='margin-bottom:5px;'><strong>Loss:</strong> 1.94 | <strong>Cost:</strong> $0.00 | <strong>Quality:</strong> 24.6/100 average</p>
179
+ <p style='margin-bottom:0;'><strong>Status:</strong> Best checkpoint from early training | <strong>Full v0.1:</strong> Coming March 2026</p>
180
+ </div>
181
+ """)
182
+
183
+ # Achievement Box
184
+ gr.Markdown("""
185
+ <div id='achievement-box'>
186
+ <h3 style='margin-top:0; color:#6a1b9a;'>πŸ† Community Validation</h3>
187
+ <p style='margin-bottom:5px;'>βœ… <strong>Followed by Gradio team member</strong> - recognized for unique approach</p>
188
+ <p style='margin-bottom:5px;'>βœ… <strong>Liked by mradermacher</strong> - quantization expert validated concept</p>
189
+ <p style='margin-bottom:0;'>βœ… <strong>5+ downloads</strong> - early adopters supporting mobile ML training</p>
190
+ </div>
191
+ """)
192
+
193
+ # Main Interface
194
+ with gr.Row():
195
+ with gr.Column(scale=1):
196
+ prompt_input = gr.Textbox(
197
+ label="πŸ’» Code Prompt",
198
+ placeholder="module Main where",
199
+ lines=3,
200
+ info="Try Agda for best results!"
201
+ )
202
+
203
+ with gr.Accordion("βš™οΈ Advanced Settings", open=False):
204
+ max_length = gr.Slider(
205
+ minimum=20,
206
+ maximum=200,
207
+ value=100,
208
+ step=10,
209
+ label="Max Length",
210
+ info="Maximum tokens to generate"
211
+ )
212
+ temperature = gr.Slider(
213
+ minimum=0.1,
214
+ maximum=1.5,
215
+ value=0.7,
216
+ step=0.1,
217
+ label="Temperature",
218
+ info="Higher = more creative, lower = more conservative"
219
+ )
220
+ top_p = gr.Slider(
221
+ minimum=0.1,
222
+ maximum=1.0,
223
+ value=0.9,
224
+ step=0.05,
225
+ label="Top P",
226
+ info="Nucleus sampling parameter"
227
+ )
228
+
229
+ generate_btn = gr.Button("πŸš€ Generate Code", variant="primary", size="lg")
230
+
231
+ with gr.Column(scale=1):
232
+ output = gr.Textbox(
233
+ label="πŸ“ Generated Code",
234
+ lines=15,
235
+ show_copy_button=True
236
+ )
237
+
238
+ # Examples Section
239
+ gr.Markdown("### πŸ’‘ Try These Examples:")
240
+ gr.Examples(
241
+ examples=examples,
242
+ inputs=[prompt_input, max_length, temperature, top_p],
243
+ outputs=output,
244
+ fn=generate_code,
245
+ cache_examples=False,
246
+ label="Click any example to try it"
247
+ )
248
+
249
+ # Generate button action
250
+ generate_btn.click(
251
+ fn=generate_code,
252
+ inputs=[prompt_input, max_length, temperature, top_p],
253
+ outputs=output
254
+ )
255
+
256
+ # Footer
257
+ gr.Markdown("""
258
+ <footer>
259
+
260
+ ### 🌟 About This Project
261
+
262
+ **Yuuki proves that LLM training is accessible** even with zero budget and consumer hardware.
263
+
264
+ **Why this matters:**
265
+ - πŸŽ“ **Students** without GPU access can experiment with ML training
266
+ - 🌍 **Democratizes** ML research globally - barriers are mindset, not money
267
+ - πŸ“± **Explores** edge ML training possibilities on mobile devices
268
+ - πŸ”¬ **Documents** complete training journey including failures and recoveries
269
+
270
+ **Training Journey Highlights:**
271
+ - Step 1,292: Early peak (loss 1.70, quality 31/100)
272
+ - Step 1,600: Mode collapse (loss 2.41) πŸ’€
273
+ - Step 1,900: Recovery begins (loss 1.76)
274
+ - **Step 2,000: Current best** (loss 1.94, quality 24.6/100) ⭐
275
+ - Steps 2,100-2,500: Bad data zone (<11/100 quality)
276
+
277
+ **Key Finding:** Dataset quality matters more than loss value. Some checkpoints with excellent
278
+ loss (1.71) had terrible quality (7/100) due to corrupted training data.
279
+
280
+ ---
281
+
282
+ ### πŸ”— Links
283
+
284
+ - πŸ€— [Yuuki-best Model](https://huggingface.co/OpceanAI/Yuuki-best) - This checkpoint (recommended)
285
+ - πŸ“œ [Original Yuuki](https://huggingface.co/OpceanAI/Yuuki) - First upload (historical)
286
+ - ⏳ Yuuki v0.1 Complete - Coming March 2026 (2 full epochs)
287
+ - πŸ“„ Research Paper - Coming soon
288
+ - πŸ’» [Training Code](https://github.com/YuuKi-OS/yuuki-training)
289
+
290
+ ---
291
+
292
+ <p align="center">
293
+ <i>Built with patience, a phone, and zero budget</i><br>
294
+ <b>🌸 Proving the barrier to AI is mindset, not money</b><br><br>
295
+ Made with ❀️ | Powered by <a href="https://gradio.app">Gradio</a> & <a href="https://huggingface.co">HuggingFace</a>
296
+ </p>
297
+
298
+ </footer>
299
+ """)
300
 
301
+ # Launch
302
  if __name__ == "__main__":
303
  demo.launch()
requirements.txt ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ gradio==4.44.0
2
+ transformers==4.36.0
3
+ torch==2.1.0
4
+ accelerate==0.25.0