Rajesh0279 commited on
Commit
d89ed60
ยท
verified ยท
1 Parent(s): 85be3d8

Update src/streamlit_app.py

Browse files
Files changed (1) hide show
  1. src/streamlit_app.py +756 -35
src/streamlit_app.py CHANGED
@@ -1,40 +1,761 @@
1
- import altair as alt
2
- import numpy as np
3
- import pandas as pd
 
 
 
 
 
4
  import streamlit as st
 
 
 
 
 
 
 
 
 
5
 
6
- """
7
- # Welcome to Streamlit!
 
 
 
 
 
8
 
9
- Edit `/streamlit_app.py` to customize this app to your heart's desire :heart:.
10
- If you have any questions, checkout our [documentation](https://docs.streamlit.io) and [community
11
- forums](https://discuss.streamlit.io).
12
 
13
- In the meantime, below is an example of what you can do with just a few lines of code:
14
- """
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
15
 
16
- num_points = st.slider("Number of points in spiral", 1, 10000, 1100)
17
- num_turns = st.slider("Number of turns in spiral", 1, 300, 31)
18
-
19
- indices = np.linspace(0, 1, num_points)
20
- theta = 2 * np.pi * num_turns * indices
21
- radius = indices
22
-
23
- x = radius * np.cos(theta)
24
- y = radius * np.sin(theta)
25
-
26
- df = pd.DataFrame({
27
- "x": x,
28
- "y": y,
29
- "idx": indices,
30
- "rand": np.random.randn(num_points),
31
- })
32
-
33
- st.altair_chart(alt.Chart(df, height=700, width=700)
34
- .mark_point(filled=True)
35
- .encode(
36
- x=alt.X("x", axis=None),
37
- y=alt.Y("y", axis=None),
38
- color=alt.Color("idx", legend=None, scale=alt.Scale()),
39
- size=alt.Size("rand", legend=None, scale=alt.Scale(range=[1, 150])),
40
- ))
 
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
+ from run2 import run_app2
11
+ import pandas as pd
12
+ import numpy as np
13
+ import re
14
+ import plotly.express as px
15
+ import plotly.graph_objects as go
16
+ from typing import Optional, Tuple, List, Dict
17
+ from run3 import estimate_training_time_and_cost,get_gpu_teraflops,get_gpu_cost_per_tflop_hour
18
+ from utils import get_all_models_from_database
19
 
20
+ # โœ… MUST be the first Streamlit command
21
+ st.set_page_config(
22
+ page_title="LLM Compatibility Advisor",
23
+ layout="wide",
24
+ page_icon="",
25
+ initial_sidebar_state="expanded"
26
+ )
27
 
28
+ # Enhanced data loading with error handling
 
 
29
 
