qwerty45-uiop commited on
Commit
5cc3290
·
verified ·
1 Parent(s): e2fb4ba

Update src/streamlit_app.py

Browse files
Files changed (1) hide show
  1. src/streamlit_app.py +109 -391
src/streamlit_app.py CHANGED
@@ -1,27 +1,24 @@
1
  #!/usr/bin/env python3
2
  """
3
- LLM Compatibility Advisor - Streamlined with Download Sizes
4
  Author: Assistant
5
- Description: Provides device-based LLM recommendations with popular models and download sizes
6
  Requirements: streamlit, pandas, plotly, openpyxl
7
  """
8
 
9
  import streamlit as st
10
  import pandas as pd
11
  import re
12
- import plotly.express as px
13
  import plotly.graph_objects as go
14
- from typing import Optional, Tuple, List, Dict
15
 
16
- # MUST be the first Streamlit command
17
  st.set_page_config(
18
  page_title="LLM Compatibility Advisor",
19
  layout="wide",
20
- page_icon="🧠",
21
- initial_sidebar_state="expanded"
22
  )
23
 
24
- # Enhanced data loading with error handling
25
  @st.cache_data
26
  def load_data():
27
  try:
@@ -33,14 +30,13 @@ def load_data():
33
  except Exception as e:
34
  return None, f"Error loading data: {str(e)}"
35
 
36
- # Enhanced RAM extraction with better parsing
37
  def extract_numeric_ram(ram) -> Optional[int]:
38
  if pd.isna(ram):
39
  return None
40
 
41
  ram_str = str(ram).lower().replace(" ", "")
42
 
43
- # Handle various formats: "8GB", "8 GB", "8gb", "8192MB", etc.
44
  gb_match = re.search(r"(\d+(?:\.\d+)?)(?:gb|g)", ram_str)
45
  if gb_match:
46
  return int(float(gb_match.group(1)))
@@ -48,274 +44,158 @@ def extract_numeric_ram(ram) -> Optional[int]:
48
  # Handle MB format
49
  mb_match = re.search(r"(\d+)(?:mb|m)", ram_str)
50
  if mb_match:
51
- return max(1, int(int(mb_match.group(1)) / 1024)) # Convert MB to GB
52
 
53
- # Handle plain numbers (assume GB)
54
  plain_match = re.search(r"(\d+)", ram_str)
55
  if plain_match:
56
  return int(plain_match.group(1))
57
 
58
  return None
59
 
