awacke1 commited on
Commit
dc4eb4f
Β·
verified Β·
1 Parent(s): 017755d

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +97 -98
app.py CHANGED
@@ -14,13 +14,20 @@ from dataclasses import dataclass
14
  from typing import Optional, Tuple
15
  import zipfile
16
  import math
 
 
17
 
18
- # Page Configuration
19
  st.set_page_config(
20
- page_title="SFT Model Builder πŸš€",
21
  page_icon="πŸ€–",
22
  layout="wide",
23
  initial_sidebar_state="expanded",
 
 
 
 
 
24
  )
25
 
26
  # Model Configuration Class
@@ -49,53 +56,37 @@ class SFTDataset(Dataset):
49
  prompt = self.data[idx]["prompt"]
50
  response = self.data[idx]["response"]
51
 
52
- prompt_encoding = self.tokenizer(
53
- prompt,
54
- max_length=self.max_length // 2,
55
- padding="max_length",
56
- truncation=True,
57
- return_tensors="pt"
58
- )
59
-
60
  full_text = f"{prompt} {response}"
61
- full_encoding = self.tokenizer(
62
- full_text,
63
- max_length=self.max_length,
64
- padding="max_length",
65
- truncation=True,
66
- return_tensors="pt"
67
- )
68
 
69
  input_ids = prompt_encoding["input_ids"].squeeze()
70
  attention_mask = prompt_encoding["attention_mask"].squeeze()
71
  labels = full_encoding["input_ids"].squeeze()
72
 
73
  prompt_len = prompt_encoding["input_ids"].ne(self.tokenizer.pad_token_id).sum().item()
74
- labels[:prompt_len] = -100 # Mask prompt in loss
75
 
76
- return {
77
- "input_ids": input_ids,
78
- "attention_mask": attention_mask,
79
- "labels": labels
80
- }
81
 
82
- # Model Builder Class
83
  class ModelBuilder:
84
  def __init__(self):
85
  self.config = None
86
  self.model = None
87
  self.tokenizer = None
88
  self.sft_data = None
 
89
 
90
  def load_model(self, model_path: str, config: Optional[ModelConfig] = None):
91
- with st.spinner("Loading model... ⏳"):
92
  self.model = AutoModelForCausalLM.from_pretrained(model_path)
93
  self.tokenizer = AutoTokenizer.from_pretrained(model_path)
94
  if self.tokenizer.pad_token is None:
95
  self.tokenizer.pad_token = self.tokenizer.eos_token
96
  if config:
97
  self.config = config
98
- st.success("Model loaded! βœ…")
99
  return self
100
 
101
  def fine_tune_sft(self, csv_path: str, epochs: int = 3, batch_size: int = 4):
@@ -113,7 +104,7 @@ class ModelBuilder:
113
  device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
114
  self.model.to(device)
115
  for epoch in range(epochs):
116
- with st.spinner(f"Training epoch {epoch + 1}/{epochs}... βš™οΈ"):
117
  total_loss = 0
118
  for batch in dataloader:
119
  optimizer.zero_grad()
@@ -126,35 +117,29 @@ class ModelBuilder:
126
  optimizer.step()
127
  total_loss += loss.item()
128
  st.write(f"Epoch {epoch + 1} completed. Average loss: {total_loss / len(dataloader):.4f}")
129
- st.success("SFT Fine-tuning completed! πŸŽ‰")
130
  return self
131
 
132
  def save_model(self, path: str):
133
- with st.spinner("Saving model... πŸ’Ύ"):
134
  os.makedirs(os.path.dirname(path), exist_ok=True)
135
  self.model.save_pretrained(path)
136
  self.tokenizer.save_pretrained(path)
137
- st.success(f"Model saved at {path}! βœ…")
138
 
139
  def evaluate(self, prompt: str):
140
  self.model.eval()
141
  with torch.no_grad():
142
  inputs = self.tokenizer(prompt, return_tensors="pt", max_length=128, truncation=True).to(self.model.device)
143
- outputs = self.model.generate(
144
- **inputs,
145
- max_new_tokens=50,
146
- do_sample=True,
147
- top_p=0.95,
148
- temperature=0.7
149
- )
150
  return self.tokenizer.decode(outputs[0], skip_special_tokens=True)
151
 
152
- # Utility Functions
153
  def get_download_link(file_path, mime_type="text/plain", label="Download"):
154
  with open(file_path, 'rb') as f:
