qwerty45-uiop commited on
Commit
b8d4ff0
ยท
verified ยท
1 Parent(s): 574a10f

Update src/streamlit_app.py

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