60
- # Streamlined LLM database with popular models and download sizes
61
  LLM_DATABASE = {
62
  "ultra_low": { # ≤2GB
63
  "general": [
64
  {"name": "TinyLlama-1.1B-Chat", "size": "637MB", "description": "Compact chat model"},
65
- {"name": "DistilBERT-base", "size": "268MB", "description": "Efficient BERT variant"},
66
  {"name": "all-MiniLM-L6-v2", "size": "91MB", "description": "Sentence embeddings"}
67
  ],
68
  "code": [
69
- {"name": "CodeT5-small", "size": "242MB", "description": "Code generation"},
70
- {"name": "Replit-code-v1-3B", "size": "1.2GB", "description": "Code completion"}
71
  ]
72
  },
73
  "low": { # 3-4GB
74
  "general": [
75
  {"name": "Phi-1.5", "size": "2.8GB", "description": "Microsoft's efficient model"},
76
- {"name": "Gemma-2B", "size": "1.4GB", "description": "Google's compact model"},
77
- {"name": "OpenLLaMA-3B", "size": "2.1GB", "description": "Open source LLaMA"}
78
  ],
79
  "code": [
80
- {"name": "CodeGen-2B", "size": "1.8GB", "description": "Salesforce code model"},
81
- {"name": "StarCoder-1B", "size": "1.1GB", "description": "BigCode project"}
82
- ],
83
- "chat": [
84
- {"name": "Alpaca-3B", "size": "2.0GB", "description": "Stanford's instruction model"},
85
- {"name": "Vicuna-3B", "size": "2.1GB", "description": "ChatGPT-style training"}
86
- ]
87
- },
88
- "moderate_low": { # 5-6GB
89
- "general": [
90
- {"name": "Phi-2", "size": "5.2GB", "description": "Microsoft's 2.7B model"},
91
- {"name": "Gemma-7B-it", "size": "4.2GB", "description": "Google instruction tuned"},
92
- {"name": "Mistral-7B-v0.1", "size": "4.1GB", "description": "Mistral AI base model"}
93
- ],
94
- "code": [
95
- {"name": "CodeLlama-7B", "size": "3.8GB", "description": "Meta's code specialist"},
96
- {"name": "StarCoder-7B", "size": "4.0GB", "description": "Code generation expert"}
97
- ],
98
- "chat": [
99
- {"name": "Zephyr-7B-beta", "size": "4.2GB", "description": "HuggingFace chat model"},
100
- {"name": "Neural-Chat-7B", "size": "4.1GB", "description": "Intel optimized"}
101
  ]
102
  },
103
- "moderate": { # 7-8GB
104
  "general": [
105
  {"name": "Llama-2-7B-Chat", "size": "3.5GB", "description": "Meta's popular chat model"},
106
- {"name": "Mistral-7B-Instruct-v0.2", "size": "4.1GB", "description": "Latest Mistral instruct"},
107
- {"name": "Qwen-7B-Chat", "size": "4.0GB", "description": "Alibaba's multilingual"}
108
  ],
109
  "code": [
110
- {"name": "CodeLlama-7B-Instruct", "size": "3.8GB", "description": "Instruction-tuned CodeLlama"},
111
- {"name": "WizardCoder-7B", "size": "4.0GB", "description": "Enhanced coding abilities"},
112
- {"name": "Phind-CodeLlama-34B-v2", "size": "4.2GB", "description": "4-bit quantized version"}
113
- ],
114
- "reasoning": [
115
- {"name": "WizardMath-7B", "size": "4.0GB", "description": "Mathematical reasoning"},
116
- {"name": "MetaMath-7B", "size": "3.9GB", "description": "Math problem solving"}
117
  ]
118
  },
119
  "good": { # 9-16GB
120
  "general": [
121
  {"name": "Llama-2-13B-Chat", "size": "7.3GB", "description": "Larger Llama variant"},
122
- {"name": "Vicuna-13B-v1.5", "size": "7.2GB", "description": "Enhanced Vicuna"},
123
  {"name": "OpenChat-3.5", "size": "7.1GB", "description": "High-quality chat model"}
124
  ],
125
  "code": [
126
- {"name": "CodeLlama-13B-Instruct", "size": "7.3GB", "description": "Larger code model"},
127
- {"name": "WizardCoder-15B", "size": "8.2GB", "description": "Advanced coding"},
128
- {"name": "StarCoder-15B", "size": "8.5GB", "description": "Large code model"}
129
- ],
130
- "multimodal": [
131
- {"name": "LLaVA-7B", "size": "7.0GB", "description": "Vision + language"},
132
- {"name": "MiniGPT-4-7B", "size": "6.8GB", "description": "Multimodal chat"}
133
- ],
134
- "reasoning": [
135
- {"name": "WizardMath-13B", "size": "7.3GB", "description": "Advanced math"},
136
- {"name": "Orca-2-13B", "size": "7.4GB", "description": "Microsoft reasoning"}
137
  ]
138
  },
139
  "high": { # 17-32GB
140
  "general": [
141
  {"name": "Mixtral-8x7B-Instruct-v0.1", "size": "26.9GB", "description": "Mixture of experts"},
142
- {"name": "Llama-2-70B-Chat", "size": "38.0GB", "description": "8-bit quantized"},
143
  {"name": "Yi-34B-Chat", "size": "19.5GB", "description": "01.AI's large model"}
144
  ],
145
  "code": [
146
- {"name": "CodeLlama-34B-Instruct", "size": "19.0GB", "description": "Large code specialist"},
147
- {"name": "DeepSeek-Coder-33B", "size": "18.5GB", "description": "DeepSeek's coder"},
148
- {"name": "WizardCoder-34B", "size": "19.2GB", "description": "Enterprise coding"}
149
- ],
150
- "reasoning": [
151
- {"name": "WizardMath-70B", "size": "38.5GB", "description": "8-bit quantized math"},
152
- {"name": "MetaMath-70B", "size": "38.0GB", "description": "8-bit math reasoning"}
153
  ]
154
  },
155
  "ultra_high": { # >32GB
156
  "general": [
157
  {"name": "Llama-2-70B", "size": "130GB", "description": "Full precision"},
158
- {"name": "Mixtral-8x22B", "size": "176GB", "description": "Latest mixture model"},
159
- {"name": "Qwen-72B", "size": "145GB", "description": "Alibaba's flagship"}
160
- ],
161
- "code": [
162
- {"name": "CodeLlama-34B", "size": "68GB", "description": "Full precision code"},
163
- {"name": "DeepSeek-Coder-33B", "size": "66GB", "description": "Full precision coding"}
164
- ],
165
- "reasoning": [
166
- {"name": "WizardMath-70B", "size": "130GB", "description": "Full precision math"},
167
- {"name": "Goat-70B", "size": "132GB", "description": "Arithmetic reasoning"}
168
  ]
169
  }
170
  }
171
 
172
- # Enhanced LLM recommendation with performance tiers
173
- def recommend_llm(ram_str) -> Tuple[str, str, str, Dict[str, List[Dict]]]:
174
- """Returns (recommendation, performance_tier, additional_info, detailed_models)"""
175
  ram = extract_numeric_ram(ram_str)
176
 
177
  if ram is None:
178
- return ("⚪ Check exact specs or test with quantized models.",
179
- "Unknown",
180
- "Verify RAM specifications",
181
- {})
182
 
183
  if ram <= 2:
184
- models = LLM_DATABASE["ultra_low"]
185
- return ("🔸 Ultra-lightweight models - basic NLP tasks",
186
- "Ultra Low",
187
- "Mobile-optimized, simple tasks, limited context",
188
- models)
189
  elif ram <= 4:
190
- models = LLM_DATABASE["low"]
191
- return ("🔸 Small language models - decent capabilities",
192
- "Low",
193
- "Basic chat, simple reasoning, text classification",
194
- models)
195
- elif ram <= 6:
196
- models = LLM_DATABASE["moderate_low"]
197
- return ("🟠 Mid-range models - good general performance",
198
- "Moderate-Low",
199
- "Solid reasoning, coding help, longer conversations",
200
- models)
201
  elif ram <= 8:
202
- models = LLM_DATABASE["moderate"]
203
- return ("🟠 Strong 7B models - excellent capabilities",
204
- "Moderate",
205
- "Professional use, coding assistance, complex reasoning",
206
- models)
207
  elif ram <= 16:
208
- models = LLM_DATABASE["good"]
209
- return ("🟢 High-quality models - premium performance",
210
- "Good",
211
- "Advanced tasks, multimodal support, research use",
212
- models)
213
  elif ram <= 32:
214
- models = LLM_DATABASE["high"]
215
- return ("🔵 Premium models - professional grade",
216
- "High",
217
- "Enterprise ready, complex reasoning, specialized tasks",
218
- models)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
219
  else:
220
- models = LLM_DATABASE["ultra_high"]
221
- return ("🔵 Top-tier models - enterprise capabilities",
222
- "Ultra High",
223
- "Research grade, maximum performance, domain expertise",
224
- models)
225
 
226
- # Performance visualization
227
  def create_performance_chart(df):
228
- """Create a performance distribution chart"""
229
  laptop_rams = df["Laptop RAM"].apply(extract_numeric_ram).dropna()
230
  mobile_rams = df["Mobile RAM"].apply(extract_numeric_ram).dropna()
231
 
232
  fig = go.Figure()
233
-
234
- fig.add_trace(go.Histogram(
235
- x=laptop_rams,
236
- name="Laptop RAM",
237
- opacity=0.7,
238
- nbinsx=10
239
- ))
240
-
241
- fig.add_trace(go.Histogram(
242
- x=mobile_rams,
243
- name="Mobile RAM",
244
- opacity=0.7,
245
- nbinsx=10
246
- ))
247
 
248
  fig.update_layout(
249
- title="RAM Distribution Across Devices",
250
  xaxis_title="RAM (GB)",
251
- yaxis_title="Number of Students",
252
  barmode='overlay',
253
  height=400
254
  )
255
-
256
  return fig
257
 
258
- # Enhanced model details display function
259
- def display_model_categories(models_dict: Dict[str, List[Dict]], ram_gb: int):
260
- """Display models organized by category with download sizes"""
261
  if not models_dict:
262
  return
263
 
264
- st.markdown(f"### 🎯 Recommended Models for {ram_gb}GB RAM:")
265
-
266
  for category, model_list in models_dict.items():
267
  if model_list:
268
- with st.expander(f"📂 {category.replace('_', ' ').title()} Models"):
269
- for model in model_list[:8]: # Limit to top 8 per category
270
- col1, col2, col3 = st.columns([3, 1, 2])
271
- with col1:
272
- st.markdown(f"**{model['name']}**")
273
- with col2:
274
- st.markdown(f"`{model['size']}`")
275
- with col3:
276
- st.markdown(f"*{model['description']}*")
277
 
278
  # Main App
279
  st.title("🧠 LLM Compatibility Advisor")
280
- st.markdown("Get personalized recommendations from **150+ popular open source AI models** with download sizes!")
281
 
282
  # Load data
283
  df, error = load_data()
284
 
285
  if error:
286
  st.error(error)
287
- st.info("Please ensure the Excel file 'BITS_INTERNS.xlsx' is in the same directory as this script.")
288
  st.stop()
289
 
290
  if df is None or df.empty:
291
- st.error("No data found in the Excel file.")
292
  st.stop()
293
 
294
- # Sidebar filters and info
295
  with st.sidebar:
296
- st.header("🔍 Filters & Info")
297
-
298
- # Performance tier filter
299
- performance_filter = st.multiselect(
300
- "Filter by Performance Tier:",
301
- ["Ultra Low", "Low", "Moderate-Low", "Moderate", "Good", "High", "Ultra High", "Unknown"],
302
- default=["Ultra Low", "Low", "Moderate-Low", "Moderate", "Good", "High", "Ultra High", "Unknown"]
303
- )
304
-
305
- # Model category filter
306
- st.subheader("Model Categories")
307
- show_categories = st.multiselect(
308
- "Show specific categories:",
309
- ["general", "code", "chat", "reasoning", "multimodal"],
310
- default=["general", "code", "chat"]
311
- )
312
-
313
- st.markdown("---")
314
- st.markdown("### 📊 Quick Stats")
315
  st.metric("Total Students", len(df))
316
- st.metric("Popular Models", "150+")
317
 
318
- # Calculate average RAM
319
  avg_laptop_ram = df["Laptop RAM"].apply(extract_numeric_ram).mean()
320
  avg_mobile_ram = df["Mobile RAM"].apply(extract_numeric_ram).mean()
321
 
@@ -324,7 +204,7 @@ with st.sidebar:
324
  if not pd.isna(avg_mobile_ram):
325
  st.metric("Avg Mobile RAM", f"{avg_mobile_ram:.1f} GB")
326
 
327
- # User selection with search
328
  st.subheader("👤 Individual Student Analysis")