155
  data = f.read()
156
  b64 = base64.b64encode(data).decode()
157
- return f'<a href="data:{mime_type};base64,{b64}" download="{os.path.basename(file_path)}">{label} πŸ“₯</a>'
158
 
159
  def zip_directory(directory_path, zip_path):
160
  with zipfile.ZipFile(zip_path, 'w', zipfile.ZIP_DEFLATED) as zipf:
@@ -167,12 +152,14 @@ def zip_directory(directory_path, zip_path):
167
  def get_model_files():
168
  return [d for d in glob.glob("models/*") if os.path.isdir(d)]
169
 
 
 
 
 
 
 
170
  # Cargo Travel Time Tool
171
- def calculate_cargo_travel_time(
172
- origin_coords: Tuple[float, float],
173
- destination_coords: Tuple[float, float],
174
- cruising_speed_kmh: float = 750.0
175
- ) -> float:
176
  def to_radians(degrees: float) -> float:
177
  return degrees * (math.pi / 180)
178
  lat1, lon1 = map(to_radians, origin_coords)
@@ -188,13 +175,28 @@ def calculate_cargo_travel_time(
188
  return round(flight_time, 2)
189
 
190
  # Main App
191
- st.title("SFT Model Builder πŸ€–πŸš€")
192
-
193
- # Sidebar for Model Management
194
- st.sidebar.header("Model Management πŸ—‚οΈ")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
195
  model_dirs = get_model_files()
196
  selected_model = st.sidebar.selectbox("Select Saved Model", ["None"] + model_dirs)
197
-
198
  if selected_model != "None" and st.sidebar.button("Load Model πŸ“‚"):
199
  if 'builder' not in st.session_state:
200
  st.session_state['builder'] = ModelBuilder()
@@ -204,21 +206,16 @@ if selected_model != "None" and st.sidebar.button("Load Model πŸ“‚"):
204
  st.rerun()
205
 
206
  # Main UI with Tabs
207
- tab1, tab2, tab3, tab4 = st.tabs(["Build New Model 🌱", "Fine-Tune Model πŸ”§", "Test Model πŸ§ͺ", "Agentic RAG Demo 🌐"])
208
 
209
  with tab1:
210
- st.header("Build New Model 🌱")
211
  base_model = st.selectbox(
212
- "Select Base Model",
213
- [
214
- "HuggingFaceTB/SmolLM-135M", # ~270 MB
215
- "HuggingFaceTB/SmolLM-360M", # ~720 MB
216
- "Qwen/Qwen1.5-0.5B-Chat", # ~1 GB
217
- "TinyLlama/TinyLlama-1.1B-Chat-v1.0" # ~2 GB, slightly over but included
218
- ],
219
- help="Choose a tiny, open-source model (<1 GB except TinyLlama)"
220
  )
221
- model_name = st.text_input("Model Name", f"new-model-{int(time.time())}")
222
  domain = st.text_input("Target Domain", "general")
223
 
224
  if st.button("Download Model ⬇️"):
@@ -228,19 +225,19 @@ with tab1:
228
  builder.save_model(config.model_path)
229
  st.session_state['builder'] = builder
230
  st.session_state['model_loaded'] = True
231
- st.success(f"Model downloaded and saved to {config.model_path}! πŸŽ‰")
232
  st.rerun()
233
 
234
  with tab2:
235
- st.header("Fine-Tune Model πŸ”§")
236
  if 'builder' not in st.session_state or not st.session_state.get('model_loaded', False):
237
- st.warning("Please download or load a model first! ⚠️")
238
  else:
239
  if st.button("Generate Sample CSV πŸ“"):
240
  sample_data = [
241
- {"prompt": "What is AI?", "response": "AI is artificial intelligence, simulating human intelligence in machines."},
242
- {"prompt": "Explain machine learning", "response": "Machine learning is a subset of AI where models learn from data."},
243
- {"prompt": "What is a neural network?", "response": "A neural network is a model inspired by the human brain."},
244
  ]
245
  csv_path = f"sft_data_{int(time.time())}.csv"
246
  with open(csv_path, "w", newline="") as f:
@@ -248,7 +245,7 @@ with tab2:
248
  writer.writeheader()
249
  writer.writerows(sample_data)
250
  st.markdown(get_download_link(csv_path, "text/csv", "Download Sample CSV"), unsafe_allow_html=True)
251
- st.success(f"Sample CSV generated as {csv_path}! βœ…")
252
 
253
  uploaded_csv = st.file_uploader("Upload CSV for SFT", type="csv")
254
  if uploaded_csv and st.button("Fine-Tune with Uploaded CSV πŸ”„"):
@@ -263,20 +260,20 @@ with tab2:
263
  domain=st.session_state['builder'].config.domain
264
  )
