darkc0de commited on
Commit
e0c9a91
Β·
verified Β·
1 Parent(s): 8057f5b

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +76 -55
app.py CHANGED
@@ -1,6 +1,7 @@
1
  import gradio as gr
2
  import pandas as pd
3
  from huggingface_hub import hf_hub_download
 
4
 
5
  # --- Constants ---
6
  REPO_ID = "DontPlanToEnd/UGI-Leaderboard"
@@ -14,7 +15,7 @@ def make_clickable_model(model_name, link):
14
 
15
  def get_data():
16
  """
17
- Downloads, processes, and returns the leaderboard data + status message.
18
  """
19
  print("πŸ”„ Starting download...")
20
  try:
@@ -26,19 +27,22 @@ def get_data():
26
  df = pd.read_csv(file_path, encoding='utf-8-sig')
27
  df.columns = df.columns.str.strip()
28
 
29
- # 3. Fuzzy Column Matching (Robust against emojis)
30
  def get_col(keyword):
31
  matches = [c for c in df.columns if keyword.lower() in c.lower()]
32
  return matches[0] if matches else None
33
 
34
- # Try to find columns even if emojis are messed up
35
- model_col = get_col("author") or get_col("model")
36
- link_col = get_col("link")
37
- ugi_col = get_col("ugi")
38
- natint_col = get_col("natint")
39
- w10_col = get_col("w/10")
 
 
 
40
 
41
- # 4. Check if we found everything
42
  if not all([model_col, ugi_col, natint_col, w10_col]):
43
  missing = []
44
  if not model_col: missing.append("Model")
@@ -47,38 +51,43 @@ def get_data():
47
  if not w10_col: missing.append("W/10")
48
  return pd.DataFrame(), f"❌ Error: Could not find columns: {', '.join(missing)}. Found: {list(df.columns)}"
49
 
50
- # 5. Clean Numeric Data
 
 
 
 
 
 
 
 
 
 
 
 
 
51
  for col in [ugi_col, natint_col, w10_col]:
52
  df[col] = pd.to_numeric(df[col], errors='coerce').fillna(0)
53
 
54
- # 6. Calculate UGI Index
55
- # Formula: (UGI + NatInt) * (W/10)^2
56
  df['UGI Index'] = (df[ugi_col] + df[natint_col]) * (df[w10_col] ** 2)
57
  df['UGI Index'] = df['UGI Index'].round(2)
58
 
59
- # 7. Format Links
60
- if link_col:
61
- df[model_col] = df.apply(lambda x: make_clickable_model(x[model_col], x[link_col]), axis=1)
62
-
63
  # 8. Sort and Rank
64
  df = df.sort_values(by='UGI Index', ascending=False)
65
  df.insert(0, 'Rank', range(1, len(df) + 1))
66
 
67
- # 9. Renaming for display
68
- final_cols = {
69
- model_col: 'Model',
70
- ugi_col: 'UGI',
71
- natint_col: 'NatInt',
72
- w10_col: 'W/10'
73
- }
74
- df = df.rename(columns=final_cols)
75
-
76
- # 10. Select Columns to Display
77
- display_cols = ['Rank', 'Model', 'UGI Index', 'UGI', 'NatInt', 'W/10']
78
-
79
- final_df = df[display_cols]
80
-
81
- return final_df, f"βœ… Successfully loaded {len(final_df)} models."
82
 
83
  except Exception as e:
84
  print(f"Error: {e}")
@@ -87,23 +96,32 @@ def get_data():
87
  # Global cache for search to use
88
  CACHED_DF = pd.DataFrame()
89
 
90
- def app_load():
91
- """Called when app starts."""
92
- global CACHED_DF
93
- df, status = get_data()
94
- CACHED_DF = df
95
- return df, status
96
-
97
- def search(query):
98
- """Filters the cached dataframe."""
99
  if CACHED_DF.empty:
100
  return CACHED_DF
101
 
