fbaldassarri commited on
Commit
99ed203
·
1 Parent(s): c356b08

Initial Commit

Browse files
Files changed (3) hide show
  1. README.md +4 -4
  2. app.py +675 -0
  3. requirements.txt +7 -0
README.md CHANGED
@@ -1,14 +1,14 @@
1
  ---
2
  title: Fbaldassarri Repository Eval
3
- emoji: 🏢
4
- colorFrom: blue
5
- colorTo: red
6
  sdk: streamlit
7
  sdk_version: 1.44.1
8
  app_file: app.py
9
  pinned: false
10
  license: apache-2.0
11
- short_description: fbaldassarri's Repositories Evaluation Chart
12
  ---
13
 
14
  Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
1
  ---
2
  title: Fbaldassarri Repository Eval
3
+ emoji: 🦀
4
+ colorFrom: indigo
5
+ colorTo: green
6
  sdk: streamlit
7
  sdk_version: 1.44.1
8
  app_file: app.py
9
  pinned: false
10
  license: apache-2.0
11
+ short_description: fbaldassarri-repository-eval
12
  ---
13
 
14
  Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
app.py ADDED
@@ -0,0 +1,675 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import pandas as pd
3
+ import plotly.express as px
4
+ import plotly.graph_objects as go
5
+ from huggingface_hub import HfApi, model_info
6
+ import time
7
+ import re
8
+ import os
9
+ import json
10
+ import signal
11
+ from contextlib import contextmanager
12
+ import numpy as np
13
+ from functools import partial
14
+ import gc
15
+ import sys
16
+
17
+ # Set page configuration
18
+ st.set_page_config(
19
+ page_title="Quantized Model Comparison",
20
+ page_icon="📊",
21
+ layout="wide",
22
+ initial_sidebar_state="expanded"
23
+ )
24
+
25
+ # Define a timeout context manager for safety on CPU-only environments
26
+ @contextmanager
27
+ def timeout(time_seconds=60):
28
+ def signal_handler(signum, frame):
29
+ raise TimeoutError("Timed out!")
30
+
31
+ signal.signal(signal.SIGALRM, signal_handler)
32
+ signal.alarm(time_seconds)
33
+ try:
34
+ yield
35
+ finally:
36
+ signal.alarm(0)
37
+
38
+ # Quantization keywords for filtering
39
+ QUANTIZATION_KEYWORDS = [
40
+ "auto_round", "auto-round", "autoround", "intel",
41
+ "autogptq", "auto_gptq", "auto-gptq",
42
+ "autoawq", "auto_awq", "auto-awq"
43
+ ]
44
+
45
+ # Cache API results
46
+ @st.cache_data(ttl=3600) # Cache for 1 hour
47
+ def get_user_models(username):
48
+ api = HfApi()
49
+ try:
50
+ models = list(api.list_models(author=username))
51
+ return models
52
+ except Exception as e:
53
+ st.error(f"Error fetching models: {str(e)}")
54
+ return []
55
+
56
+ # Get model metadata without loading the model
57
+ @st.cache_data(ttl=3600)
58
+ def get_model_metadata(model_id):
59
+ try:
60
+ api = HfApi()
61
+ model_meta = model_info(repo_id=model_id)
62
+ return model_meta
63
+ except Exception as e:
64
+ st.warning(f"Failed to fetch metadata for {model_id}: {str(e)}")
65
+ return None
66
+
67
+ # Function to check if a model matches the quantization keywords
68
+ def model_matches_keywords(model_id):
69
+ model_name = model_id.lower()
70
+ return any(keyword.lower() in model_name for keyword in QUANTIZATION_KEYWORDS)
71
+
72
+ # Function to extract quantization method from model name
73
+ def extract_quantization_method(model_id):
74
+ model_name = model_id.lower()
75
+
76
+ if any(kw in model_name for kw in ["auto_round", "auto-round", "autoround", "intel"]):
77
+ return "Intel AutoRound"
78
+ elif any(kw in model_name for kw in ["autogptq", "auto_gptq", "auto-gptq"]):
79
+ return "AutoGPTQ"
80
+ elif any(kw in model_name for kw in ["autoawq", "auto_awq", "auto-awq"]):
81
+ return "AutoAWQ"
82
+ else:
83
+ return "Unknown"
84
+
85
+ # Function to extract model metadata from name and repo
86
+ def extract_model_metadata(model_id, repo_metadata=None):
87
+ model_name = model_id.split("/")[-1]
88
+
89
+ # Extract quantization method
90
+ quant_method = extract_quantization_method(model_id)
91
+
92
+ # Extract precision
93
+ precision = "Unknown"
94
+ if "int8" in model_name.lower():
95
+ precision = "INT8"
96
+ elif "int4" in model_name.lower():
97
+ precision = "INT4"
98
+ elif "fp16" in model_name.lower():
99
+ precision = "FP16"
100
+ elif "fp32" in model_name.lower():
101
+ precision = "FP32"
102
+
103
+ # Extract group size
104
+ group_size = None
105
+ gs_match = re.search(r'gs(\d+)', model_name.lower())
106
+ if gs_match:
107
+ group_size = int(gs_match.group(1))
108
+
109
+ # Extract model size if available
110
+ size_patterns = [r'(\d+(\.\d+)?)b', r'(\d+(\.\d+)?)m']
111
+ model_size = None
112
+
113
+ for pattern in size_patterns:
114
+ match = re.search(pattern, model_name.lower())
115
+ if match:
116
+ size = float(match.group(1))
117
+ unit = match.group(0)[-1].lower()
118
+ if unit == 'b':
119
+ model_size = size
120
+ elif unit == 'm':
121
+ model_size = size / 1000 # Convert to billions
122
+ break
123
+
124
+ # Extract base model name
125
+ base_model = re.sub(r'[-_]?(auto_?round|auto_?gptq|auto_?awq|intel)[-_]?', '', model_name, flags=re.IGNORECASE)
126
+ base_model = re.sub(r'[-_]?(int4|int8|fp16|fp32)[-_]?', '', base_model, flags=re.IGNORECASE)
127
+ base_model = re.sub(r'[-_]?gs\d+[-_]?', '', base_model, flags=re.IGNORECASE)
128
+
129
+ # Add repository metadata if available
130
+ downloads = None
131
+ likes = None
132
+ last_modified = None
133
+ library_name = None
134
+ model_tags = []
135
+
136
+ if repo_metadata:
137
+ downloads = repo_metadata.downloads
138
+ likes = repo_metadata.likes
139
+ last_modified = repo_metadata.last_modified
140
+
141
+ # Try to determine library from tags
142
+ if hasattr(repo_metadata, "tags") and repo_metadata.tags:
143
+ model_tags = repo_metadata.tags
144
+
145
+ library_mapping = {
146
+ "autoawq": "AutoAWQ",
147
+ "gptq": "AutoGPTQ",
148
+ "autogptq": "AutoGPTQ",
149
+ "auto-gptq": "AutoGPTQ",
150
+ "awq": "AutoAWQ",
151
+ "quantization": "Quantized",
152
+ "quantized": "Quantized",
153
+ "intel": "Intel",
154
+ "auto-round": "Intel AutoRound",
155
+ "autoround": "Intel AutoRound"
156
+ }
157
+
158
+ for tag in model_tags:
159
+ if tag.lower() in library_mapping:
160
+ library_name = library_mapping[tag.lower()]
161
+ break
162
+
163
+ # If we couldn't determine the library from tags, use the name-based method
164
+ if not library_name:
165
+ library_name = quant_method
166
+
167
+ return {
168
+ "model_name": model_name,
169
+ "base_model": base_model,
170
+ "quant_method": quant_method,
171
+ "precision": precision,
172
+ "group_size": group_size,
173
+ "model_size": model_size,
174
+ "downloads": downloads,
175
+ "likes": likes,
176
+ "last_modified": last_modified,
177
+ "library": library_name,
178
+ "tags": model_tags
179
+ }
180
+
181
+ # Get model stats without loading the entire model
182
+ @st.cache_data(ttl=3600)
183
+ def get_model_stats(model_id):
184
+ try:
185
+ api = HfApi()
186
+ sibling_files = api.list_repo_files(repo_id=model_id)
187
+
188
+ # Look for config files
189
+ config_file = None
190
+ for file in sibling_files:
191
+ if file.endswith("config.json") or file == "config.json":
192
+ config_file = file
193
+ break
194
+
195
+ if config_file:
196
+ # Download just the config file
197
+ config_content = api.hf_hub_download(repo_id=model_id, filename=config_file)
198
+
199
+ with open(config_content, 'r') as f:
200
+ config = json.load(f)
201
+
202
+ # Extract useful info
203
+ stats = {}
204
+
205
+ # Get hidden size
206
+ if "hidden_size" in config:
207
+ stats["hidden_size"] = config["hidden_size"]
208
+
209
+ # Get vocab size
210
+ if "vocab_size" in config:
211
+ stats["vocab_size"] = config["vocab_size"]
212
+
213
+ # Get number of layers/blocks
214
+ for key in ["num_hidden_layers", "n_layer", "num_layers"]:
215
+ if key in config:
216
+ stats["num_layers"] = config[key]
217
+ break
218
+
219
+ # Get attention details
220
+ if "num_attention_heads" in config:
221
+ stats["num_attention_heads"] = config["num_attention_heads"]
222
+
223
+ # Get sequence length
224
+ for key in ["max_position_embeddings", "n_positions", "max_seq_len"]:
225
+ if key in config:
226
+ stats["max_seq_len"] = config[key]
227
+ break
228
+
229
+ return stats
230
+
231
+ return {}
232
+ except Exception as e:
233
+ st.warning(f"Failed to fetch stats for {model_id}: {str(e)}")
234
+ return {}
235
+
236
+ # Function to estimate model size (without loading the model)
237
+ def estimate_model_size_from_files(model_id):
238
+ try:
239
+ api = HfApi()
240
+ sibling_files = list(api.list_repo_files(repo_id=model_id))
241
+
242
+ # Look for binary model files
243
+ model_files = [f for f in sibling_files if f.endswith('.bin') or f.endswith('.safetensors')]
244
+
245
+ total_size = 0
246
+ for file in model_files:
247
+ file_info = api.hf_hub_file_info(repo_id=model_id, filename=file)
248
+ total_size += file_info.size
249
+
250
+ # Convert to GB
251
+ size_gb = total_size / (1024 ** 3)
252
+ return size_gb
253
+ except Exception as e:
254
+ st.warning(f"Failed to estimate size for {model_id}: {str(e)}")
255
+ return None
256
+
257
+ # Main function
258
+ def main():
259
+ st.title("🔍 Quantized Model Comparison Tool")
260
+ st.write("Compare Intel AutoRound, AutoGPTQ, and AutoAWQ models (optimized for free tier Space)")
261
+
262
+ # Sidebar for configuration
263
+ st.sidebar.header("Configuration")
264
+ username = st.sidebar.text_input("HuggingFace Username", "fbaldassarri")
265
+
266
+ # Fetch all models
267
+ with st.spinner("Fetching models..."):
268
+ all_models = get_user_models(username)
269
+ all_model_ids = [model.id for model in all_models]
270
+
271
+ # Filter models with quantization keywords
272
+ quantized_model_ids = [model_id for model_id in all_model_ids if model_matches_keywords(model_id)]
273
+
274
+ st.sidebar.write(f"Found {len(quantized_model_ids)} quantized models out of {len(all_model_ids)} total models")
275
+
276
+ # Quantization method filtering
277
+ quant_methods = ["Intel AutoRound", "AutoGPTQ", "AutoAWQ"]
278
+ selected_quant_methods = st.sidebar.multiselect(
279
+ "Filter by quantization method",
280
+ options=quant_methods,
281
+ default=quant_methods
282
+ )
283
+
284
+ # Additional filtering
285
+ additional_filter = st.sidebar.text_input("Additional model name filter", "")
286
+
287
+ # Apply filters
288
+ filtered_models = []
289
+ for model_id in quantized_model_ids:
290
+ quant_method = extract_quantization_method(model_id)
291
+ if quant_method in selected_quant_methods:
292
+ if additional_filter.lower() in model_id.lower() or not additional_filter:
293
+ filtered_models.append(model_id)
294
+
295
+ # Group models by base model name
296
+ model_groups = {}
297
+ for model_id in filtered_models:
298
+ metadata = extract_model_metadata(model_id)
299
+ base_model = metadata["base_model"]
300
+ if base_model not in model_groups:
301
+ model_groups[base_model] = []
302
+ model_groups[base_model].append(model_id)
303
+
304
+ # Select base model group
305
+ base_model_options = list(model_groups.keys())
306
+ base_model_options.sort()
307
+
308
+ selected_base_model = st.sidebar.selectbox(
309
+ "Select base model to compare",
310
+ options=["All"] + base_model_options
311
+ )
312
+
313
+ # Final model selection
314
+ if selected_base_model == "All":
315
+ model_selection_options = filtered_models
316
+ else:
317
+ model_selection_options = model_groups[selected_base_model]
318
+
319
+ # Limit selection to prevent resource issues
320
+ max_models_comparison = st.sidebar.slider("Maximum models to compare", 2, 10, 5)
321
+ default_models = model_selection_options[:min(max_models_comparison, len(model_selection_options))]
322
+
323
+ selected_models = st.sidebar.multiselect(
324
+ "Select models to compare",
325
+ options=model_selection_options,
326
+ default=default_models
327
+ )
328
+
329
+ # Limit selection if exceeded
330
+ if len(selected_models) > max_models_comparison:
331
+ st.warning(f"⚠️ Limited to {max_models_comparison} models for comparison (CPU constraints)")
332
+ selected_models = selected_models[:max_models_comparison]
333
+
334
+ # Comparison method
335
+ st.sidebar.header("Comparison Method")
336
+
337
+ compare_method = st.sidebar.radio(
338
+ "Choose comparison method",
339
+ ["Metadata Comparison Only", "Metadata + Estimated Size"]
340
+ )
341
+
342
+ if st.button("Run Comparison") and selected_models:
343
+ # Progress tracking
344
+ progress_bar = st.progress(0)
345
+ status_text = st.empty()
346
+
347
+ results = []
348
+
349
+ # Analyze each model
350
+ for i, model_id in enumerate(selected_models):
351
+ status_text.text(f"Analyzing {model_id} ({i+1}/{len(selected_models)})")
352
+
353
+ # Get repository metadata
354
+ repo_meta = get_model_metadata(model_id)
355
+
356
+ # Extract metadata
357
+ metadata = extract_model_metadata(model_id, repo_meta)
358
+ model_result = metadata.copy()
359
+
360
+ # Get model architecture stats
361
+ model_stats = get_model_stats(model_id)
362
+ model_result.update(model_stats)
363
+
364
+ # Get estimated size if needed
365
+ if compare_method == "Metadata + Estimated Size":
366
+ with st.spinner(f"Estimating size for {model_id}..."):
367
+ try:
368
+ estimated_size = estimate_model_size_from_files(model_id)
369
+ model_result["estimated_size_gb"] = estimated_size
370
+ except Exception as e:
371
+ st.warning(f"Size estimation failed for {model_id}: {str(e)}")
372
+
373
+ # Add to results
374
+ results.append(model_result)
375
+
376
+ # Update progress
377
+ progress_bar.progress((i + 1) / len(selected_models))
378
+
379
+ # Clear progress indicators
380
+ progress_bar.empty()
381
+ status_text.empty()
382
+
383
+ # Display results
384
+ if results:
385
+ # Convert to DataFrame
386
+ results_df = pd.DataFrame(results)
387
+
388
+ # Add formatting for dates if present
389
+ if "last_modified" in results_df.columns:
390
+ results_df["last_modified"] = pd.to_datetime(results_df["last_modified"])
391
+ results_df["days_since_update"] = (pd.Timestamp.now() - results_df["last_modified"]).dt.days
392
+
393
+ # Sort by quantization method and model name
394
+ if "quant_method" in results_df.columns and "model_name" in results_df.columns:
395
+ results_df = results_df.sort_values(["quant_method", "model_name"])
396
+
397
+ # Display results in tabs
398
+ results_tabs = st.tabs(["Model Comparison", "Model Details", "Visualizations"])
399
+
400
+ with results_tabs[0]:
401
+ st.subheader("Model Comparison")
402
+
403
+ # Define columns to display
404
+ basic_cols = ["model_name", "quant_method", "precision", "group_size"]
405
+
406
+ size_cols = []
407
+ if "model_size" in results_df.columns:
408
+ size_cols.append("model_size")
409
+ if "estimated_size_gb" in results_df.columns:
410
+ size_cols.append("estimated_size_gb")
411
+
412
+ arch_cols = []
413
+ for col in ["num_layers", "hidden_size", "num_attention_heads", "max_seq_len"]:
414
+ if col in results_df.columns:
415
+ arch_cols.append(col)
416
+
417
+ stats_cols = []
418
+ for col in ["downloads", "likes", "days_since_update"]:
419
+ if col in results_df.columns:
420
+ stats_cols.append(col)
421
+
422
+ # Create display dataframe
423
+ display_cols = basic_cols + size_cols + arch_cols + stats_cols
424
+ display_df = results_df[display_cols].copy()
425
+
426
+ # Format columns
427
+ if "estimated_size_gb" in display_df.columns:
428
+ display_df["estimated_size_gb"] = display_df["estimated_size_gb"].apply(
429
+ lambda x: f"{x:.2f} GB" if pd.notna(x) else "Unknown"
430
+ )
431
+
432
+ if "model_size" in display_df.columns:
433
+ display_df["model_size"] = display_df["model_size"].apply(
434
+ lambda x: f"{x:.2f}B" if pd.notna(x) else "Unknown"
435
+ )
436
+
437
+ # Display the table
438
+ st.dataframe(display_df)
439
+
440
+ with results_tabs[1]:
441
+ st.subheader("Detailed Model Information")
442
+
443
+ # Create tabs for each model
444
+ model_tabs = st.tabs([m.split("/")[-1] for m in selected_models])
445
+
446
+ for i, model_id in enumerate(selected_models):
447
+ with model_tabs[i]:
448
+ # Get the model row
449
+ model_row = results_df[results_df["model_name"] == model_id.split("/")[-1]].iloc[0]
450
+
451
+ # Display model info in columns
452
+ col1, col2 = st.columns(2)
453
+
454
+ with col1:
455
+ st.markdown("#### Model Information")
456
+ st.markdown(f"**Repository:** {model_id}")
457
+ st.markdown(f"**Base Model:** {model_row.get('base_model', 'Unknown')}")
458
+ st.markdown(f"**Quantization:** {model_row.get('quant_method', 'Unknown')}")
459
+ st.markdown(f"**Precision:** {model_row.get('precision', 'Unknown')}")
460
+
461
+ if "group_size" in model_row and pd.notna(model_row["group_size"]):
462
+ st.markdown(f"**Group Size:** {int(model_row['group_size'])}")
463
+
464
+ if "estimated_size_gb" in model_row and pd.notna(model_row["estimated_size_gb"]):
465
+ st.markdown(f"**Model Size:** {model_row['estimated_size_gb']:.2f} GB")
466
+
467
+ with col2:
468
+ st.markdown("#### Architecture Details")
469
+
470
+ for col in ["hidden_size", "num_layers", "num_attention_heads", "max_seq_len", "vocab_size"]:
471
+ if col in model_row and pd.notna(model_row[col]):
472
+ st.markdown(f"**{col.replace('_', ' ').title()}:** {int(model_row[col])}")
473
+
474
+ # Repository stats
475
+ st.markdown("#### Repository Statistics")
476
+ stat_cols = st.columns(3)
477
+
478
+ with stat_cols[0]:
479
+ if "downloads" in model_row and pd.notna(model_row["downloads"]):
480
+ st.metric("Downloads", f"{int(model_row['downloads']):,}")
481
+
482
+ with stat_cols[1]:
483
+ if "likes" in model_row and pd.notna(model_row["likes"]):
484
+ st.metric("Likes", f"{int(model_row['likes']):,}")
485
+
486
+ with stat_cols[2]:
487
+ if "days_since_update" in model_row and pd.notna(model_row["days_since_update"]):
488
+ st.metric("Days Since Update", f"{int(model_row['days_since_update'])}")
489
+
490
+ # Tags
491
+ if "tags" in model_row and model_row["tags"]:
492
+ st.markdown("#### Model Tags")
493
+ tags_html = " ".join([f"<span style='background-color: #eee; padding: 0.2rem 0.5rem; border-radius: 0.5rem; margin-right: 0.5rem;'>{tag}</span>" for tag in model_row["tags"]])
494
+ st.markdown(tags_html, unsafe_allow_html=True)
495
+
496
+ # Add a link to the model
497
+ st.markdown(f"[View on HuggingFace 🤗]({'https://huggingface.co/' + model_id})")
498
+
499
+ with results_tabs[2]:
500
+ st.subheader("Visualizations")
501
+
502
+ viz_tabs = st.tabs(["Quantization Methods", "Model Architecture", "Repository Stats"])
503
+
504
+ with viz_tabs[0]:
505
+ # Quantization method distribution
506
+ if "quant_method" in results_df.columns:
507
+ method_counts = results_df["quant_method"].value_counts().reset_index()
508
+ method_counts.columns = ["Method", "Count"]
509
+
510
+ fig = px.pie(
511
+ method_counts,
512
+ names="Method",
513
+ values="Count",
514
+ title="Distribution of Quantization Methods",
515
+ color="Method",
516
+ color_discrete_map={
517
+ "Intel AutoRound": "#0071c5",
518
+ "AutoGPTQ": "#ff4b4b",
519
+ "AutoAWQ": "#1e88e5"
520
+ }
521
+ )
522
+ st.plotly_chart(fig, use_container_width=True)
523
+
524
+ # Precision distribution
525
+ if "precision" in results_df.columns:
526
+ precision_counts = results_df["precision"].value_counts().reset_index()
527
+ precision_counts.columns = ["Precision", "Count"]
528
+
529
+ fig = px.bar(
530
+ precision_counts,
531
+ x="Precision",
532
+ y="Count",
533
+ title="Distribution of Precision Formats",
534
+ color="Precision"
535
+ )
536
+ st.plotly_chart(fig, use_container_width=True)
537
+
538
+ # Group size distribution (if available)
539
+ if "group_size" in results_df.columns and results_df["group_size"].notna().any():
540
+ valid_gs_data = results_df[results_df["group_size"].notna()]
541
+ gs_counts = valid_gs_data["group_size"].value_counts().reset_index()
542
+ gs_counts.columns = ["Group Size", "Count"]
543
+
544
+ fig = px.bar(
545
+ gs_counts,
546
+ x="Group Size",
547
+ y="Count",
548
+ title="Distribution of Group Sizes",
549
+ color="Group Size"
550
+ )
551
+ st.plotly_chart(fig, use_container_width=True)
552
+
553
+ with viz_tabs[1]:
554
+ # Model size comparison
555
+ if "estimated_size_gb" in results_df.columns and results_df["estimated_size_gb"].notna().any():
556
+ valid_size_data = results_df[results_df["estimated_size_gb"].notna()].sort_values("estimated_size_gb")
557
+
558
+ fig = px.bar(
559
+ valid_size_data,
560
+ x="model_name",
561
+ y="estimated_size_gb",
562
+ color="quant_method",
563
+ title="Model Size Comparison (GB)",
564
+ labels={"estimated_size_gb": "Size (GB)", "model_name": "Model", "quant_method": "Method"}
565
+ )
566
+ fig.update_layout(xaxis_tickangle=-45)
567
+ st.plotly_chart(fig, use_container_width=True)
568
+
569
+ # Architecture comparison
570
+ for arch_col in ["num_layers", "hidden_size", "num_attention_heads"]:
571
+ if arch_col in results_df.columns and results_df[arch_col].notna().any():
572
+ valid_data = results_df[results_df[arch_col].notna()].sort_values(arch_col)
573
+
574
+ fig = px.bar(
575
+ valid_data,
576
+ x="model_name",
577
+ y=arch_col,
578
+ color="quant_method",
579
+ title=f"{arch_col.replace('_', ' ').title()} Comparison",
580
+ labels={arch_col: arch_col.replace('_', ' ').title(), "model_name": "Model", "quant_method": "Method"}
581
+ )
582
+ fig.update_layout(xaxis_tickangle=-45)
583
+ st.plotly_chart(fig, use_container_width=True)
584
+
585
+ with viz_tabs[2]:
586
+ # Downloads comparison
587
+ if "downloads" in results_df.columns and results_df["downloads"].notna().any():
588
+ valid_data = results_df[results_df["downloads"].notna()].sort_values("downloads", ascending=False)
589
+
590
+ fig = px.bar(
591
+ valid_data,
592
+ x="model_name",
593
+ y="downloads",
594
+ color="quant_method",
595
+ title="Downloads Comparison",
596
+ labels={"downloads": "Downloads", "model_name": "Model", "quant_method": "Method"}
597
+ )
598
+ fig.update_layout(xaxis_tickangle=-45)
599
+ st.plotly_chart(fig, use_container_width=True)
600
+
601
+ # Likes comparison
602
+ if "likes" in results_df.columns and results_df["likes"].notna().any():
603
+ valid_data = results_df[results_df["likes"].notna()].sort_values("likes", ascending=False)
604
+
605
+ fig = px.bar(
606
+ valid_data,
607
+ x="model_name",
608
+ y="likes",
609
+ color="quant_method",
610
+ title="Likes Comparison",
611
+ labels={"likes": "Likes", "model_name": "Model", "quant_method": "Method"}
612
+ )
613
+ fig.update_layout(xaxis_tickangle=-45)
614
+ st.plotly_chart(fig, use_container_width=True)
615
+
616
+ # Last updated comparison
617
+ if "days_since_update" in results_df.columns and results_df["days_since_update"].notna().any():
618
+ valid_data = results_df[results_df["days_since_update"].notna()].sort_values("days_since_update")
619
+
620
+ fig = px.bar(
621
+ valid_data,
622
+ x="model_name",
623
+ y="days_since_update",
624
+ color="quant_method",
625
+ title="Days Since Last Update",
626
+ labels={"days_since_update": "Days", "model_name": "Model", "quant_method": "Method"}
627
+ )
628
+ fig.update_layout(xaxis_tickangle=-45)
629
+ st.plotly_chart(fig, use_container_width=True)
630
+
631
+ # Export options
632
+ st.subheader("Export Results")
633
+
634
+ # Prepare download data
635
+ csv_data = results_df.to_csv(index=False)
636
+
637
+ st.download_button(
638
+ "Download Results as CSV",
639
+ data=csv_data,
640
+ file_name=f"quantized_model_comparison_{username}_{time.strftime('%Y%m%d_%H%M')}.csv",
641
+ mime="text/csv"
642
+ )
643
+ else:
644
+ st.warning("No results were obtained. Please check for errors and try again.")
645
+
646
+ # Show instructions if no comparison run
647
+ if not st.session_state.get('comparison_run', False):
648
+ st.info("""
649
+ ## CPU-Optimized Model Comparison
650
+
651
+ This tool is designed to compare your quantized models without requiring GPU resources, making it suitable for the free tier HuggingFace Space.
652
+
653
+ ### Features:
654
+
655
+ - **Metadata Analysis**: Compare model architectures without loading models
656
+ - **Repository Stats**: View downloads, likes, and update frequency
657
+ - **Visualization**: Compare models across multiple dimensions
658
+ - **Filtering**: Focus on specific quantization methods or model families
659
+
660
+ ### Supported Quantization Methods:
661
+
662
+ - **Intel AutoRound**: Intel's quantization solution
663
+ - **AutoGPTQ**: Automatic GPTQ quantization
664
+ - **AutoAWQ**: Activation-aware weight quantization
665
+
666
+ ### Instructions:
667
+
668
+ 1. Select models using the sidebar filters
669
+ 2. Click "Run Comparison" to analyze without loading full models
670
+ 3. View results in the tabs and charts
671
+ 4. Download results as CSV for further analysis
672
+ """)
673
+
674
+ if __name__ == "__main__":
675
+ main()
requirements.txt ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ streamlit
2
+ huggingface_hub
3
+ evaluate
4
+ pandas
5
+ plotly
6
+ torch
7
+ transformers