265
  st.session_state['builder'].config = new_config
266
- with st.status("Fine-tuning model... ⏳", expanded=True) as status:
267
  st.session_state['builder'].fine_tune_sft(csv_path)
268
  st.session_state['builder'].save_model(new_config.model_path)
269
- status.update(label="Fine-tuning completed! πŸŽ‰", state="complete")
270
 
271
  zip_path = f"{new_config.model_path}.zip"
272
  zip_directory(new_config.model_path, zip_path)
273
- st.markdown(get_download_link(zip_path, "application/zip", "Download Fine-Tuned Model"), unsafe_allow_html=True)
274
  st.rerun()
275
 
276
  with tab3:
277
- st.header("Test Model πŸ§ͺ")
278
  if 'builder' not in st.session_state or not st.session_state.get('model_loaded', False):
279
- st.warning("Please download or load a model first! ⚠️")
280
  else:
281
  if st.session_state['builder'].sft_data:
282
  st.write("Testing with SFT Data:")
@@ -286,15 +283,15 @@ with tab3:
286
  generated = st.session_state['builder'].evaluate(prompt)
287
  st.write(f"**Prompt**: {prompt}")
288
  st.write(f"**Expected**: {expected}")
289
- st.write(f"**Generated**: {generated}")
290
  st.write("---")
291
 
292
  test_prompt = st.text_area("Enter Test Prompt", "What is AI?")
293
  if st.button("Run Test ▢️"):
294
  result = st.session_state['builder'].evaluate(test_prompt)
295
- st.write(f"**Generated Response**: {result}")
296
 
297
- if st.button("Export Model Files πŸ“¦"):
298
  config = st.session_state['builder'].config
299
  app_code = f"""
300
  import streamlit as st
@@ -303,47 +300,47 @@ from transformers import AutoModelForCausalLM, AutoTokenizer
303
  model = AutoModelForCausalLM.from_pretrained("{config.model_path}")
304
  tokenizer = AutoTokenizer.from_pretrained("{config.model_path}")
305
 
306
- st.title("SFT Model Demo")
307
  input_text = st.text_area("Enter prompt")
308
  if st.button("Generate"):
309
  inputs = tokenizer(input_text, return_tensors="pt")
310
  outputs = model.generate(**inputs, max_new_tokens=50, do_sample=True, top_p=0.95, temperature=0.7)
311
  st.write(tokenizer.decode(outputs[0], skip_special_tokens=True))
312
  """
313
- with open("sft_app.py", "w") as f:
314
  f.write(app_code)
315
  reqs = "streamlit\ntorch\ntransformers\n"
316
- with open("sft_requirements.txt", "w") as f:
317
  f.write(reqs)
318
  readme = f"""
319
- # SFT Model Demo
320
 
321
  ## How to run
322
- 1. Install requirements: `pip install -r sft_requirements.txt`
323
- 2. Run the app: `streamlit run sft_app.py`
324
- 3. Input a prompt and click "Generate".
325
  """
326
- with open("sft_README.md", "w") as f:
327
  f.write(readme)
328
 
329
- st.markdown(get_download_link("sft_app.py", "text/plain", "Download App"), unsafe_allow_html=True)
330
- st.markdown(get_download_link("sft_requirements.txt", "text/plain", "Download Requirements"), unsafe_allow_html=True)
331
- st.markdown(get_download_link("sft_README.md", "text/markdown", "Download README"), unsafe_allow_html=True)
332
- st.success("Model files exported! βœ…")
333
 
334
  with tab4:
335
- st.header("Agentic RAG Demo 🌐")
336
- st.write("This demo uses tiny models with Agentic RAG to plan a luxury superhero-themed party, enhancing retrieval with DuckDuckGo.")
337
 
338
  if st.button("Run Agentic RAG Demo πŸŽ‰"):
339
  try:
340
  from smolagents import CodeAgent, DuckDuckGoSearchTool, VisitWebpageTool
341
 
342
- # Load selected tiny model
343
  tokenizer = AutoTokenizer.from_pretrained("HuggingFaceTB/SmolLM-135M")
