bgamazay commited on
Commit
ec5fd05
·
verified ·
1 Parent(s): 361f8d0

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +242 -18
app.py CHANGED
@@ -32,6 +32,7 @@ def format_stars(score):
32
  score_int = int(score)
33
  except Exception:
34
  score_int = 0
 
35
  return f'<span style="color: black; font-size:1.5em;">{"★" * score_int}</span>'
36
 
37
  def make_link(mname):
@@ -39,53 +40,94 @@ def make_link(mname):
39
  display_name = parts[1] if len(parts) > 1 else mname
40
  return f'<a href="https://huggingface.co/{mname}" target="_blank">{display_name}</a>'
41
 
 
 
 
 
 
 
 
 
 
42
  def generate_html_table_from_df(df):
43
  """
44
- Generates an HTML table with tooltips for column headers.
 
 
 
 
 
45
  """
 
 
 
 
 
 
 
 
46
  max_energy = df['gpu_energy_numeric'].max() if not df.empty else 1
47
  color_map = {"1": "black", "2": "black", "3": "black", "4": "black", "5": "black"}
48
-
49
  html = '<table style="width:100%; border-collapse: collapse; font-family: Inter, sans-serif;">'
 
50
  html += '<thead><tr style="background-color: #f2f2f2;">'
51
  html += '<th style="text-align: left; padding: 8px;" title="Model name with link to Hugging Face">Model</th>'
52
  html += '<th style="text-align: left; padding: 8px;" title="GPU energy consumed in Watt-hours for 1,000 queries">GPU Energy (Wh)</th>'
53
- html += '<th style="text-align: left; padding: 8px;" title="5 is most efficient, 1 is least. Relative energy efficiency score at launch">Score</th>'
54
  html += '</tr></thead>'
55
  html += '<tbody>'
56
-
57
  for _, row in df.iterrows():
58
  energy_numeric = row['gpu_energy_numeric']
59
- energy_str = f"{energy_numeric:.2f}" # Display GPU energy with 2 decimal places
 
60
  bar_width = (energy_numeric / max_energy) * 100
61
  score_val = row['energy_score']
62
  bar_color = color_map.get(str(score_val), "gray")
63
-
64
  html += '<tr>'
65
- html += f'<td style="padding: 8px;">{row["Model"]}</td>'
66
- html += f'<td style="padding: 8px;">{energy_str}<br>'
67
- html += f'<div style="background-color: {bar_color}; width: {bar_width:.1f}%; height: 10px;"></div></td>'
 
 
68
  html += f'<td style="padding: 8px;">{row["Score"]}</td>'
69
  html += '</tr>'
70
-
71
  html += '</tbody></table>'
72
  return html
73
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
74
  def get_model_names_html(task, sort_order="Low to High"):
75
  df = pd.read_csv('data/energy/' + task)
76
  if df.columns[0].startswith("Unnamed:"):
77
  df = df.iloc[:, 1:]
78
  df['energy_score'] = df['energy_score'].astype(int)
 
79
  df['gpu_energy_numeric'] = pd.to_numeric(df['total_gpu_energy'], errors='raise') * 1000
80
  df['Model'] = df['model'].apply(make_link)
81
  df['Score'] = df['energy_score'].apply(format_stars)
82
- ascending = True # Always default to Low to High
83
  df = df.sort_values(by='gpu_energy_numeric', ascending=ascending)
84
  return generate_html_table_from_df(df)
85
 
86
- def update_all_tasks(sort_order):
87
- return get_all_model_names_html(sort_order)
88
-
89
  def get_all_model_names_html(sort_order="Low to High"):
90
  all_df = pd.DataFrame()
91
  for task in tasks:
@@ -98,11 +140,69 @@ def get_all_model_names_html(sort_order="Low to High"):
98
  df['Score'] = df['energy_score'].apply(format_stars)
99
  all_df = pd.concat([all_df, df], ignore_index=True)
100
  all_df = all_df.drop_duplicates(subset=['model'])
101
- ascending = True # Default to Low to High
102
  all_df = all_df.sort_values(by='gpu_energy_numeric', ascending=ascending)
103
  return generate_html_table_from_df(all_df)
104
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
105
  # --- Build the Gradio Interface ---
 