102
- if not query:
103
- return CACHED_DF
 
 
 
 
 
 
 
 
104
 
105
- # Filter
106
- return CACHED_DF[CACHED_DF['Model'].astype(str).str.contains(query, case=False, na=False)]
 
 
 
 
 
 
 
 
107
 
108
  # --- UI ---
109
  custom_css = """
@@ -114,29 +132,31 @@ footer {visibility: hidden}
114
  with gr.Blocks(css=custom_css, title="UGI Index Leaderboard") as demo:
115
  gr.Markdown("# πŸ† UGI Index")
116
 
117
- # --- Updated Note Explaining the Squared W/10 ---
118
  gr.Markdown("""
119
  ### ℹ️ How is the Score Calculated?
120
- The **UGI Index** ranks LLMs based on data from [DontPlanToEnd/UGI-Leaderboard](https://huggingface.co/spaces/DontPlanToEnd/UGI-Leaderboard) with a simple holistic mathematical equation that ensures top ranked models posses a high amount of Uncensored Information, are Naturally very Intelligent, and most importantly they are OBEDIENT to the user.
121
 
122
- $$ \\text{UGI Index} = (\\text{UGI} + \\text{NatInt}) \\times (\\text{W/10})^2 $$
123
 
124
  * **UGI:** Uncensored General Intelligence
125
  * **NatInt:** Natural Intelligence
126
- * **W/10:** Willingness
 
 
127
  """)
128
- # ------------------------------------------
129
 
130
  with gr.Row():
131
  status_box = gr.Textbox(label="Status", value="Initializing...", interactive=False, scale=4)
132
  refresh_btn = gr.Button("Refresh Data", scale=1)
133
 
134
  with gr.Row():
135
- search_box = gr.Textbox(label="Search Models", placeholder="Type model name...", interactive=True)
 
136
 
137
  # Initialize with empty dataframe
138
  data_table = gr.Dataframe(
139
- headers=['Rank', 'Model', 'UGI Index', 'UGI', 'NatInt', 'W/10'],
140
  datatype="markdown",
141
  interactive=False,
142
  wrap=True
@@ -144,13 +164,14 @@ with gr.Blocks(css=custom_css, title="UGI Index Leaderboard") as demo:
144
 
145
  # Wire up events
146
  # 1. On Load: Fetch data, update table and status
147
- demo.load(fn=app_load, outputs=[data_table, status_box])
148
 
149
  # 2. On Refresh: Fetch data again
150
- refresh_btn.click(fn=app_load, outputs=[data_table, status_box])
151
 
152
- # 3. On Search: Filter existing data
153
- search_box.change(fn=search, inputs=search_box, outputs=data_table)
 
154
 
155
  if __name__ == "__main__":
156
  demo.launch()
 
1
  import gradio as gr
2
  import pandas as pd
3
  from huggingface_hub import hf_hub_download
4
+ import re
5
 
6
  # --- Constants ---
7
  REPO_ID = "DontPlanToEnd/UGI-Leaderboard"
 
15
 
16
  def get_data():
17
  """
18
+ Downloads, processes, and returns the full leaderboard dataframe + status message.
19
  """
20
  print("πŸ”„ Starting download...")
21
  try:
 
27
  df = pd.read_csv(file_path, encoding='utf-8-sig')
28
  df.columns = df.columns.str.strip()
29
 
30
+ # 3. Exact & Fuzzy Column Matching
31
  def get_col(keyword):
32
  matches = [c for c in df.columns if keyword.lower() in c.lower()]
33
  return matches[0] if matches else None
34
 
35
+ # Prioritize exact names from the CSV, fallback to fuzzy matching
36
+ model_col = "author/model_name" if "author/model_name" in df.columns else (get_col("author") or get_col("model"))
37
+ link_col = "Model Link" if "Model Link" in df.columns else get_col("link")
38
+ ugi_col = "UGI πŸ†" if "UGI πŸ†" in df.columns else get_col("ugi")
39
+ natint_col = "NatInt πŸ’‘" if "NatInt πŸ’‘" in df.columns else get_col("natint")
40
+ w10_col = "W/10 πŸ‘" if "W/10 πŸ‘" in df.columns else get_col("w/10")
41
+
42
+ # We need TOTAL parameters to accurately estimate the GGUF file size
43
+ param_col = "Total Parameters" if "Total Parameters" in df.columns else (get_col("param") or get_col("size"))
44
 
45
+ # 4. Check if we found required columns
46
  if not all([model_col, ugi_col, natint_col, w10_col]):
47
  missing = []
48
  if not model_col: missing.append("Model")
 
51
  if not w10_col: missing.append("W/10")
52
  return pd.DataFrame(), f"❌ Error: Could not find columns: {', '.join(missing)}. Found: {list(df.columns)}"
53
 
54
+ # 5. Extract Parameter Size & Calculate Q4_K_M size
55
+ if param_col:
56
+ df['Params (B)'] = pd.to_numeric(df[param_col], errors='coerce').fillna(0)
57
+ else:
58
+ # Fallback: Extract from model name (e.g., "Llama-3-70B" -> 70)
59
+ df['Params (B)'] = df[model_col].astype(str).str.extract(r'(?i)(\d+\.?\d*)[bB]').astype(float).fillna(0)
60
+
61
+ # Q4_K_M size formula: Parameter count * 0.6 GB (e.g., 24B * 0.6 = 14.4 GB)
62
+ df['Q4_K_M Size (GB)'] = (df['Params (B)'] * 0.6).round(1)
63
+
64
+ # Friendly string representation for the UI
65
+ df['Q4_K_M Size'] = df['Q4_K_M Size (GB)'].apply(lambda x: f"{x} GB" if x > 0 else "API / Unknown")
66
+
67
+ # 6. Clean Numeric Data
68
  for col in [ugi_col, natint_col, w10_col]:
69
  df[col] = pd.to_numeric(df[col], errors='coerce').fillna(0)
70
 
71
+ # 7. Calculate UGI Index (UPDATED LOGIC)
72
+ # Formula: (UGI + NatInt) * (W/10 ^ 2)
73
  df['UGI Index'] = (df[ugi_col] + df[natint_col]) * (df[w10_col] ** 2)
74
  df['UGI Index'] = df['UGI Index'].round(2)
75
 
 
 
 
 
76
  # 8. Sort and Rank
77
  df = df.sort_values(by='UGI Index', ascending=False)
78
  df.insert(0, 'Rank', range(1, len(df) + 1))
79
 
80
+ # 9. Normalize display columns
81
+ if link_col:
82
+ df['Model'] = df.apply(lambda x: make_clickable_model(x[model_col], x[link_col]), axis=1)
83
+ else:
84
+ df['Model'] = df[model_col]
85
+
86
+ df['UGI'] = df[ugi_col]
87
+ df['NatInt'] = df[natint_col]
88
+ df['W/10'] = df[w10_col]
89
+
90
+ return df, f"βœ… Successfully loaded {len(df)} models."
 
 
 
 
91
 
92
  except Exception as e:
93
  print(f"Error: {e}")
 
96
  # Global cache for search to use
97
  CACHED_DF = pd.DataFrame()
98
 
99
+ def search(query, max_size):
100
+ """Filters the cached dataframe by search query and Q4_K_M Size."""
 
 
 
 
 
 
 
101
  if CACHED_DF.empty:
102
  return CACHED_DF
103
 
104
+ df = CACHED_DF.copy()
105
+
106
+ # Text Filter
107
+ if query:
108
+ df = df[df['Model'].astype(str).str.contains(query, case=False, na=False)]
109
+
110
+ # Size Filter (128 is the arbitrary "Show All" max value)
111
+ if max_size < 128:
112
+ # Hide API models (Size == 0) and models that exceed the selected size
113
+ df = df[(df['Q4_K_M Size (GB)'] <= max_size) & (df['Q4_K_M Size (GB)'] > 0)]
114
 
115
+ display_cols = ['Rank', 'Model', 'Q4_K_M Size', 'UGI Index', 'UGI', 'NatInt', 'W/10']
116
+ return df[display_cols]
117
+
118
+ def app_load(query, max_size):
119
+ """Called when app starts or refreshes."""
120
+ global CACHED_DF
121
+ df, status = get_data()
122
+ CACHED_DF = df
123
+ filtered_df = search(query, max_size)
124
+ return filtered_df, status
125
 
126
  # --- UI ---
127
  custom_css = """
 
132
  with gr.Blocks(css=custom_css, title="UGI Index Leaderboard") as demo:
133
  gr.Markdown("# πŸ† UGI Index")
134
 
135
+ # (UPDATED MARKDOWN FORMULA)
136
  gr.Markdown("""
137
  ### ℹ️ How is the Score Calculated?
138
+ The **UGI Index** ranks LLMs based on data from [DontPlanToEnd/UGI-Leaderboard](https://huggingface.co/spaces/DontPlanToEnd/UGI-Leaderboard) with a simple holistic mathematical equation that ensures top ranked models posses a high amount of Uncensored Information, are Naturally very Intelligent, and most importantly they are OBEDIENT to the user. This is just my personal "rule of thumb" method for choosing the best uncensored model for LOCAL use on any given hardware I have laying around. Ajust the slider to the amount of RAM on your device to see the best uncensored model for your hardware. It uses Q4_K_M as a refrence point for GGUF size, however there are tons of options so it can be flexable. If your brand new and just want to try a uncensored local LLM for the first time do this: Grab a **mradermacher** quant in **i1-IQ4_XS** and run with **LMstudio.ai**
139
 
140
+ $$ \\text{UGI Index} = (\\text{UGI} + \\text{NatInt}) \\times \\text{W/10}^2 $$
141
 
142
  * **UGI:** Uncensored General Intelligence
143
  * **NatInt:** Natural Intelligence
144
+ * **W/10:** Willingness (Squared)
145
+
146
+ *πŸ’‘ **Note on Model Size:** GGUF size is calculated at standard **Q4_K_M** quantization (`Total Parameters Γ— 0.6 GB`). Lowering the slider automatically hides closed-source API models.*
147
  """)
 
148
 
149
  with gr.Row():
150
  status_box = gr.Textbox(label="Status", value="Initializing...", interactive=False, scale=4)
151
  refresh_btn = gr.Button("Refresh Data", scale=1)
152
 
153
  with gr.Row():
154
+ search_box = gr.Textbox(label="Search Models", placeholder="Type model name...", interactive=True, scale=1)
155
+ size_slider = gr.Slider(minimum=1, maximum=128, value=128, step=1, label="πŸ’» Running Local? Max Q4_K_M Size (GB) - Set to 128 to include API models", interactive=True, scale=1)
156
 
157
  # Initialize with empty dataframe
158
  data_table = gr.Dataframe(
159
+ headers=['Rank', 'Model', 'Q4_K_M Size', 'UGI Index', 'UGI', 'NatInt', 'W/10'],
160
  datatype="markdown",
161
  interactive=False,
162
  wrap=True
 
164
 
165
  # Wire up events
166
  # 1. On Load: Fetch data, update table and status
167
+ demo.load(fn=app_load, inputs=[search_box, size_slider], outputs=[data_table, status_box])
168
 
169
  # 2. On Refresh: Fetch data again
170
+ refresh_btn.click(fn=app_load, inputs=[search_box, size_slider], outputs=[data_table, status_box])
171
 
172
+ # 3. On Search or Slider Change: Filter existing data
173
+ search_box.change(fn=search, inputs=[search_box, size_slider], outputs=data_table)
174
+ size_slider.change(fn=search, inputs=[search_box, size_slider], outputs=data_table)
175
 
176
  if __name__ == "__main__":
177
  demo.launch()