344
  model = AutoModelForCausalLM.from_pretrained("HuggingFaceTB/SmolLM-135M")
345
 
346
- # Define Agentic RAG agent
347
  agent = CodeAgent(
348
  model=model,
349
  tokenizer=tokenizer,
@@ -355,16 +352,18 @@ with tab4:
355
  )
356
 
357
  task = """
358
- Plan a luxury superhero-themed party at Wayne Manor (42.3601Β° N, 71.0589Β° W). Search for the latest superhero party trends using DuckDuckGo,
359
- refine results to include luxury elements (decorations, entertainment, catering), and calculate cargo travel times from key locations
360
- (e.g., New York, LA, London) to Wayne Manor. Synthesize a complete plan and return it as a pandas dataframe with at least 6 entries
361
- including locations, travel times, and luxury party ideas.
 
362
  """
363
- with st.spinner("Running Agentic RAG system... ⏳"):
364
  result = agent.run(task)
365
- st.write("Agentic RAG Result:")
366
  st.write(result)
 
367
  except ImportError:
368
  st.error("Please install required packages: `pip install smolagents pandas`")
369
  except Exception as e:
370
- st.error(f"Error running demo: {str(e)}")
 
14
  from typing import Optional, Tuple
15
  import zipfile
16
  import math
17
+ from PIL import Image
18
+ import random
19
 
20
+ # Page Configuration with a Dash of Humor
21
  st.set_page_config(
22
+ page_title="SFT Tiny Titans πŸš€",
23
  page_icon="πŸ€–",
24
  layout="wide",
25
  initial_sidebar_state="expanded",
26
+ menu_items={
27
+ 'Get Help': 'https://huggingface.co/awacke1',
28
+ 'Report a bug': 'https://huggingface.co/spaces/awacke1',
29
+ 'About': "Tiny Titans: Small models, big dreams, and a sprinkle of chaos! 🌌"
30
+ }
31
  )
32
 
33
  # Model Configuration Class
 
56
  prompt = self.data[idx]["prompt"]
57
  response = self.data[idx]["response"]
58
 