106
  demo = gr.Blocks(css="""
107
  .gr-dataframe table {
108
  table-layout: fixed;
@@ -117,10 +217,134 @@ demo = gr.Blocks(css="""
117
  """)
118
 
119
  with demo:
120
- gr.HTML('<div style="text-align: center;"><img src="logo.png" alt="Logo" style="width: 200px;"></div>')
121
- gr.HTML('<div style="text-align: center; font-size: 1.2em;">Welcome to the AI Energy Score Leaderboard</div>')
 
 
 
 
 
 
 
 
 
 
122
 
123
  with gr.Tabs():
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
124
  with gr.TabItem("All Tasks 💡"):
125
  sort_dropdown_all = gr.Dropdown(
126
  choices=["Low to High", "High to Low"],
@@ -140,4 +364,4 @@ with demo:
140
  )
141
  gr.Markdown("""Last updated: February 2025""")
142
 
143
- demo.launch()
 
32
  score_int = int(score)
33
  except Exception:
34
  score_int = 0
35
+ # Render stars in black with a slightly larger font.
36
  return f'<span style="color: black; font-size:1.5em;">{"★" * score_int}</span>'
37
 
38
  def make_link(mname):
 
40
  display_name = parts[1] if len(parts) > 1 else mname
41
  return f'<a href="https://huggingface.co/{mname}" target="_blank">{display_name}</a>'
42
 
43
+ def extract_link_text(html_link):
44
+ """Extracts the inner text from an HTML link."""
45
+ start = html_link.find('>') + 1
46
+ end = html_link.rfind('</a>')
47
+ if start > 0 and end > start:
48
+ return html_link[start:end]
49
+ else:
50
+ return html_link
51
+
52
  def generate_html_table_from_df(df):
53
  """
54
+ Given a dataframe with a numeric energy column (gpu_energy_numeric),
55
+ generate an HTML table with three columns:
56
+ - Model (the link, with a fixed width based on the longest model name)
57
+ - GPU Energy (Wh) plus a horizontal bar whose width is proportional
58
+ to the energy value relative to the maximum in the table.
59
+ - Score (displayed as stars)
60
  """
61
+ # Compute a static width (in pixels) for the Model column based on the longest model name.
62
+ if not df.empty:
63
+ max_length = max(len(extract_link_text(link)) for link in df['Model'])
64
+ else:
65
+ max_length = 10
66
+ # Multiply by an estimated average character width (10 pixels) and add some extra padding.
67
+ static_width = max_length * 10 + 16
68
+
69
  max_energy = df['gpu_energy_numeric'].max() if not df.empty else 1
70
  color_map = {"1": "black", "2": "black", "3": "black", "4": "black", "5": "black"}
 
71
  html = '<table style="width:100%; border-collapse: collapse; font-family: Inter, sans-serif;">'
72
+ # Keep only one header (the one with hover text)
73
  html += '<thead><tr style="background-color: #f2f2f2;">'
74
  html += '<th style="text-align: left; padding: 8px;" title="Model name with link to Hugging Face">Model</th>'
75
  html += '<th style="text-align: left; padding: 8px;" title="GPU energy consumed in Watt-hours for 1,000 queries">GPU Energy (Wh)</th>'
76
+ html += '<th style="text-align: left; padding: 8px;" title="5 is most efficient, 1 is least. Relative energy efficiency score relative to other models in task/class at the time of leaderboard launch">Score</th>'
77
  html += '</tr></thead>'
78
  html += '<tbody>'
 
79
  for _, row in df.iterrows():
80
  energy_numeric = row['gpu_energy_numeric']
81
+ energy_str = f"{energy_numeric:.2f}"
82
+ # Compute the relative width (as a percentage)
83
  bar_width = (energy_numeric / max_energy) * 100
84
  score_val = row['energy_score']
85
  bar_color = color_map.get(str(score_val), "gray")
 
86
  html += '<tr>'
87
+ html += f'<td style="padding: 8px; width: {static_width}px;">{row["Model"]}</td>'
88
+ html += (
89
+ f'<td style="padding: 8px;">{energy_str}<br>'
90
+ f'<div style="background-color: {bar_color}; width: {bar_width:.1f}%; height: 10px;"></div></td>'
91
+ )
92
  html += f'<td style="padding: 8px;">{row["Score"]}</td>'
93
  html += '</tr>'
 
94
  html += '</tbody></table>'
95
  return html
96
 
97
+ # --- Function to zip all CSV files ---
98
+ def zip_csv_files():
99
+ data_dir = "data/energy"
100
+ zip_filename = "data.zip"
101
+ with zipfile.ZipFile(zip_filename, "w", zipfile.ZIP_DEFLATED) as zipf:
102
+ for filename in os.listdir(data_dir):
103
+ if filename.endswith(".csv"):
104
+ filepath = os.path.join(data_dir, filename)
105
+ zipf.write(filepath, arcname=filename)
106
+ return zip_filename
107
+
108
+ def get_zip_data_link():
109
+ """Creates a data URI download link for the ZIP file."""
110
+ zip_filename = zip_csv_files()
111
+ with open(zip_filename, "rb") as f:
112
+ data = f.read()
113
+ b64 = base64.b64encode(data).decode()
114
+ href = f'<a href="data:application/zip;base64,{b64}" download="data.zip" style="margin: 0 15px; text-decoration: none; font-weight: bold; font-size: 1.1em;">Download Data</a>'
115
+ return href
116
+
117
+ # --- Modified functions to include a sort_order parameter ---
118
  def get_model_names_html(task, sort_order="Low to High"):
119
  df = pd.read_csv('data/energy/' + task)
120
  if df.columns[0].startswith("Unnamed:"):
121
  df = df.iloc[:, 1:]
122
  df['energy_score'] = df['energy_score'].astype(int)
123
+ # Convert kWh to Wh:
124
  df['gpu_energy_numeric'] = pd.to_numeric(df['total_gpu_energy'], errors='raise') * 1000
125
  df['Model'] = df['model'].apply(make_link)
126
  df['Score'] = df['energy_score'].apply(format_stars)
127
+ ascending = True if sort_order == "Low to High" else False
128
  df = df.sort_values(by='gpu_energy_numeric', ascending=ascending)
129
  return generate_html_table_from_df(df)
130
 
 
 
 
131
  def get_all_model_names_html(sort_order="Low to High"):
132
  all_df = pd.DataFrame()
133
  for task in tasks:
 
140
  df['Score'] = df['energy_score'].apply(format_stars)
141
  all_df = pd.concat([all_df, df], ignore_index=True)
142
  all_df = all_df.drop_duplicates(subset=['model'])
143
+ ascending = True if sort_order == "Low to High" else False
144
  all_df = all_df.sort_values(by='gpu_energy_numeric', ascending=ascending)
145
  return generate_html_table_from_df(all_df)
146
 
147
+ def get_text_generation_model_names_html(model_class, sort_order="Low to High"):
148
+ df = pd.read_csv('data/energy/text_generation.csv')
149
+ if df.columns[0].startswith("Unnamed:"):
150
+ df = df.iloc[:, 1:]
151
+ if 'class' in df.columns:
152
+ df = df[df['class'] == model_class]
153
+ df['energy_score'] = df['energy_score'].astype(int)
154
+ df['gpu_energy_numeric'] = pd.to_numeric(df['total_gpu_energy'], errors='raise') * 1000
155
+ df['Model'] = df['model'].apply(make_link)
156
+ df['Score'] = df['energy_score'].apply(format_stars)
157
+ ascending = True if sort_order == "Low to High" else False
158
+ df = df.sort_values(by='gpu_energy_numeric', ascending=ascending)
159
+ return generate_html_table_from_df(df)
160
+
161
+ # --- Update functions for dropdown changes ---
162
+
163
+ # For Text Generation, two dropdowns: model class and sort order.
164
+ def update_text_generation(selected_display, sort_order):
165
+ mapping = {
166
+ "A (Single Consumer GPU) <20B parameters": "A",
167
+ "B (Single Cloud GPU) 20-66B parameters": "B",
168
+ "C (Multiple Cloud GPUs) >66B parameters": "C"
169
+ }
170
+ model_class = mapping.get(selected_display, "A")
171
+ return get_text_generation_model_names_html(model_class, sort_order)
172
+
173
+ # For the other tabs, each update function simply takes the sort_order.
174
+ def update_image_generation(sort_order):
175
+ return get_model_names_html('image_generation.csv', sort_order)
176
+
177
+ def update_text_classification(sort_order):
178
+ return get_model_names_html('text_classification.csv', sort_order)
179
+
180
+ def update_image_classification(sort_order):
181
+ return get_model_names_html('image_classification.csv', sort_order)
182
+
183
+ def update_image_captioning(sort_order):
184
+ return get_model_names_html('image_captioning.csv', sort_order)
185
+
186
+ def update_summarization(sort_order):
187
+ return get_model_names_html('summarization.csv', sort_order)
188
+
189
+ def update_asr(sort_order):
190
+ return get_model_names_html('asr.csv', sort_order)
191
+
192
+ def update_object_detection(sort_order):
193
+ return get_model_names_html('object_detection.csv', sort_order)
194
+
195
+ def update_sentence_similarity(sort_order):
196
+ return get_model_names_html('sentence_similarity.csv', sort_order)
197
+
198
+ def update_extractive_qa(sort_order):
199
+ return get_model_names_html('question_answering.csv', sort_order)
200
+
201
+ def update_all_tasks(sort_order):
202
+ return get_all_model_names_html(sort_order)
203
+
204
  # --- Build the Gradio Interface ---
205
+
206
  demo = gr.Blocks(css="""
207
  .gr-dataframe table {
208
  table-layout: fixed;
 
217
  """)
218
 
219
  with demo:
220
+ # Replace title with a centered logo and a centered subtitle.
221
+ gr.HTML('<div style="text-align: center;"><img src="logo.png" alt="Logo"></div>')
222
+ gr.Markdown('<p style="text-align: center;">Welcome to the leaderboard for the <a href="https://huggingface.co/AIEnergyScore">AI Energy Score Project!</a> — Select different tasks to see scored models.</p>')
223
+
224
+ # Header links (using a row of components, including a Download Data link)
225
+ with gr.Row():
226
+ submission_link = gr.HTML('<a href="https://huggingface.co/spaces/AIEnergyScore/submission_portal" style="margin: 0 10px; text-decoration: none; font-weight: bold; font-size: 1.1em;">Submission Portal</a>')
227
+ label_link = gr.HTML('<a href="https://huggingface.co/spaces/AIEnergyScore/Label" style="margin: 0 10px; text-decoration: none; font-weight: bold; font-size: 1.1em;">Label Generator</a>')
228
+ faq_link = gr.HTML('<a href="https://huggingface.github.io/AIEnergyScore/#faq" style="margin: 0 10px; text-decoration: none; font-weight: bold; font-size: 1.1em;">FAQ</a>')
229
+ documentation_link = gr.HTML('<a href="https://huggingface.github.io/AIEnergyScore/#documentation" style="margin: 0 10px; text-decoration: none; font-weight: bold; font-size: 1.1em;">Documentation</a>')
230
+ download_link = gr.HTML(get_zip_data_link())
231
+ community_link = gr.HTML('<a href="https://huggingface.co/spaces/AIEnergyScore/README/discussions" style="margin: 0 10px; text-decoration: none; font-weight: bold; font-size: 1.1em;">Community</a>')
232
 
233
  with gr.Tabs():
234
+ # --- Text Generation Tab ---
235
+ with gr.TabItem("Text Generation 💬"):
236
+ with gr.Row():
237
+ model_class_options = [
238
+ "A (Single Consumer GPU) <20B parameters",
239
+ "B (Single Cloud GPU) 20-66B parameters",
240
+ "C (Multiple Cloud GPUs) >66B parameters"
241
+ ]
242
+ model_class_dropdown = gr.Dropdown(
243
+ choices=model_class_options,
244
+ label="Select Model Class",
245
+ value=model_class_options[0]
246
+ )
247
+ sort_dropdown_tg = gr.Dropdown(
248
+ choices=["Low to High", "High to Low"],
249
+ label="Sort",
250
+ value="Low to High"
251
+ )
252
+ tg_table = gr.HTML(get_text_generation_model_names_html("A", "Low to High"))
253
+ # When either dropdown changes, update the table.
254
+ model_class_dropdown.change(fn=update_text_generation, inputs=[model_class_dropdown, sort_dropdown_tg], outputs=tg_table)
255
+ sort_dropdown_tg.change(fn=update_text_generation, inputs=[model_class_dropdown, sort_dropdown_tg], outputs=tg_table)
256
+
257
+ # --- Image Generation Tab ---
258
+ with gr.TabItem("Image Generation 📷"):
259
+ sort_dropdown_img = gr.Dropdown(
260
+ choices=["Low to High", "High to Low"],
261
+ label="Sort",
262
+ value="Low to High"
263
+ )
264
+ img_table = gr.HTML(get_model_names_html('image_generation.csv', "Low to High"))
265
+ sort_dropdown_img.change(fn=update_image_generation, inputs=sort_dropdown_img, outputs=img_table)
266
+
267
+ # --- Text Classification Tab ---
268
+ with gr.TabItem("Text Classification 🎭"):
269
+ sort_dropdown_tc = gr.Dropdown(
270
+ choices=["Low to High", "High to Low"],
271
+ label="Sort",
272
+ value="Low to High"
273
+ )
274
+ tc_table = gr.HTML(get_model_names_html('text_classification.csv', "Low to High"))
275
+ sort_dropdown_tc.change(fn=update_text_classification, inputs=sort_dropdown_tc, outputs=tc_table)
276
+
277
+ # --- Image Classification Tab ---
278
+ with gr.TabItem("Image Classification 🖼️"):
279
+ sort_dropdown_ic = gr.Dropdown(
280
+ choices=["Low to High", "High to Low"],
281
+ label="Sort",
282
+ value="Low to High"
283
+ )
284
+ ic_table = gr.HTML(get_model_names_html('image_classification.csv', "Low to High"))
285
+ sort_dropdown_ic.change(fn=update_image_classification, inputs=sort_dropdown_ic, outputs=ic_table)
286
+
287
+ # --- Image Captioning Tab ---
288
+ with gr.TabItem("Image Captioning 📝"):
289
+ sort_dropdown_icap = gr.Dropdown(
290
+ choices=["Low to High", "High to Low"],
291
+ label="Sort",
292
+ value="Low to High"
293
+ )
294
+ icap_table = gr.HTML(get_model_names_html('image_captioning.csv', "Low to High"))
295
+ sort_dropdown_icap.change(fn=update_image_captioning, inputs=sort_dropdown_icap, outputs=icap_table)
296
+
297
+ # --- Summarization Tab ---
298
+ with gr.TabItem("Summarization 📃"):
299
+ sort_dropdown_sum = gr.Dropdown(
300
+ choices=["Low to High", "High to Low"],
301
+ label="Sort",
302
+ value="Low to High"
303
+ )
304
+ sum_table = gr.HTML(get_model_names_html('summarization.csv', "Low to High"))
305
+ sort_dropdown_sum.change(fn=update_summarization, inputs=sort_dropdown_sum, outputs=sum_table)
306
+
307
+ # --- Automatic Speech Recognition Tab ---
308
+ with gr.TabItem("Automatic Speech Recognition 💬"):
309
+ sort_dropdown_asr = gr.Dropdown(
310
+ choices=["Low to High", "High to Low"],
311
+ label="Sort",
312
+ value="Low to High"
313
+ )
314
+ asr_table = gr.HTML(get_model_names_html('asr.csv', "Low to High"))
315
+ sort_dropdown_asr.change(fn=update_asr, inputs=sort_dropdown_asr, outputs=asr_table)
316
+
317
+ # --- Object Detection Tab ---
318
+ with gr.TabItem("Object Detection 🚘"):
319
+ sort_dropdown_od = gr.Dropdown(
320
+ choices=["Low to High", "High to Low"],
321
+ label="Sort",
322
+ value="Low to High"
323
+ )
324
+ od_table = gr.HTML(get_model_names_html('object_detection.csv', "Low to High"))
325
+ sort_dropdown_od.change(fn=update_object_detection, inputs=sort_dropdown_od, outputs=od_table)
326
+
327
+ # --- Sentence Similarity Tab ---
328
+ with gr.TabItem("Sentence Similarity 📚"):
329
+ sort_dropdown_ss = gr.Dropdown(
330
+ choices=["Low to High", "High to Low"],
331
+ label="Sort",
332
+ value="Low to High"
333
+ )
334
+ ss_table = gr.HTML(get_model_names_html('sentence_similarity.csv', "Low to High"))
335
+ sort_dropdown_ss.change(fn=update_sentence_similarity, inputs=sort_dropdown_ss, outputs=ss_table)
336
+
337
+ # --- Extractive QA Tab ---
338
+ with gr.TabItem("Extractive QA ❔"):
339
+ sort_dropdown_qa = gr.Dropdown(
340
+ choices=["Low to High", "High to Low"],
341
+ label="Sort",
342
+ value="Low to High"
343
+ )
344
+ qa_table = gr.HTML(get_model_names_html('question_answering.csv', "Low to High"))
345
+ sort_dropdown_qa.change(fn=update_extractive_qa, inputs=sort_dropdown_qa, outputs=qa_table)
346
+
347
+ # --- All Tasks Tab ---
348
  with gr.TabItem("All Tasks 💡"):
349
  sort_dropdown_all = gr.Dropdown(
350
  choices=["Low to High", "High to Low"],
 
364
  )
365
  gr.Markdown("""Last updated: February 2025""")
366
 
367
+ demo.launch()