329
  selected_user = st.selectbox(
330
  "Choose a student:",
@@ -335,255 +215,93 @@ selected_user = st.selectbox(
335
  if selected_user:
336
  user_data = df[df["Full Name"] == selected_user].iloc[0]
337
 
338
- # Enhanced user display
339
  col1, col2 = st.columns(2)
340
 
341
  with col1:
342
- st.markdown("### 💻 Laptop Configuration")
 
343
  laptop_ram = user_data.get('Laptop RAM', 'Not specified')
344
- laptop_rec, laptop_tier, laptop_info, laptop_models = recommend_llm(laptop_ram)
345
- laptop_ram_gb = extract_numeric_ram(laptop_ram) or 0
346
 
 
347
  st.markdown(f"**RAM:** {laptop_ram}")
348
- st.markdown(f"**Performance Tier:** {laptop_tier}")
349
 
350
- st.success(f"**💡 Recommendation:** {laptop_rec}")
351
- st.info(f"**ℹ️ Notes:** {laptop_info}")
352
-
353
- # Display detailed models for laptop
354
- if laptop_models:
355
- filtered_models = {k: v for k, v in laptop_models.items() if k in show_categories}
356
- display_model_categories(filtered_models, laptop_ram_gb)
357
 
358
  with col2:
359
- st.markdown("### 📱 Mobile Configuration")
 
360
  mobile_ram = user_data.get('Mobile RAM', 'Not specified')
361
- mobile_rec, mobile_tier, mobile_info, mobile_models = recommend_llm(mobile_ram)
362
- mobile_ram_gb = extract_numeric_ram(mobile_ram) or 0
363
 
 
364
  st.markdown(f"**RAM:** {mobile_ram}")
365
- st.markdown(f"**Performance Tier:** {mobile_tier}")
366
-
367
- st.success(f"**💡 Recommendation:** {mobile_rec}")
368
- st.info(f"**ℹ️ Notes:** {mobile_info}")
369
 
370
- # Display detailed models for mobile
371
- if mobile_models:
372
- filtered_models = {k: v for k, v in mobile_models.items() if k in show_categories}
373
- display_model_categories(filtered_models, mobile_ram_gb)
374
 
375
- # Batch Analysis Section
376
  st.markdown("---")
377
- st.header("📊 Batch Analysis & Insights")
378
 
379
- # Create enhanced batch table
380
  df_display = df[["Full Name", "Laptop RAM", "Mobile RAM"]].copy()
 
 
381
 
382
- # Add recommendations and performance tiers
383
- laptop_recommendations = df["Laptop RAM"].apply(lambda x: recommend_llm(x)[0])
384
- mobile_recommendations = df["Mobile RAM"].apply(lambda x: recommend_llm(x)[0])
385
- laptop_tiers = df["Laptop RAM"].apply(lambda x: recommend_llm(x)[1])
386
- mobile_tiers = df["Mobile RAM"].apply(lambda x: recommend_llm(x)[1])
387
-
388
- df_display["Laptop LLM"] = laptop_recommendations
389
- df_display["Mobile LLM"] = mobile_recommendations
390
- df_display["Laptop Tier"] = laptop_tiers
391
- df_display["Mobile Tier"] = mobile_tiers
392
-
393
- # Filter based on sidebar selections
394
- mask = (laptop_tiers.isin(performance_filter) | mobile_tiers.isin(performance_filter))
395
-
396
- df_filtered = df_display[mask]
397
 
398
- # Display filtered table
399
- st.subheader(f"📋 Student Recommendations ({len(df_filtered)} students)")
400
- st.dataframe(
401
- df_filtered,
402
- use_container_width=True,
403
- column_config={
404
- "Full Name": st.column_config.TextColumn("Student Name", width="medium"),
405
- "Laptop RAM": st.column_config.TextColumn("Laptop RAM", width="small"),
406
- "Mobile RAM": st.column_config.TextColumn("Mobile RAM", width="small"),
407
- "Laptop LLM": st.column_config.TextColumn("Laptop Recommendation", width="large"),
408
- "Mobile LLM": st.column_config.TextColumn("Mobile Recommendation", width="large"),
409
- "Laptop Tier": st.column_config.TextColumn("L-Tier", width="small"),
410
- "Mobile Tier": st.column_config.TextColumn("M-Tier", width="small"),
411
- }
412
- )
413
-
414
- # Performance distribution chart
415
  if len(df) > 1:
416
- st.subheader("📈 RAM Distribution Analysis")
417
  fig = create_performance_chart(df)
418
  st.plotly_chart(fig, use_container_width=True)
419
 
420
- # Performance tier summary
421
- st.subheader("🎯 Performance Tier Summary")
422
- tier_col1, tier_col2 = st.columns(2)
423
-
424
- with tier_col1:
425
- st.markdown("**Laptop Performance Tiers:**")
426
- laptop_tier_counts = laptop_tiers.value_counts()
427
- for tier, count in laptop_tier_counts.items():
428
- percentage = (count / len(laptop_tiers)) * 100
429
- st.write(f"• {tier}: {count} students ({percentage:.1f}%)")
430
-
431
- with tier_col2:
432
- st.markdown("**Mobile Performance Tiers:**")
433
- mobile_tier_counts = mobile_tiers.value_counts()
434
- for tier, count in mobile_tier_counts.items():
435
- percentage = (count / len(mobile_tier_counts)) * 100
436
- st.write(f"• {tier}: {count} students ({percentage:.1f}%)")
437
-
438
- # Model Explorer Section
439
  st.markdown("---")
440
- st.header("🔍 Popular Model Explorer")
441
-
442
- explorer_col1, explorer_col2 = st.columns(2)
443
 
444
- with explorer_col1:
445
- selected_ram_range = st.selectbox(
446
- "Select RAM range to explore models:",
447
- ["≤2GB (Ultra Low)", "3-4GB (Low)", "5-6GB (Moderate-Low)",
448
- "7-8GB (Moderate)", "9-16GB (Good)", "17-32GB (High)", ">32GB (Ultra High)"]
449
- )
450
-
451
- with explorer_col2:
452
- selected_category = st.selectbox(
453
- "Select model category:",
454
- ["general", "code", "chat", "reasoning", "multimodal"]
455
- )
456
 
457
- # Map selection to database key
458
  ram_mapping = {
459
  "≤2GB (Ultra Low)": "ultra_low",
460
  "3-4GB (Low)": "low",
461
- "5-6GB (Moderate-Low)": "moderate_low",
462
- "7-8GB (Moderate)": "moderate",
463
  "9-16GB (Good)": "good",
464
  "17-32GB (High)": "high",
465
  ">32GB (Ultra High)": "ultra_high"
466
  }
467
 
468
- selected_ram_key = ram_mapping[selected_ram_range]
469
- if selected_ram_key in LLM_DATABASE and selected_category in LLM_DATABASE[selected_ram_key]:
470
- models = LLM_DATABASE[selected_ram_key][selected_category]
471
-
472
- st.subheader(f"🎯 {selected_category.title()} Models for {selected_ram_range}")
473
-
474
- # Display models in a detailed table
475
- for model in models:
476
- with st.container():
477
- col1, col2, col3 = st.columns([3, 1, 3])
478
- with col1:
479
- st.markdown(f"### {model['name']}")
480
- with col2:
481
- st.markdown(f"**{model['size']}**")
482
- st.caption("Download Size")
483
- with col3:
484
- st.markdown(f"*{model['description']}*")
485
- # Add download suggestion
486
- if "Llama" in model['name']:
487
- st.caption("🔗 Available on Hugging Face & Ollama")
488
- elif "Mistral" in model['name']:
489
- st.caption("🔗 Available on Hugging Face & Mistral AI")
490
- elif "Gemma" in model['name']:
491
- st.caption("🔗 Available on Hugging Face & Google")
492
- else:
493
- st.caption("🔗 Available on Hugging Face")
494
- st.markdown("---")
495
- else:
496
- st.info(f"No {selected_category} models available for {selected_ram_range}")
497
 
498
- # Enhanced reference guide
499
- with st.expander("📘 Model Guide & Download Information"):
500
  st.markdown("""
501
- ## 🚀 Popular Models by Category
502
-
503
- ### 🎯 **General Purpose Champions**
504
- - **Llama-2 Series**: Meta's flagship models (7B, 13B, 70B)
505
- - **Mistral Series**: Excellent efficiency and performance
506
- - **Gemma**: Google's efficient models (2B, 7B)
507
- - **Phi**: Microsoft's compact powerhouses
508
 
509
- ### 💻 **Code Specialists**
510
- - **CodeLlama**: Meta's dedicated coding models
511
- - **StarCoder**: BigCode's programming experts
512
- - **WizardCoder**: Enhanced coding capabilities
513
- - **DeepSeek-Coder**: Chinese tech giant's coder
514
 
515
- ### 💬 **Chat Optimized**
516
- - **Vicuna**: UC Berkeley's ChatGPT alternative
517
- - **Zephyr**: HuggingFace's chat specialist
518
- - **OpenChat**: High-quality conversation models
519
- - **Neural-Chat**: Intel-optimized chat models
520
 
521
- ### 🧮 **Reasoning Masters**
522
- - **WizardMath**: Mathematical problem solving
523
- - **MetaMath**: Advanced arithmetic reasoning
524
- - **Orca-2**: Microsoft's reasoning specialist
525
- - **Goat**: Specialized arithmetic model
526
-
527
- ### 👁️ **Multimodal Models**
528
- - **LLaVA**: Large Language and Vision Assistant
529
- - **MiniGPT-4**: Multimodal conversational AI
530
-
531
- ## 💾 Download Size Reference
532
-
533
- | Model Size | FP16 | 8-bit | 4-bit | Use Case |
534
- |------------|------|-------|-------|----------|
535
- | **1-3B** | 2-6GB | 1-3GB | 0.5-1.5GB | Mobile, Edge |
536
- | **7B** | 13GB | 7GB | 3.5GB | Desktop, Laptop |
537
- | **13B** | 26GB | 13GB | 7GB | Workstation |
538
- | **30-34B** | 60GB | 30GB | 15GB | Server, Cloud |
539
- | **70B** | 140GB | 70GB | 35GB | High-end Server |
540
-
541
- ## 🛠️ Where to Download
542
-
543
- ### **Primary Sources**
544
- - **🤗 Hugging Face**: Largest repository with 400,000+ models
545
- - **🦙 Ollama**: Simple CLI tool for local deployment
546
- - **📦 LM Studio**: User-friendly GUI for model management
547
-
548
- ### **Quantized Formats**
549
- - **GGUF**: Best for CPU inference (llama.cpp)
550
- - **GPTQ**: GPU-optimized quantization
551
- - **AWQ**: Advanced weight quantization
552
-
553
- ### **Download Tips**
554
- - Use `git lfs` for large models from Hugging Face
555
- - Consider bandwidth and storage before downloading
556
- - Start with 4-bit quantized versions for testing
557
- - Use `ollama pull model_name` for easiest setup
558
-
559
- ## 🔧 Optimization Strategies
560
-
561
- ### **Memory Reduction**
562
- - **4-bit quantization**: 75% memory reduction
563
- - **8-bit quantization**: 50% memory reduction
564
- - **CPU offloading**: Use system RAM for overflow
565
-
566
- ### **Speed Optimization**
567
- - **GPU acceleration**: CUDA, ROCm, Metal
568
- - **Batch processing**: Process multiple requests
569
- - **Context caching**: Reuse computations
570
  """)
571
 
572
- # Footer with updated resources
573
  st.markdown("---")
574
- st.markdown("""
575
- ### 🔗 Essential Download & Deployment Tools
576
-
577
- **📦 Easy Model Deployment:**
578
- - [**Ollama**](https://ollama.ai/) – `curl -fsSL https://ollama.ai/install.sh | sh`
579
- - [**LM Studio**](https://lmstudio.ai/) – Drag-and-drop GUI for running models locally
580
- - [**GPT4All**](https://gpt4all.io/) – Cross-platform desktop app for local LLMs
581
-
582
- **🤗 Model Repositories:**
583
- - [**Hugging Face Hub**](https://huggingface.co/models) – Filter by model size, task, and license
584
- - [**TheBloke's Quantizations**](https://huggingface.co/TheBloke) – Pre-quantized models in GGUF/GPTQ format
585
- - [**Awesome LLM**](https://github.com/Hannibal046/Awesome-LLMs) – Curated list of models and resources
586
-
587
-
588
- ---
589
- """)
 
1
  #!/usr/bin/env python3
2
  """
3
+ LLM Compatibility Advisor - Streamlined Version
4
  Author: Assistant
5
+ Description: Provides device-based LLM recommendations with popular models
6
  Requirements: streamlit, pandas, plotly, openpyxl
7
  """
8
 
9
  import streamlit as st
10
  import pandas as pd
11
  import re
 
12
  import plotly.graph_objects as go
13
+ from typing import Optional, Tuple, Dict, List
14
 
15
+ # Must be first Streamlit command
16
  st.set_page_config(
17
  page_title="LLM Compatibility Advisor",
18
  layout="wide",
19
+ page_icon="🧠"
 
20
  )
21
 
 
22
  @st.cache_data
23
  def load_data():
24
  try:
 
30
  except Exception as e:
31
  return None, f"Error loading data: {str(e)}"
32
 
 
33
  def extract_numeric_ram(ram) -> Optional[int]:
34
  if pd.isna(ram):
35
  return None
36
 
37
  ram_str = str(ram).lower().replace(" ", "")
38
 
39
+ # Handle GB format
40
  gb_match = re.search(r"(\d+(?:\.\d+)?)(?:gb|g)", ram_str)
41
  if gb_match:
42
  return int(float(gb_match.group(1)))
 
44
  # Handle MB format
45
  mb_match = re.search(r"(\d+)(?:mb|m)", ram_str)
46
  if mb_match:
47
+ return max(1, int(int(mb_match.group(1)) / 1024))
48
 
49
+ # Handle plain numbers
50
  plain_match = re.search(r"(\d+)", ram_str)
51
  if plain_match:
52
  return int(plain_match.group(1))
53
 
54
  return None
55
 
56
+ # Simplified LLM database
57
  LLM_DATABASE = {
58
  "ultra_low": { # ≤2GB
59
  "general": [
60
  {"name": "TinyLlama-1.1B-Chat", "size": "637MB", "description": "Compact chat model"},
 
61
  {"name": "all-MiniLM-L6-v2", "size": "91MB", "description": "Sentence embeddings"}
62
  ],
63
  "code": [
64
+ {"name": "CodeT5-small", "size": "242MB", "description": "Code generation"}
 
65
  ]
66
  },
67
  "low": { # 3-4GB
68
  "general": [
69
  {"name": "Phi-1.5", "size": "2.8GB", "description": "Microsoft's efficient model"},
70
+ {"name": "Gemma-2B", "size": "1.4GB", "description": "Google's compact model"}
 
71
  ],
72
  "code": [
73
+ {"name": "CodeGen-2B", "size": "1.8GB", "description": "Salesforce code model"}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
74
  ]
75
  },
76
+ "moderate": { # 5-8GB
77
  "general": [
78
  {"name": "Llama-2-7B-Chat", "size": "3.5GB", "description": "Meta's popular chat model"},
79
+ {"name": "Mistral-7B-Instruct-v0.2", "size": "4.1GB", "description": "Latest Mistral instruct"}
 
80
  ],
81
  "code": [
82
+ {"name": "CodeLlama-7B-Instruct", "size": "3.8GB", "description": "Instruction-tuned CodeLlama"}
 
 
 
 
 
 
83
  ]
84
  },
85
  "good": { # 9-16GB
86
  "general": [
87
  {"name": "Llama-2-13B-Chat", "size": "7.3GB", "description": "Larger Llama variant"},
 
88
  {"name": "OpenChat-3.5", "size": "7.1GB", "description": "High-quality chat model"}
89
  ],
90
  "code": [
91
+ {"name": "CodeLlama-13B-Instruct", "size": "7.3GB", "description": "Larger code model"}
 
 
 
 
 
 
 
 
 
 
92
  ]
93
  },
94
  "high": { # 17-32GB
95
  "general": [
96
  {"name": "Mixtral-8x7B-Instruct-v0.1", "size": "26.9GB", "description": "Mixture of experts"},
 
97
  {"name": "Yi-34B-Chat", "size": "19.5GB", "description": "01.AI's large model"}
98
  ],
99
  "code": [
100
+ {"name": "CodeLlama-34B-Instruct", "size": "19.0GB", "description": "Large code specialist"}
 
 
 
 
 
 
101
  ]
102
  },
103
  "ultra_high": { # >32GB
104
  "general": [
105
  {"name": "Llama-2-70B", "size": "130GB", "description": "Full precision"},
106
+ {"name": "Mixtral-8x22B", "size": "176GB", "description": "Latest mixture model"}
 
 
 
 
 
 
 
 
 
107
  ]
108
  }
109
  }
110
 
111
+ def recommend_llm(ram_str) -> Tuple[str, str, Dict[str, List[Dict]]]:
112
+ """Returns (recommendation, performance_tier, detailed_models)"""
 
113
  ram = extract_numeric_ram(ram_str)
114
 
115
  if ram is None:
116
+ return "⚪ Check exact specs", "Unknown", {}
 
 
 
117
 
118
  if ram <= 2:
119
+ return "🔸 Ultra-lightweight models", "Ultra Low", LLM_DATABASE["ultra_low"]
 
 
 
 
120
  elif ram <= 4:
121
+ return "🔸 Small language models", "Low", LLM_DATABASE["low"]
 
 
 
 
 
 
 
 
 
 
122
  elif ram <= 8:
123
+ return "🟠 7B models - excellent capabilities", "Moderate", LLM_DATABASE["moderate"]
 
 
 
 
124
  elif ram <= 16:
125
+ return "🟢 High-quality models", "Good", LLM_DATABASE["good"]
 
 
 
 
126
  elif ram <= 32:
127
+ return "🔵 Premium models", "High", LLM_DATABASE["high"]
128
+ else:
129
+ return "🔵 Top-tier models", "Ultra High", LLM_DATABASE["ultra_high"]
130
+
131
+ def get_os_info(os_name) -> Tuple[str, str]:
132
+ """Returns (icon, clean_name)"""
133
+ if pd.isna(os_name):
134
+ return "💻", "Not specified"
135
+
136
+ os = str(os_name).lower()
137
+ if "windows" in os:
138
+ return "🪟", os_name
139
+ elif "mac" in os:
140
+ return "🍎", os_name
141
+ elif "linux" in os or "ubuntu" in os:
142
+ return "🐧", os_name
143
+ elif "android" in os:
144
+ return "🤖", os_name
145
+ elif "ios" in os:
146
+ return "📱", os_name
147
  else:
148
+ return "💻", os_name
 
 
 
 
149
 
 
150
  def create_performance_chart(df):
151
+ """Create RAM distribution chart"""
152
  laptop_rams = df["Laptop RAM"].apply(extract_numeric_ram).dropna()
153
  mobile_rams = df["Mobile RAM"].apply(extract_numeric_ram).dropna()
154
 
155
  fig = go.Figure()
156
+ fig.add_trace(go.Histogram(x=laptop_rams, name="Laptop RAM", opacity=0.7))
157
+ fig.add_trace(go.Histogram(x=mobile_rams, name="Mobile RAM", opacity=0.7))
 
 
 
 
 
 
 
 
 
 
 
 
158
 
159
  fig.update_layout(
160
+ title="RAM Distribution",
161
  xaxis_title="RAM (GB)",
162
+ yaxis_title="Students",
163
  barmode='overlay',
164
  height=400
165
  )
 
166
  return fig
167
 
168
+ def display_models(models_dict: Dict[str, List[Dict]]):
169
+ """Display models by category"""
 
170
  if not models_dict:
171
  return
172
 
 
 
173
  for category, model_list in models_dict.items():
174
  if model_list:
175
+ st.markdown(f"**{category.title()} Models:**")
176
+ for model in model_list[:5]: # Limit to 5 per category
177
+ st.write(f"• {model['name']} ({model['size']}) - {model['description']}")
 
 
 
 
 
 
178
 
179
  # Main App
180
  st.title("🧠 LLM Compatibility Advisor")
181
+ st.markdown("Get personalized AI model recommendations with download sizes!")
182
 
183
  # Load data
184
  df, error = load_data()
185
 
186
  if error:
187
  st.error(error)
 
188
  st.stop()
189
 
190
  if df is None or df.empty:
191
+ st.error("No data found.")
192
  st.stop()
193
 
194
+ # Sidebar
195
  with st.sidebar:
196
+ st.header("📊 Quick Stats")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
197
  st.metric("Total Students", len(df))
 
198
 
 
199
  avg_laptop_ram = df["Laptop RAM"].apply(extract_numeric_ram).mean()
200
  avg_mobile_ram = df["Mobile RAM"].apply(extract_numeric_ram).mean()
201
 
 
204
  if not pd.isna(avg_mobile_ram):
205
  st.metric("Avg Mobile RAM", f"{avg_mobile_ram:.1f} GB")
206
 
207
+ # Individual Analysis
208
  st.subheader("👤 Individual Student Analysis")
209
  selected_user = st.selectbox(
210
  "Choose a student:",
 
215
  if selected_user:
216
  user_data = df[df["Full Name"] == selected_user].iloc[0]
217
 
 
218
  col1, col2 = st.columns(2)
219
 
220
  with col1:
221
+ st.markdown("### 💻 Laptop")
222
+ laptop_os_icon, laptop_os_name = get_os_info(user_data.get('Laptop Operating System'))
223
  laptop_ram = user_data.get('Laptop RAM', 'Not specified')
224
+ laptop_rec, laptop_tier, laptop_models = recommend_llm(laptop_ram)
 
225
 
226
+ st.markdown(f"**OS:** {laptop_os_icon} {laptop_os_name}")
227
  st.markdown(f"**RAM:** {laptop_ram}")
228
+ st.success(f"**Recommendation:** {laptop_rec}")
229
 
230
+ display_models(laptop_models)
 
 
 
 
 
 
231
 
232
  with col2:
233
+ st.markdown("### 📱 Mobile")
234
+ mobile_os_icon, mobile_os_name = get_os_info(user_data.get('Mobile Operating System'))
235
  mobile_ram = user_data.get('Mobile RAM', 'Not specified')
236
+ mobile_rec, mobile_tier, mobile_models = recommend_llm(mobile_ram)
 
237
 
238
+ st.markdown(f"**OS:** {mobile_os_icon} {mobile_os_name}")
239
  st.markdown(f"**RAM:** {mobile_ram}")
240
+ st.success(f"**Recommendation:** {mobile_rec}")
 
 
 
241
 
242
+ display_models(mobile_models)
 
 
 
243
 
244
+ # Batch Analysis
245
  st.markdown("---")
246
+ st.header("📊 Batch Analysis")
247
 
248
+ # Create summary table
249
  df_display = df[["Full Name", "Laptop RAM", "Mobile RAM"]].copy()
250
+ df_display["Laptop Recommendation"] = df["Laptop RAM"].apply(lambda x: recommend_llm(x)[0])
251
+ df_display["Mobile Recommendation"] = df["Mobile RAM"].apply(lambda x: recommend_llm(x)[0])
252
 
253
+ st.dataframe(df_display, use_container_width=True)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
254
 
255
+ # Performance chart
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
256
  if len(df) > 1:
257
+ st.subheader("📈 RAM Distribution")
258
  fig = create_performance_chart(df)
259
  st.plotly_chart(fig, use_container_width=True)
260
 
261
+ # Model Explorer
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
262
  st.markdown("---")
263
+ st.header("🔍 Model Explorer")
 
 
264
 
265
+ selected_ram_range = st.selectbox(
266
+ "Select RAM range:",
267
+ ["≤2GB (Ultra Low)", "3-4GB (Low)", "5-8GB (Moderate)",
268
+ "9-16GB (Good)", "17-32GB (High)", ">32GB (Ultra High)"]
269
+ )
 
 
 
 
 
 
 
270
 
271
+ # Map selection to database
272
  ram_mapping = {
273
  "≤2GB (Ultra Low)": "ultra_low",
274
  "3-4GB (Low)": "low",
275
+ "5-8GB (Moderate)": "moderate",
 
276
  "9-16GB (Good)": "good",
277
  "17-32GB (High)": "high",
278
  ">32GB (Ultra High)": "ultra_high"
279
  }
280
 
281
+ selected_key = ram_mapping[selected_ram_range]
282
+ if selected_key in LLM_DATABASE:
283
+ st.subheader(f"Models for {selected_ram_range}")
284
+ display_models(LLM_DATABASE[selected_key])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
285
 
286
+ # Quick reference
287
+ with st.expander("📘 Quick Reference"):
288
  st.markdown("""
289
+ ## Popular Models by Category
 
 
 
 
 
 
290
 
291
+ **General Purpose:**
292
+ - Llama-2 Series (7B, 13B, 70B)
293
+ - Mistral Series
294
+ - Gemma (2B, 7B)
 
295
 
296
+ **Code Specialists:**
297
+ - CodeLlama
298
+ - CodeGen
 
 
299
 
300
+ **Where to Download:**
301
+ - 🤗 Hugging Face Hub
302
+ - 🦙 Ollama
303
+ - 📦 LM Studio
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
304
  """)
305
 
 
306
  st.markdown("---")
307
+ st.markdown("*Built for BITS Pilani Interns*")