30
+ def run_app1():
31
+ # ... place all existing logic from `streamlit_app.py` here ...
32
+ if __name__ == "__main__":
33
+ run_app1()
34
+
35
+ @st.cache_data
36
+ def load_data():
37
+ paths = [
38
+ "src/BITS_INTERNS.xlsx",
39
+ "src/ICFAI.xlsx"
40
+ ]
41
+
42
+ combined_df = pd.DataFrame()
43
+ for path in paths:
44
+ try:
45
+ df = pd.read_excel(path, sheet_name="Form Responses 1")
46
+ df.columns = df.columns.str.strip()
47
+ combined_df = pd.concat([combined_df, df], ignore_index=True)
48
+ except FileNotFoundError:
49
+ return None, f"Excel file '{path}' not found. Please upload the file."
50
+ except Exception as e:
51
+ return None, f"Error loading '{path}': {str(e)}"
52
+
53
+ # Return success case - this was missing!
54
+ if combined_df.empty:
55
+ return None, "No data found in Excel files."
56
+ else:
57
+ return combined_df, None
58
+
59
+ # Enhanced RAM extraction with better parsing
60
+ def extract_numeric_ram(ram) -> Optional[int]:
61
+ if pd.isna(ram):
62
+ return None
63
+
64
+ ram_str = str(ram).lower().replace(" ", "")
65
+
66
+ # Handle various formats: "8GB", "8 GB", "8gb", "8192MB", etc.
67
+ gb_match = re.search(r"(\d+(?:\.\d+)?)(?:gb|g)", ram_str)
68
+ if gb_match:
69
+ return int(float(gb_match.group(1)))
70
+
71
+ # Handle MB format
72
+ mb_match = re.search(r"(\d+)(?:mb|m)", ram_str)
73
+ if mb_match:
74
+ return max(1, int(int(mb_match.group(1)) / 1024)) # Convert MB to GB
75
+
76
+ # Handle plain numbers (assume GB)
77
+ plain_match = re.search(r"(\d+)", ram_str)
78
+ if plain_match:
79
+ return int(plain_match.group(1))
80
+
81
+ return None
82
+
83
+ # Streamlined LLM database with popular models and download sizes
84
+ LLM_DATABASE = {
85
+ "ultra_low": { # โ‰ค2GB
86
+ "general": [
87
+ {"name": "TinyLlama-1.1B-Chat", "size": "637MB", "description": "Compact chat model", "cost(A100)":"โ‚น1,21,929", "cost(H100)":"โ‚น53,796"},
88
+ {"name": "DistilBERT-base", "size": "268MB", "description": "Efficient BERT variant", "cost(A100)": "โ‚น12,193","cost(H100)":"โ‚น5,380"},
89
+ {"name": "all-MiniLM-L6-v2", "size": "91MB", "description": "Sentence embeddings", "cost(A100)":"โ‚น4,024", "cost(H100)":"โ‚น1,775"}
90
+ ],
91
+ "code": [
92
+ {"name": "CodeT5-small", "size": "242MB", "description": "Code generation", "cost(A100)":"โ‚น12,193","cost(H100)":"โ‚น5,380"},
93
+ {"name": "Replit-code-v1-3B", "size": "1.2GB", "description": "Code completion", "cost(A100)":"โ‚น3,65,787","cost(H100)":"โ‚น1,61,388"}
94
+ ]
95
+ },
96
+ "low": { # 3-4GB
97
+ "general": [
98
+ {"name": "Phi-1.5", "size": "2.8GB", "description": "Microsoft's efficient model", "cost(A100)":"โ‚น1,58,507","cost(H100)":"โ‚น70,023"},
99
+ {"name": "Gemma-2B", "size": "1.4GB", "description": "Google's compact model", "cost(A100)":"โ‚น2,43,858","cost(H100)":"โ‚น1,07,592"},
100
+ {"name": "OpenLLaMA-3B", "size": "2.1GB", "description": "Open source LLaMA", "cost(A100)": "โ‚น3,65,787","cost(H100)":"โ‚น1,61,388"}
101
+ ],
102
+ "code": [
103
+ {"name": "CodeGen-2B", "size": "1.8GB", "description": "Salesforce code model", "cost(A100)":"โ‚น2,43,858","cost(H100)":"โ‚น1,07,592"},
104
+ {"name": "StarCoder-1B", "size": "1.1GB", "description": "BigCode project", "cost(A100)":"โ‚น1,21,929","cost(H100)":"โ‚น53,796"}
105
+ ],
106
+ "chat": [
107
+ {"name": "Alpaca-3B", "size": "2.0GB", "description": "Stanford's instruction model", "cost(A100)": "โ‚น3,65,787","cost(H100)":"โ‚น1,61,388"},
108
+ {"name": "Vicuna-3B", "size": "2.1GB", "description": "ChatGPT-style training","cost(A100)":"โ‚น3,65,787","cost(H100)":"โ‚น1,61,388"}
109
+ ]
110
+ },
111
+ "moderate_low": { # 5-6GB
112
+ "general": [
113
+ {"name": "Phi-2", "size": "5.2GB", "description": "Microsoft's 2.7B model", "cost(A100)":"โ‚น3,29,209","cost(H100)":"โ‚น1,45,249"},
114
+ {"name": "Gemma-7B-it", "size": "4.2GB", "description": "Google instruction tuned", "cost(A100)":"โ‚น8,53,501","cost(H100)":"โ‚น3,76,572"},
115
+ {"name": "Mistral-7B-v0.1", "size": "4.1GB", "description": "Mistral AI base model", "cost(A100)":"โ‚น8,53,501","cost(H100)":"โ‚น3,76,572"}
116
+ ],
117
+ "code": [
118
+ {"name": "CodeLlama-7B", "size": "3.8GB", "description": "Meta's code specialist","cost(A100)": "โ‚น8,53,501","cost(H100)":"โ‚น3,76,572"},
119
+ {"name": "StarCoder-7B", "size": "4.0GB", "description": "Code generation expert", "cost(A100)":"โ‚น8,53,501","cost(H100)":"โ‚น3,76,572"}
120
+ ],
121
+ "chat": [
122
+ {"name": "Zephyr-7B-beta", "size": "4.2GB", "description": "HuggingFace chat model", "cost(A100)":"โ‚น8,53,501","cost(H100)":"3,76,572"},
123
+ {"name": "Neural-Chat-7B", "size": "4.1GB", "description": "Intel optimized", "cost(A100)": "โ‚น8,53,501","cost(H100)":"โ‚น3,76,572"}
124
+ ]
125
+ },
126
+ "moderate": { # 7-8GB
127
+ "general": [
128
+ {"name": "Llama-2-7B-Chat", "size": "3.5GB", "description": "Meta's popular chat model", "cost(A100)":"โ‚น8,53,501","cost(H100)":"โ‚น3,76,572"},
129
+ {"name": "Mistral-7B-Instruct-v0.2", "size": "4.1GB", "description": "Latest Mistral instruct", "cost(A100)":"โ‚น8,53,501","cost(H100)":"โ‚น3,76,572"},
130
+ {"name": "Qwen-7B-Chat", "size": "4.0GB", "description": "Alibaba's multilingual","cost(A100)": "โ‚น8,53,501","cost(H100)":"โ‚น3,76,572"}
131
+ ],
132
+ "code": [
133
+ {"name": "CodeLlama-7B-Instruct", "size": "3.8GB", "description": "Instruction-tuned CodeLlama", "cost(A100)":"โ‚น8,53,501","cost(H100)":"โ‚น3,76,572"},
134
+ {"name": "WizardCoder-7B", "size": "4.0GB", "description": "Enhanced coding abilities", "cost(A100)":"โ‚น8,53,501","cost(H100)":"โ‚น3,76,572"},
135
+ {"name": "Phind-CodeLlama-34B-v2", "size": "4.2GB", "description": "4-bit quantized version", "cost(A100)": "โ‚น8,53,501","cost(H100)":"โ‚น3,76,572"}
136
+ ],
137
+ "reasoning": [
138
+ {"name": "WizardMath-7B", "size": "4.0GB", "description": "Mathematical reasoning", "cost(A100)":"โ‚น8,53,501","cost(H100)":"โ‚น3,76,572"},
139
+ {"name": "MetaMath-7B", "size": "3.9GB", "description": "Math problem solving","cost(A100)":"โ‚น8,53,501","cost(H100)":"โ‚น3,76,572"}
140
+ ]
141
+ },
142
+ "good": { # 9-16GB
143
+ "general": [
144
+ {"name": "Llama-2-13B-Chat", "size": "7.3GB", "description": "Larger Llama variant", "cost(A100)":"โ‚น15,81,072","cost(H100)":"โ‚น6,97,344"},
145
+ {"name": "Vicuna-13B-v1.5", "size": "7.2GB", "description": "Enhanced Vicuna", "cost(A100)":"โ‚น15,81,072","cost(H100)":"โ‚น6,97,344"},
146
+ {"name": "OpenChat-3.5", "size": "7.1GB", "description": "High-quality chat model", "cost(A100)":"โ‚น15,81,072","cost(H100)":"โ‚น6,97,344"}
147
+ ],
148
+ "code": [
149
+ {"name": "CodeLlama-13B-Instruct", "size": "7.3GB", "description": "Larger code model", "cost(A100)":"โ‚น15,81,072","cost(H100)":"โ‚น6,97,344"},
150
+ {"name": "WizardCoder-15B", "size": "8.2GB", "description": "Advanced coding", "cost(A100)":"โ‚น18,28,931","cost(H100)":"โ‚น8,06,937"},
151
+ {"name": "StarCoder-15B", "size": "8.5GB", "description": "Large code model", "cost(A100)": "โ‚น18,28,931","cost(H100)":"โ‚น8,06,937"}
152
+ ],
153
+ "multimodal": [
154
+ {"name": "LLaVA-7B", "size": "7.0GB", "description": "Vision + language","cost(A100)":"โ‚น8,53,501","cost(H100)":"โ‚น3,76,572"},
155
+ {"name": "MiniGPT-4-7B", "size": "6.8GB", "description": "Multimodalchat","cost(A100)":"โ‚น8,53,501","cost(H100)":"โ‚น3,76,572"}
156
+ ],
157
+ "reasoning": [
158
+ {"name": "WizardMath-13B", "size": "7.3GB", "description": "Advanced math","cost(A100)":"โ‚น15,81,072","cost(H100)":"โ‚น6,97,344"},
159
+ {"name": "Orca-2-13B", "size": "7.4GB", "description": "Microsoft reasoning", "cost(A100)":"โ‚น15,81,072","cost(H100)":"โ‚น6,97,344"}
160
+ ]
161
+ },
162
+ "high": { # 17-32GB
163
+ "general": [
164
+ {"name": "Mixtral-8x7B-Instruct-v0.1", "size": "26.9GB", "description": "Mixture of experts","cost(A100)":"โ‚น8,53,501","cost(H100)":"โ‚น3,76,572"},
165
+ {"name": "Llama-2-70B-Chat", "size": "38.0GB", "description": "8-bit quantized", "cost(A100)":"โ‚น85,35,004","cost(H100)":"โ‚น37,65,715"},
166
+ {"name": "Yi-34B-Chat", "size": "19.5GB", "description": "01.AI's large model", "cost(A100)":"โ‚น41,45,586","cost(H100)":"โ‚น18,25,785"}
167
+ ],
168
+ "code": [
169
+ {"name": "CodeLlama-34B-Instruct", "size": "19.0GB", "description": "Large code specialist", "cost(A100)":"โ‚น41,45,586","cost(H100)":"โ‚น18,25,785"},
170
+ {"name": "DeepSeek-Coder-33B", "size": "18.5GB", "description": "DeepSeek's coder", "cost(A100)":"โ‚น40,23,393","cost(H100)":"โ‚น17,71,989"},
171
+ {"name": "WizardCoder-34B", "size": "19.2GB", "description": "Enterprise coding", "cost(A100)":"โ‚น41,45,586","cost(H100)":"โ‚น18,25,785"}
172
+ ],
173
+ "reasoning": [
174
+ {"name": "WizardMath-70B", "size": "38.5GB", "description": "8-bit quantized math", "cost(A100)":"โ‚น85,35,004","cost(H100)":"โ‚น37,65,715"},
175
+ {"name": "MetaMath-70B", "size": "38.0GB", "description": "8-bit math reasoning", "cost(A100)":"โ‚น85,35,004","cost(H100)":"โ‚น37,65,715"}
176
+ ]
177
+ },
178
+ "ultra_high": { # >32GB
179
+ "general": [
180
+ {"name": "Llama-2-70B", "size": "130GB", "description": "Full precision", "cost(A100)":"โ‚น85,35,004","cost(H100)":"โ‚น37,65,715"},
181
+ {"name": "Mixtral-8x22B", "size": "176GB", "description": "Latest mixture model","cost(A100)":"โ‚น2,14,59,516","cost(H100)":"โ‚น94,61,302"},
182
+ {"name": "Qwen-72B", "size": "145GB", "description": "Alibaba's flagship", "cost(A100)":"โ‚น87,89,394","cost(H100)":"โ‚น38,80,798"}
183
+ ],
184
+ "code": [
185
+ {"name": "CodeLlama-34B", "size": "68GB", "description": "Full precision code", "cost(A100)":"โ‚น41,45,586","cost(H100)":"โ‚น18,25,785"},
186
+ {"name": "DeepSeek-Coder-33B", "size": "66GB", "description": "Full precision coding", "cost(A100)":"โ‚น40,23,393","cost(H100)":"โ‚น17,71,989"}
187
+ ],
188
+ "reasoning": [
189
+ {"name": "WizardMath-70B", "size": "130GB", "description": "Full precision math", "cost(A100)":"โ‚น85,35,004","cost(H100)":"โ‚น37,65,715"},
190
+ {"name": "Goat-70B", "size": "132GB", "description": "Arithmetic reasoning", "cost(A100)":"โ‚น85,35,004","cost(H100)":"โ‚น37,65,715"}
191
+ ]
192
+ }
193
+ }
194
+
195
+ # Enhanced LLM recommendation with performance tiers
196
+ def recommend_llm(ram_str) -> Tuple[str, str, str, Dict[str, List[Dict]]]:
197
+ """Returns (recommendation, performance_tier, additional_info, detailed_models)"""
198
+ ram = extract_numeric_ram(ram_str)
199
+
200
+ if ram is None:
201
+ return ("โšช Check exact specs or test with quantized models.",
202
+ "Unknown",
203
+ "Verify RAM specifications",
204
+ {})
205
+
206
+ if ram <= 2:
207
+ models = LLM_DATABASE["ultra_low"]
208
+ return ("๐Ÿ”ธ Ultra-lightweight models - basic NLP tasks",
209
+ "Ultra Low",
210
+ "Mobile-optimized, simple tasks, limited context",
211
+ models)
212
+ elif ram <= 4:
213
+ models = LLM_DATABASE["low"]
214
+ return ("๐Ÿ”ธ Small language models - decent capabilities",
215
+ "Low",
216
+ "Basic chat, simple reasoning, text classification",
217
+ models)
218
+ elif ram <= 6:
219
+ models = LLM_DATABASE["moderate_low"]
220
+ return ("๐ŸŸ  Mid-range models - good general performance",
221
+ "Moderate-Low",
222
+ "Solid reasoning, coding help, longer conversations",
223
+ models)
224
+ elif ram <= 8:
225
+ models = LLM_DATABASE["moderate"]
226
+ return ("๐ŸŸ  Strong 7B models - excellent capabilities",
227
+ "Moderate",
228
+ "Professional use, coding assistance, complex reasoning",
229
+ models)
230
+ elif ram <= 16:
231
+ models = LLM_DATABASE["good"]
232
+ return ("๐ŸŸข High-quality models - premium performance",
233
+ "Good",
234
+ "Advanced tasks, multimodal support, research use",
235
+ models)
236
+ elif ram <= 32:
237
+ models = LLM_DATABASE["high"]
238
+ return ("๐Ÿ”ต Premium models - professional grade",
239
+ "High",
240
+ "Enterprise ready, complex reasoning, specialized tasks",
241
+ models)
242
+ else:
243
+ models = LLM_DATABASE["ultra_high"]
244
+ return ("๐Ÿ”ต Top-tier models - enterprise capabilities",
245
+ "Ultra High",
246
+ "Research grade, maximum performance, domain expertise",
247
+ models)
248
+
249
+ # Enhanced OS detection with better icons
250
+ def get_os_info(os_name) -> Tuple[str, str]:
251
+ """Returns (icon, clean_name)"""
252
+ if pd.isna(os_name):
253
+ return "๐Ÿ’ป", "Not specified"
254
+
255
+ os = str(os_name).lower()
256
+ if "windows" in os:
257
+ return "๐ŸชŸ", os_name
258
+ elif "mac" in os or "darwin" in os:
259
+ return "๐ŸŽ", os_name
260
+ elif "linux" in os or "ubuntu" in os:
261
+ return "๐Ÿง", os_name
262
+ elif "android" in os:
263
+ return "๐Ÿค–", os_name
264
+ elif "ios" in os:
265
+ return "๐Ÿ“ฑ", os_name
266
+ else:
267
+ return "๐Ÿ’ป", os_name
268
+
269
+ # Performance visualization
270
+ def create_performance_chart(df):
271
+ """Create a performance distribution chart"""
272
+ laptop_rams = df["Laptop RAM"].apply(extract_numeric_ram).dropna()
273
+ mobile_rams = df["Mobile RAM"].apply(extract_numeric_ram).dropna()
274
+
275
+ fig = go.Figure()
276
+
277
+ fig.add_trace(go.Histogram(
278
+ x=laptop_rams,
279
+ name="Laptop RAM",
280
+ opacity=0.7,
281
+ nbinsx=10
282
+ ))
283
+
284
+ fig.add_trace(go.Histogram(
285
+ x=mobile_rams,
286
+ name="Mobile RAM",
287
+ opacity=0.7,
288
+ nbinsx=10
289
+ ))
290
+
291
+ fig.update_layout(
292
+ title="RAM Distribution Across Devices",
293
+ xaxis_title="RAM (GB)",
294
+ yaxis_title="Number of Students",
295
+ barmode='overlay',
296
+ height=400
297
+ )
298
+
299
+ return fig
300
+
301
+ # Enhanced model details display function
302
+ def display_model_categories(models_dict: Dict[str, List[Dict]], ram_gb: int):
303
+ """Display models organized by category with download sizes"""
304
+ if not models_dict:
305
+ return
306
+
307
+ st.markdown(f"### ๐ŸŽฏ Recommended Models for {ram_gb}GB RAM:")
308
+
309
+ for category, model_list in models_dict.items():
310
+ if model_list:
311
+ with st.expander(f"๐Ÿ“‚ {category.replace('_', ' ').title()} Models"):
312
+ for model in model_list[:8]: # Limit to top 8 per category
313
+ col1, col2, col3, col4 = st.columns([3, 1, 2, 4])
314
+ with col1:
315
+ st.markdown(f"**{model['name']}**")
316
+ with col2:
317
+ st.markdown(f"`{model['size']}`")
318
+ with col3:
319
+ st.markdown(f"*{model['description']}*")
320
+ with col4:
321
+ st.markdown(f"*{model['cost(A100)']}*")
322
+
323
+ # Demo data generator for when Excel files are not available
324
+ def generate_demo_data():
325
+ """Generate demo data for testing when Excel files are missing"""
326
+ demo_data = {
327
+ "Full Name": [
328
+ "Demo Student 1", "Demo Student 2", "Demo Student 3", "Demo Student 4",
329
+ "Demo Student 5", "Demo Student 6", "Demo Student 7", "Demo Student 8"
330
+ ],
331
+ "Laptop RAM": ["8GB", "16GB", "4GB", "32GB", "6GB", "12GB", "2GB", "24GB"],
332
+ "Mobile RAM": ["4GB", "8GB", "3GB", "12GB", "6GB", "4GB", "2GB", "8GB"],
333
+ "Laptop Operating System": [
334
+ "Windows 11", "macOS Monterey", "Ubuntu 22.04", "Windows 10",
335
+ "macOS Big Sur", "Fedora 36", "Windows 11", "macOS Ventura"
336
+ ],
337
+ "Mobile Operating System": [
338
+ "Android 13", "iOS 16", "Android 12", "iOS 15",
339
+ "Android 14", "iOS 17", "Android 11", "iOS 16"
340
+ ]
341
+ }
342
+ return pd.DataFrame(demo_data)
343
+
344
+ # Function to safely prepare user options
345
+ def prepare_user_options(df):
346
+ """Safely prepare user options for selectbox, handling NaN values and mixed types"""
347
+ try:
348
+ # Get unique names and filter out NaN values
349
+ unique_names = df["Full Name"].dropna().unique()
350
+
351
+ # Convert to strings and filter out any remaining non-string values
352
+ valid_names = []
353
+ for name in unique_names:
354
+ try:
355
+ str_name = str(name).strip()
356
+ if str_name and str_name.lower() != 'nan':
357
+ valid_names.append(str_name)
358
+ except:
359
+ continue
360
+
361
+ # Create options list with proper string concatenation
362
+ options = ["Select a student..."] + sorted(valid_names)
363
+ return options
364
+ except Exception as e:
365
+ st.error(f"Error preparing user options: {e}")
366
+ return ["Select a student..."]
367
+
368
+ # Main App
369
+ st.title(" LLM Compatibility Advisor")
370
+ tab1, tab2,tab3 = st.tabs(["๐Ÿ“Š Dataset Analysis", " Manual Spec Entry","LLM Training Time Estimator"])
371
+
372
+ with tab1:
373
+ st.markdown("Get personalized recommendations from **150+ popular open source AI models** with download sizes!")
374
+
375
+ # Load data with better error handling
376
+ df, error = load_data()
377
+
378
+ if error or df is None or df.empty:
379
+ st.warning("โš ๏ธ Excel files not found. Running with demo data for testing.")
380
+ st.info("๐Ÿ“ To use real data, place 'BITS_INTERNS.xlsx' and 'ICFAI.xlsx' in the 'src/' directory.")
381
+ df = generate_demo_data()
382
+
383
+ with st.expander("๐Ÿ“‹ Expected Data Format"):
384
+ st.markdown("""
385
+ The app expects Excel files with the following columns:
386
+ - **Full Name**: Student name
387
+ - **Laptop RAM**: RAM specification (e.g., "8GB", "16 GB", "8192MB")
388
+ - **Mobile RAM**: Mobile device RAM
389
+ - **Laptop Operating System**: OS name
390
+ - **Mobile Operating System**: Mobile OS name
391
+ """)
392
+
393
+ # Verify required columns exist
394
+ required_columns = ["Full Name", "Laptop RAM", "Mobile RAM"]
395
+ missing_columns = [col for col in required_columns if col not in df.columns]
396
+
397
+ if missing_columns:
398
+ st.error(f"Missing required columns: {missing_columns}")
399
+ st.info("Please ensure your Excel file contains the required columns.")
400
+ st.stop()
401
+
402
+ # Clean the dataframe
403
+ df = df.copy()
404
+ df["Full Name"] = df["Full Name"].astype(str).str.strip()
405
+
406
+ # Sidebar filters and info
407
+ with st.sidebar:
408
+ st.header("๐Ÿ” Filters & Info")
409
+
410
+ # Performance tier filter
411
+ performance_filter = st.multiselect(
412
+ "Filter by Performance Tier:",
413
+ ["Ultra Low", "Low", "Moderate-Low", "Moderate", "Good", "High", "Ultra High", "Unknown"],
414
+ default=["Ultra Low", "Low", "Moderate-Low", "Moderate", "Good", "High", "Ultra High", "Unknown"]
415
+ )
416
+
417
+ # Model category filter
418
+ st.subheader("Model Categories")
419
+ show_categories = st.multiselect(
420
+ "Show specific categories:",
421
+ ["general", "code", "chat", "reasoning", "multimodal"],
422
+ default=["general", "code", "chat"]
423
+ )
424
+
425
+ st.markdown("---")
426
+ st.markdown("### ๐Ÿ“Š Quick Stats")
427
+ st.metric("Total Students", len(df))
428
+ st.metric("Popular Models", "150+")
429
+
430
+ # Calculate average RAM
431
+ avg_laptop_ram = df["Laptop RAM"].apply(extract_numeric_ram).mean()
432
+ avg_mobile_ram = df["Mobile RAM"].apply(extract_numeric_ram).mean()
433
+
434
+ if not pd.isna(avg_laptop_ram):
435
+ st.metric("Avg Laptop RAM", f"{avg_laptop_ram:.1f} GB")
436
+ if not pd.isna(avg_mobile_ram):
437
+ st.metric("Avg Mobile RAM", f"{avg_mobile_ram:.1f} GB")
438
+
439
+ # User selection with search - FIXED VERSION
440
+ st.subheader("๐Ÿ‘ค Individual Student Analysis")
441
+
442
+ # Prepare options safely
443
+ user_options = prepare_user_options(df)
444
+
445
+ selected_user = st.selectbox(
446
+ "Choose a student:",
447
+ options=user_options,
448
+ index=0 # Default to first option ("Select a student...")
449
+ )
450
+
451
+ if selected_user and selected_user != "Select a student...":
452
+ # Find user data with safe lookup
453
+ user_data_mask = df["Full Name"].astype(str).str.strip() == selected_user
454
+ if user_data_mask.any():
455
+ user_data = df[user_data_mask].iloc[0]
456
+
457
+ # Enhanced user display
458
+ col1, col2 = st.columns(2)
459
+
460
+ with col1:
461
+ st.markdown("### ๐Ÿ’ป Laptop Configuration")
462
+ laptop_os_icon, laptop_os_name = get_os_info(user_data.get('Laptop Operating System'))
463
+ laptop_ram = user_data.get('Laptop RAM', 'Not specified')
464
+ laptop_rec, laptop_tier, laptop_info, laptop_models = recommend_llm(laptop_ram)
465
+ laptop_ram_gb = extract_numeric_ram(laptop_ram) or 0
466
+
467
+ st.markdown(f"**OS:** {laptop_os_icon} {laptop_os_name}")
468
+ st.markdown(f"**RAM:** {laptop_ram}")
469
+ st.markdown(f"**Performance Tier:** {laptop_tier}")
470
+
471
+ st.success(f"**๐Ÿ’ก Recommendation:** {laptop_rec}")
472
+ st.info(f"**โ„น๏ธ Notes:** {laptop_info}")
473
+
474
+ # Display detailed models for laptop
475
+ if laptop_models:
476
+ filtered_models = {k: v for k, v in laptop_models.items() if k in show_categories}
477
+ display_model_categories(filtered_models, laptop_ram_gb)
478
+
479
+ with col2:
480
+ st.markdown("### ๐Ÿ“ฑ Mobile Configuration")
481
+ mobile_os_icon, mobile_os_name = get_os_info(user_data.get('Mobile Operating System'))
482
+ mobile_ram = user_data.get('Mobile RAM', 'Not specified')
483
+ mobile_rec, mobile_tier, mobile_info, mobile_models = recommend_llm(mobile_ram)
484
+ mobile_ram_gb = extract_numeric_ram(mobile_ram) or 0
485
+
486
+ st.markdown(f"**OS:** {mobile_os_icon} {mobile_os_name}")
487
+ st.markdown(f"**RAM:** {mobile_ram}")
488
+ st.markdown(f"**Performance Tier:** {mobile_tier}")
489
+
490
+ st.success(f"**๐Ÿ’ก Recommendation:** {mobile_rec}")
491
+ st.info(f"**โ„น๏ธ Notes:** {mobile_info}")
492
+
493
+ # Display detailed models for mobile
494
+ if mobile_models:
495
+ filtered_models = {k: v for k, v in mobile_models.items() if k in show_categories}
496
+ display_model_categories(filtered_models, mobile_ram_gb)
497
+
498
+ # Batch Analysis Section
499
+ st.markdown("---")
500
+ st.header("๐Ÿ“Š Batch Analysis & Insights")
501
+
502
+ # Create enhanced batch table
503
+ df_display = df[["Full Name", "Laptop RAM", "Mobile RAM"]].copy()
504
+
505
+ # Add recommendations and performance tiers
506
+ laptop_recommendations = df["Laptop RAM"].apply(lambda x: recommend_llm(x)[0])
507
+ mobile_recommendations = df["Mobile RAM"].apply(lambda x: recommend_llm(x)[0])
508
+ laptop_tiers = df["Laptop RAM"].apply(lambda x: recommend_llm(x)[1])
509
+ mobile_tiers = df["Mobile RAM"].apply(lambda x: recommend_llm(x)[1])
510
+
511
+ df_display["Laptop LLM"] = laptop_recommendations
512
+ df_display["Mobile LLM"] = mobile_recommendations
513
+ df_display["Laptop Tier"] = laptop_tiers
514
+ df_display["Mobile Tier"] = mobile_tiers
515
+
516
+ # Filter based on sidebar selections
517
+ mask = (laptop_tiers.isin(performance_filter) | mobile_tiers.isin(performance_filter))
518
+ df_filtered = df_display[mask]
519
+
520
+ # Display filtered table
521
+ st.subheader(f"๐Ÿ“‹ Student Recommendations ({len(df_filtered)} students)")
522
+ st.dataframe(
523
+ df_filtered,
524
+ use_container_width=True,
525
+ column_config={
526
+ "Full Name": st.column_config.TextColumn("Student Name", width="medium"),
527
+ "Laptop RAM": st.column_config.TextColumn("Laptop RAM", width="small"),
528
+ "Mobile RAM": st.column_config.TextColumn("Mobile RAM", width="small"),
529
+ "Laptop LLM": st.column_config.TextColumn("Laptop Recommendation", width="large"),
530
+ "Mobile LLM": st.column_config.TextColumn("Mobile Recommendation", width="large"),
531
+ "Laptop Tier": st.column_config.TextColumn("L-Tier", width="small"),
532
+ "Mobile Tier": st.column_config.TextColumn("M-Tier", width="small"),
533
+ }
534
+ )
535
+
536
+ # Performance distribution chart
537
+ if len(df) > 1:
538
+ st.subheader("๐Ÿ“ˆ RAM Distribution Analysis")
539
+ fig = create_performance_chart(df)
540
+ st.plotly_chart(fig, use_container_width=True)
541
+
542
+ # Performance tier summary
543
+ st.subheader("๐ŸŽฏ Performance Tier Summary")
544
+ tier_col1, tier_col2 = st.columns(2)
545
+
546
+ with tier_col1:
547
+ st.markdown("**Laptop Performance Tiers:**")
548
+ laptop_tier_counts = laptop_tiers.value_counts()
549
+ for tier, count in laptop_tier_counts.items():
550
+ percentage = (count / len(laptop_tiers)) * 100
551
+ st.write(f"โ€ข {tier}: {count} students ({percentage:.1f}%)")
552
+
553
+ with tier_col2:
554
+ st.markdown("**Mobile Performance Tiers:**")
555
+ mobile_tier_counts = mobile_tiers.value_counts()
556
+ for tier, count in mobile_tier_counts.items():
557
+ percentage = (count / len(mobile_tier_counts)) * 100
558
+ st.write(f"โ€ข {tier}: {count} students ({percentage:.1f}%)")
559
+
560
+ # Model Explorer Section
561
+ st.markdown("---")
562
+ st.header("๐Ÿ” Popular Model Explorer")
563
+
564
+ explorer_col1, explorer_col2 = st.columns(2)
565
+
566
+ with explorer_col1:
567
+ selected_ram_range = st.selectbox(
568
+ "Select RAM range to explore models:",
569
+ ["โ‰ค2GB (Ultra Low)", "3-4GB (Low)", "5-6GB (Moderate-Low)",
570
+ "7-8GB (Moderate)", "9-16GB (Good)", "17-32GB (High)", ">32GB (Ultra High)"]
571
+ )
572
+
573
+ with explorer_col2:
574
+ selected_category = st.selectbox(
575
+ "Select model category:",
576
+ ["general", "code", "chat", "reasoning", "multimodal"]
577
+ )
578
+
579
+ # Map selection to database key
580
+ ram_mapping = {
581
+ "โ‰ค2GB (Ultra Low)": "ultra_low",
582
+ "3-4GB (Low)": "low",
583
+ "5-6GB (Moderate-Low)": "moderate_low",
584
+ "7-8GB (Moderate)": "moderate",
585
+ "9-16GB (Good)": "good",
586
+ "17-32GB (High)": "high",
587
+ ">32GB (Ultra High)": "ultra_high"
588
+ }
589
+
590
+ selected_ram_key = ram_mapping[selected_ram_range]
591
+ if selected_ram_key in LLM_DATABASE and selected_category in LLM_DATABASE[selected_ram_key]:
592
+ models = LLM_DATABASE[selected_ram_key][selected_category]
593
+
594
+ st.subheader(f"๐ŸŽฏ {selected_category.title()} Models for {selected_ram_range}")
595
+
596
+ # Display models in a detailed table
597
+ for model in models:
598
+ with st.container():
599
+ col1, col2, col3 = st.columns([3, 1, 3])
600
+ with col1:
601
+ st.markdown(f"### {model['name']}")
602
+ with col2:
603
+ st.markdown(f"**{model['size']}**")
604
+ st.caption("Download Size")
605
+ with col3:
606
+ st.markdown(f"*{model['description']}*")
607
+ # Add download suggestion
608
+ if "Llama" in model['name']:
609
+ st.caption("๐Ÿ”— Available on Hugging Face & Ollama")
610
+ elif "Mistral" in model['name']:
611
+ st.caption("๐Ÿ”— Available on Hugging Face & Mistral AI")
612
+ elif "Gemma" in model['name']:
613
+ st.caption("๐Ÿ”— Available on Hugging Face & Google")
614
+ else:
615
+ st.caption("๐Ÿ”— Available on Hugging Face")
616
+ st.markdown("---")
617
+ else:
618
+ st.info(f"No {selected_category} models available for {selected_ram_range}")
619
+
620
+ # Enhanced reference guide
621
+ with st.expander("๐Ÿ“˜ Model Guide & Download Information"):
622
+ st.markdown("""
623
+ ## ๐Ÿš€ Popular Models by Category
624
+
625
+ ### ๐ŸŽฏ **General Purpose Champions**
626
+ - **Llama-2 Series**: Meta's flagship models (7B, 13B, 70B)
627
+ - **Mistral Series**: Excellent efficiency and performance
628
+ - **Gemma**: Google's efficient models (2B, 7B)
629
+ - **Phi**: Microsoft's compact powerhouses
630
+
631
+ ### ๐Ÿ’ป **Code Specialists**
632
+ - **CodeLlama**: Meta's dedicated coding models
633
+ - **StarCoder**: BigCode's programming experts
634
+ - **WizardCoder**: Enhanced coding capabilities
635
+ - **DeepSeek-Coder**: Chinese tech giant's coder
636
+
637
+ ### ๐Ÿ’ฌ **Chat Optimized**
638
+ - **Vicuna**: UC Berkeley's ChatGPT alternative
639
+ - **Zephyr**: HuggingFace's chat specialist
640
+ - **OpenChat**: High-quality conversation models
641
+ - **Neural-Chat**: Intel-optimized chat models
642
+
643
+ ### ๐Ÿงฎ **Reasoning Masters**
644
+ - **WizardMath**: Mathematical problem solving
645
+ - **MetaMath**: Advanced arithmetic reasoning
646
+ - **Orca-2**: Microsoft's reasoning specialist
647
+ - **Goat**: Specialized arithmetic model
648
+
649
+ ### ๐Ÿ‘๏ธ **Multimodal Models**
650
+ - **LLaVA**: Large Language and Vision Assistant
651
+ - **MiniGPT-4**: Multimodal conversational AI
652
+
653
+ ## ๐Ÿ’พ Download Size Reference
654
+
655
+ | Model Size | FP16 | 8-bit | 4-bit | Use Case |
656
+ |------------|------|-------|-------|----------|
657
+ | **1-3B** | 2-6GB | 1-3GB | 0.5-1.5GB | Mobile, Edge |
658
+ | **7B** | 13GB | 7GB | 3.5GB | Desktop, Laptop |
659
+ | **13B** | 26GB | 13GB | 7GB | Workstation |
660
+ | **30-34B** | 60GB | 30GB | 15GB | Server, Cloud |
661
+ | **70B** | 140GB | 70GB | 35GB | High-end Server |
662
+
663
+ ## ๐Ÿ› ๏ธ Where to Download
664
+
665
+ ### **Primary Sources**
666
+ - **๐Ÿค— Hugging Face**: Largest repository with 400,000+ models
667
+ - **๐Ÿฆ™ Ollama**: Simple CLI tool for local deployment
668
+ - **๐Ÿ“ฆ LM Studio**: User-friendly GUI for model management
669
+
670
+ ### **Quantized Formats**
671
+ - **GGUF**: Best for CPU inference (llama.cpp)
672
+ - **GPTQ**: GPU-optimized quantization
673
+ - **AWQ**: Advanced weight quantization
674
+
675
+ ### **Download Tips**
676
+ - Use `git lfs` for large models from Hugging Face
677
+ - Consider bandwidth and storage before downloading
678
+ - Start with 4-bit quantized versions for testing
679
+ - Use `ollama pull model_name` for easiest setup
680
+
681
+ ## ๐Ÿ”ง Optimization Strategies
682
+
683
+ ### **Memory Reduction**
684
+ - **4-bit quantization**: 75% memory reduction
685
+ - **8-bit quantization**: 50% memory reduction
686
+ - **CPU offloading**: Use system RAM for overflow
687
+
688
+ ### **Speed Optimization**
689
+ - **GPU acceleration**: CUDA, ROCm, Metal
690
+ - **Batch processing**: Process multiple requests
691
+ - **Context caching**: Reuse computations
692
+ """)
693
+
694
+ # Footer with updated resources
695
+ st.markdown("---")
696
+ st.markdown("""
697
+ ### ๐Ÿ”— Essential Download & Deployment Tools
698
+ **๐Ÿ“ฆ Easy Model Deployment:**
699
+ - [**Ollama**](https://ollama.ai/) โ€“ `curl -fsSL https://ollama.ai/install.sh | sh`
700
+ - [**LM Studio**](https://lmstudio.ai/) โ€“ Drag-and-drop GUI for running models locally
701
+ - [**GPT4All**](https://gpt4all.io/) โ€“ Cross-platform desktop app for local LLMs
702
+ **๐Ÿค— Model Repositories:**
703
+ - [**Hugging Face Hub**](https://huggingface.co/models) โ€“ Filter by model size, task, and license
704
+ - [**TheBloke's Quantizations**](https://huggingface.co/TheBloke) โ€“ Pre-quantized models in GGUF/GPTQ format
705
+ - [**Awesome LLM**](https://github.com/Hannibal046/Awesome-LLMs) โ€“ Curated list of models and resources
706
+ ---
707
+ """)
708
+
709
+ with tab2:
710
+ run_app2()
711
+
712
+
713
+ with tab3:
714
+ st.title("๐Ÿง  LLM Training Time & Cost Estimator")
715
+
716
+ # Load and prepare model list
717
+ model_list = get_all_models_from_database(LLM_DATABASE)
718
+ dropdown_options = [m["display"] for m in model_list]
719
+
720
+ # Dropdown menu
721
+ selected_display = st.selectbox("Select a Model", dropdown_options)
722
+ selected_model = next((m for m in model_list if m["display"] == selected_display), None)
723
+
724
+ # Convert size to params in billions (very rough approx.)
725
+ if "GB" in selected_model["size"]:
726
+ size_val = float(selected_model["size"].replace("GB", "").strip())
727
+ elif "MB" in selected_model["size"]:
728
+ size_val = float(selected_model["size"].replace("MB", "").strip()) / 1024
729
+ else:
730
+ size_val = 1.0 # default
731
+
732
+ params = size_val
733
+ tokens = st.number_input("Training Tokens (B)", min_value=1.0, value=300.0)
734
+
735
+ # Select compute method
736
+ gpu_choice = st.radio("Choose Compute Source", ["Manual TFLOPs", "A100", "H100", "Exo"])
737
+
738
+ if gpu_choice == "Manual TFLOPs":
739
+ teraflops = st.number_input("TFLOPs/s", min_value=1.0, value=100.0)
740
+ cost_per_tflop_hr = st.number_input("โ‚น Cost per TFLOP-Hour", min_value=0.0, value=0.0)
741
+ elif gpu_choice == "Exo":
742
+ exo_flops = st.number_input("TFLOPs from Exo", min_value=1.0)
743
+ teraflops = get_gpu_teraflops("Exo", exo_flops)
744
+ cost_per_tflop_hr = st.number_input("โ‚น Cost per TFLOP-Hour (Exo)", min_value=0.0, value=0.0)
745
+ else:
746
+ teraflops = get_gpu_teraflops(gpu_choice)
747
+ cost_str = selected_model.get(f"cost_{gpu_choice.lower()}", "โ‚น0").replace("โ‚น", "").replace(",", "")
748
+ cost_per_tflop_hr = float(cost_str) / 100 # rough est: โ‚น per 100 TFLOP-hr
749
+ st.info(f"{gpu_choice}: โ‚น{cost_per_tflop_hr:.2f} per TFLOP-Hour")
750
 
751
+ # Estimate
752
+ if st.button("Estimate Time & Cost"):
753
+ result = estimate_training_time_and_cost(params, tokens, teraflops, cost_per_tflop_hr)
754
+ st.success(f"""
755
+ ๐Ÿ“Š **Model:** {selected_model['name']}
756
+ ๐Ÿง  **Params (est):** {params:.2f}B
757
+ ๐Ÿ”ข **FLOPs Required:** {result['flops_required']:.2e}
758
+ โฑ๏ธ **Time:** {result['time_hours']:.2f} hrs / {result['time_days']:.2f} days
759
+ ๐Ÿ’ธ **Cost:** โ‚น{result['total_cost']:.2f}
760
+ โš™๏ธ **Compute Used:** {teraflops} TFLOPs/s
761
+ """)