59
+ prompt_encoding = self.tokenizer(prompt, max_length=self.max_length // 2, padding="max_length", truncation=True, return_tensors="pt")
 
 
 
 
 
 
 
60
  full_text = f"{prompt} {response}"
61
+ full_encoding = self.tokenizer(full_text, max_length=self.max_length, padding="max_length", truncation=True, return_tensors="pt")
 
 
 
 
 
 
62
 
63
  input_ids = prompt_encoding["input_ids"].squeeze()
64
  attention_mask = prompt_encoding["attention_mask"].squeeze()
65
  labels = full_encoding["input_ids"].squeeze()
66
 
67
  prompt_len = prompt_encoding["input_ids"].ne(self.tokenizer.pad_token_id).sum().item()
68
+ labels[:prompt_len] = -100
69
 
70
+ return {"input_ids": input_ids, "attention_mask": attention_mask, "labels": labels}
 
 
 
 
71
 
72
+ # Model Builder Class with Easter Egg Jokes
73
  class ModelBuilder:
74
  def __init__(self):
75
  self.config = None
76
  self.model = None
77
  self.tokenizer = None
78
  self.sft_data = None
79
+ self.jokes = ["Why did the AI go to therapy? Too many layers to unpack! πŸ˜‚", "Training complete! Time for a binary coffee break. β˜•"]
80
 
81
  def load_model(self, model_path: str, config: Optional[ModelConfig] = None):
82
+ with st.spinner(f"Loading {model_path}... ⏳ (Patience, young padawan!)"):
83
  self.model = AutoModelForCausalLM.from_pretrained(model_path)
84
  self.tokenizer = AutoTokenizer.from_pretrained(model_path)
85
  if self.tokenizer.pad_token is None:
86
  self.tokenizer.pad_token = self.tokenizer.eos_token
87
  if config:
88
  self.config = config
89
+ st.success(f"Model loaded! πŸŽ‰ {random.choice(self.jokes)}")
90
  return self
91
 
92
  def fine_tune_sft(self, csv_path: str, epochs: int = 3, batch_size: int = 4):
 
104
  device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
105
  self.model.to(device)
106
  for epoch in range(epochs):
107
+ with st.spinner(f"Training epoch {epoch + 1}/{epochs}... βš™οΈ (The AI is lifting weights!)"):
108
  total_loss = 0
109
  for batch in dataloader:
110
  optimizer.zero_grad()
 
117
  optimizer.step()
118
  total_loss += loss.item()
119
  st.write(f"Epoch {epoch + 1} completed. Average loss: {total_loss / len(dataloader):.4f}")
120
+ st.success(f"SFT Fine-tuning completed! πŸŽ‰ {random.choice(self.jokes)}")
121
  return self
122
 
123
  def save_model(self, path: str):
124
+ with st.spinner("Saving model... πŸ’Ύ (Packing the AI’s suitcase!)"):
125
  os.makedirs(os.path.dirname(path), exist_ok=True)
126
  self.model.save_pretrained(path)
127
  self.tokenizer.save_pretrained(path)
128
+ st.success(f"Model saved at {path}! βœ… May the force be with it.")
129
 
130
  def evaluate(self, prompt: str):
131
  self.model.eval()
132
  with torch.no_grad():
133
  inputs = self.tokenizer(prompt, return_tensors="pt", max_length=128, truncation=True).to(self.model.device)
134
+ outputs = self.model.generate(**inputs, max_new_tokens=50, do_sample=True, top_p=0.95, temperature=0.7)
 
 
 
 
 
 
135
  return self.tokenizer.decode(outputs[0], skip_special_tokens=True)
136
 
137
+ # Utility Functions with Wit
138
  def get_download_link(file_path, mime_type="text/plain", label="Download"):
139
  with open(file_path, 'rb') as f:
140
  data = f.read()
141
  b64 = base64.b64encode(data).decode()
142
+ return f'<a href="data:{mime_type};base64,{b64}" download="{os.path.basename(file_path)}">{label} πŸ“₯ (Grab it before it runs away!)</a>'
143
 
144
  def zip_directory(directory_path, zip_path):
145
  with zipfile.ZipFile(zip_path, 'w', zipfile.ZIP_DEFLATED) as zipf:
 
152
  def get_model_files():
153
  return [d for d in glob.glob("models/*") if os.path.isdir(d)]
154
 
155
+ def get_gallery_files(file_types):
156
+ files = []
157
+ for ext in file_types:
158
+ files.extend(glob.glob(f"*.{ext}"))
159
+ return sorted(files)
160
+
161
  # Cargo Travel Time Tool
162
+ def calculate_cargo_travel_time(origin_coords: Tuple[float, float], destination_coords: Tuple[float, float], cruising_speed_kmh: float = 750.0) -> float:
 
 
 
 
163
  def to_radians(degrees: float) -> float:
164
  return degrees * (math.pi / 180)
165
  lat1, lon1 = map(to_radians, origin_coords)
 
175
  return round(flight_time, 2)
176
 
177
  # Main App
178
+ st.title("SFT Tiny Titans πŸš€ (Small but Mighty!)")
179
+
180
+ # Sidebar with Galleries
181
+ st.sidebar.header("Galleries & Shenanigans 🎨")
182
+ st.sidebar.subheader("Image Gallery πŸ“Έ")
183
+ img_files = get_gallery_files(["png", "jpg", "jpeg"])
184
+ if img_files:
185
+ img_cols = st.sidebar.slider("Image Columns πŸ“Έ", 1, 5, 3)
186
+ cols = st.sidebar.columns(img_cols)
187
+ for idx, img_file in enumerate(img_files[:img_cols * 2]): # Limit to 2 rows
188
+ with cols[idx % img_cols]:
189
+ st.image(Image.open(img_file), caption=f"{img_file} πŸ–Ό", use_column_width=True)
190
+
191
+ st.sidebar.subheader("CSV Gallery πŸ“Š")
192
+ csv_files = get_gallery_files(["csv"])
193
+ if csv_files:
194
+ for csv_file in csv_files[:5]: # Limit to 5
195
+ st.sidebar.markdown(get_download_link(csv_file, "text/csv", f"{csv_file} πŸ“Š"), unsafe_allow_html=True)
196
+
197
+ st.sidebar.subheader("Model Management πŸ—‚οΈ")
198
  model_dirs = get_model_files()
199
  selected_model = st.sidebar.selectbox("Select Saved Model", ["None"] + model_dirs)
 
200
  if selected_model != "None" and st.sidebar.button("Load Model πŸ“‚"):
201
  if 'builder' not in st.session_state:
202
  st.session_state['builder'] = ModelBuilder()
 
206
  st.rerun()
207
 
208
  # Main UI with Tabs
209
+ tab1, tab2, tab3, tab4 = st.tabs(["Build Tiny Titan 🌱", "Fine-Tune Titan πŸ”§", "Test Titan πŸ§ͺ", "Agentic RAG Party 🌐"])
210
 
211
  with tab1:
212
+ st.header("Build Tiny Titan 🌱 (Assemble Your Mini-Mecha!)")
213
  base_model = st.selectbox(
214
+ "Select Tiny Model",
215
+ ["HuggingFaceTB/SmolLM-135M", "HuggingFaceTB/SmolLM-360M", "Qwen/Qwen1.5-0.5B-Chat"],
216
+ help="Pick a pint-sized powerhouse (<1 GB)! SmolLM-135M (~270 MB), SmolLM-360M (~720 MB), Qwen1.5-0.5B (~1 GB)"
 
 
 
 
 
217
  )
218
+ model_name = st.text_input("Model Name", f"tiny-titan-{int(time.time())}")
219
  domain = st.text_input("Target Domain", "general")
220
 
221
  if st.button("Download Model ⬇️"):
 
225
  builder.save_model(config.model_path)
226
  st.session_state['builder'] = builder
227
  st.session_state['model_loaded'] = True
228
+ st.success(f"Model downloaded and saved to {config.model_path}! πŸŽ‰ (Tiny but feisty!)")
229
  st.rerun()
230
 
231
  with tab2:
232
+ st.header("Fine-Tune Titan πŸ”§ (Teach Your Titan Some Tricks!)")
233
  if 'builder' not in st.session_state or not st.session_state.get('model_loaded', False):
234
+ st.warning("Please build or load a Titan first! ⚠️ (No Titan, no party!)")
235
  else:
236
  if st.button("Generate Sample CSV πŸ“"):
237
  sample_data = [
238
+ {"prompt": "What is AI?", "response": "AI is artificial intelligence, simulating human smarts in machines."},
239
+ {"prompt": "Explain machine learning", "response": "Machine learning is AI’s gym where models bulk up on data."},
240
+ {"prompt": "What is a neural network?", "response": "A neural network is a brainy AI mimicking human noggins."},
241
  ]
242
  csv_path = f"sft_data_{int(time.time())}.csv"
243
  with open(csv_path, "w", newline="") as f:
 
245
  writer.writeheader()
246
  writer.writerows(sample_data)
247
  st.markdown(get_download_link(csv_path, "text/csv", "Download Sample CSV"), unsafe_allow_html=True)
248
+ st.success(f"Sample CSV generated as {csv_path}! βœ… (Fresh from the data oven!)")
249
 
250
  uploaded_csv = st.file_uploader("Upload CSV for SFT", type="csv")
251
  if uploaded_csv and st.button("Fine-Tune with Uploaded CSV πŸ”„"):
 
260
  domain=st.session_state['builder'].config.domain
261
  )
262
  st.session_state['builder'].config = new_config
263
+ with st.status("Fine-tuning Titan... ⏳ (Whipping it into shape!)", expanded=True) as status:
264
  st.session_state['builder'].fine_tune_sft(csv_path)
265
  st.session_state['builder'].save_model(new_config.model_path)
266
+ status.update(label="Fine-tuning completed! πŸŽ‰ (Titan’s ready to rumble!)", state="complete")
267
 
268
  zip_path = f"{new_config.model_path}.zip"
269
  zip_directory(new_config.model_path, zip_path)
270
+ st.markdown(get_download_link(zip_path, "application/zip", "Download Fine-Tuned Titan"), unsafe_allow_html=True)
271
  st.rerun()
272
 
273
  with tab3:
274
+ st.header("Test Titan πŸ§ͺ (Put Your Titan to the Test!)")
275
  if 'builder' not in st.session_state or not st.session_state.get('model_loaded', False):
276
+ st.warning("Please build or load a Titan first! ⚠️ (No Titan, no test drive!)")
277
  else:
278
  if st.session_state['builder'].sft_data:
279
  st.write("Testing with SFT Data:")
 
283
  generated = st.session_state['builder'].evaluate(prompt)
284
  st.write(f"**Prompt**: {prompt}")
285
  st.write(f"**Expected**: {expected}")
286
+ st.write(f"**Generated**: {generated} (Titan says: '{random.choice(['Bleep bloop!', 'I am groot!', '42!'])}')")
287
  st.write("---")
288
 
289
  test_prompt = st.text_area("Enter Test Prompt", "What is AI?")
290
  if st.button("Run Test ▢️"):
291
  result = st.session_state['builder'].evaluate(test_prompt)
292
+ st.write(f"**Generated Response**: {result} (Titan’s wisdom unleashed!)")
293
 
294
+ if st.button("Export Titan Files πŸ“¦"):
295
  config = st.session_state['builder'].config
296
  app_code = f"""
297
  import streamlit as st
 
300
  model = AutoModelForCausalLM.from_pretrained("{config.model_path}")
301
  tokenizer = AutoTokenizer.from_pretrained("{config.model_path}")
302
 
303
+ st.title("Tiny Titan Demo")
304
  input_text = st.text_area("Enter prompt")
305
  if st.button("Generate"):
306
  inputs = tokenizer(input_text, return_tensors="pt")
307
  outputs = model.generate(**inputs, max_new_tokens=50, do_sample=True, top_p=0.95, temperature=0.7)
308
  st.write(tokenizer.decode(outputs[0], skip_special_tokens=True))
309
  """
310
+ with open("titan_app.py", "w") as f:
311
  f.write(app_code)
312
  reqs = "streamlit\ntorch\ntransformers\n"
313
+ with open("titan_requirements.txt", "w") as f:
314
  f.write(reqs)
315
  readme = f"""
316
+ # Tiny Titan Demo
317
 
318
  ## How to run
319
+ 1. Install requirements: `pip install -r titan_requirements.txt`
320
+ 2. Run the app: `streamlit run titan_app.py`
321
+ 3. Input a prompt and click "Generate". Watch the magic unfold! πŸͺ„
322
  """
323
+ with open("titan_README.md", "w") as f:
324
  f.write(readme)
325
 
326
+ st.markdown(get_download_link("titan_app.py", "text/plain", "Download App"), unsafe_allow_html=True)
327
+ st.markdown(get_download_link("titan_requirements.txt", "text/plain", "Download Requirements"), unsafe_allow_html=True)
328
+ st.markdown(get_download_link("titan_README.md", "text/markdown", "Download README"), unsafe_allow_html=True)
329
+ st.success("Titan files exported! βœ… (Ready to conquer the galaxy!)")
330
 
331
  with tab4:
332
+ st.header("Agentic RAG Party 🌐 (Party Like It’s 2099!)")
333
+ st.write("This demo uses tiny Titans with Agentic RAG to plan a superhero party, powered by DuckDuckGo retrieval!")
334
 
335
  if st.button("Run Agentic RAG Demo πŸŽ‰"):
336
  try:
337
  from smolagents import CodeAgent, DuckDuckGoSearchTool, VisitWebpageTool
338
 
339
+ # Load a tiny model (default to SmolLM-135M for speed)
340
  tokenizer = AutoTokenizer.from_pretrained("HuggingFaceTB/SmolLM-135M")
341
  model = AutoModelForCausalLM.from_pretrained("HuggingFaceTB/SmolLM-135M")
342
 
343
+ # Define Agentic RAG agent with a witty twist
344
  agent = CodeAgent(
345
  model=model,
346
  tokenizer=tokenizer,
 
352
  )
353
 
354
  task = """
355
+ Plan a luxury superhero-themed party at Wayne Manor (42.3601Β° N, 71.0589Β° W). Use DuckDuckGo to search for the latest superhero party trends,
356
+ refine results for luxury elements (decorations, entertainment, catering), and calculate cargo travel times from key locations
357
+ (New York: 40.7128Β° N, 74.0060Β° W; LA: 34.0522Β° N, 118.2437Β° W; London: 51.5074Β° N, 0.1278Β° W) to Wayne Manor.
358
+ Synthesize a plan with at least 6 entries in a pandas dataframe, including locations, travel times, and luxury ideas.
359
+ Add a random superhero catchphrase to each entry for fun!
360
  """
361
+ with st.spinner("Planning the ultimate superhero bash... ⏳ (Calling all caped crusaders!)"):
362
  result = agent.run(task)
363
+ st.write("Agentic RAG Party Plan:")
364
  st.write(result)
365
+ st.write("Party on, Wayne! πŸ¦Έβ€β™‚οΈπŸŽ‰")
366
  except ImportError:
367
  st.error("Please install required packages: `pip install smolagents pandas`")
368
  except Exception as e:
369
+ st.error(f"Error running demo: {str(e)} (Even Batman has off days!)")