bgamazay commited on
Commit
ab1e3f0
·
verified ·
1 Parent(s): 6cf996d

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +22 -254
app.py CHANGED
@@ -32,7 +32,6 @@ def format_stars(score):
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,102 +39,54 @@ 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
  html += '<thead><tr style="background-color: #f2f2f2;">'
73
  html += '<th style="text-align: left; padding: 8px;" title="Model name with link to Hugging Face">Model</th>'
74
  html += '<th style="text-align: left; padding: 8px;" title="GPU energy consumed in Watt-hours for 1,000 queries">GPU Energy (Wh)</th>'
75
- 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>'
76
- html += '</tr></thead>'
77
-
78
- # Apply the static width to the Model column header.
79
- html += f'<thead><tr style="background-color: #f2f2f2;">'
80
- html += f'<th style="text-align: left; padding: 8px; width: {static_width}px;">Model</th>'
81
- html += '<th style="text-align: left; padding: 8px;">GPU Energy (Wh)</th>'
82
- html += '<th style="text-align: left; padding: 8px;">Score</th>'
83
  html += '</tr></thead>'
84
  html += '<tbody>'
 
85
  for _, row in df.iterrows():
86
  energy_numeric = row['gpu_energy_numeric']
87
- energy_str = f"{energy_numeric:.2f}"
88
- # Compute the relative width (as a percentage)
89
  bar_width = (energy_numeric / max_energy) * 100
90
  score_val = row['energy_score']
91
  bar_color = color_map.get(str(score_val), "gray")
 
92
  html += '<tr>'
93
- # Apply the static width to the Model column cell.
94
- html += f'<td style="padding: 8px; width: {static_width}px;">{row["Model"]}</td>'
95
- html += (
96
- f'<td style="padding: 8px;">{energy_str}<br>'
97
- f'<div style="background-color: {bar_color}; width: {bar_width:.1f}%; height: 10px;"></div></td>'
98
- )
99
  html += f'<td style="padding: 8px;">{row["Score"]}</td>'
100
  html += '</tr>'
 
101
  html += '</tbody></table>'
102
  return html
103
 
104
- # --- Function to zip all CSV files ---
105
- def zip_csv_files():
106
- data_dir = "data/energy"
107
- zip_filename = "data.zip"
108
- with zipfile.ZipFile(zip_filename, "w", zipfile.ZIP_DEFLATED) as zipf:
109
- for filename in os.listdir(data_dir):
110
- if filename.endswith(".csv"):
111
- filepath = os.path.join(data_dir, filename)
112
- zipf.write(filepath, arcname=filename)
113
- return zip_filename
114
-
115
- def get_zip_data_link():
116
- """Creates a data URI download link for the ZIP file."""
117
- zip_filename = zip_csv_files()
118
- with open(zip_filename, "rb") as f:
119
- data = f.read()
120
- b64 = base64.b64encode(data).decode()
121
- 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>'
122
- return href
123
-
124
- # --- Modified functions to include a sort_order parameter ---
125
- def get_model_names_html(task, sort_order="High to Low"):
126
  df = pd.read_csv('data/energy/' + task)
127
  if df.columns[0].startswith("Unnamed:"):
128
  df = df.iloc[:, 1:]
129
  df['energy_score'] = df['energy_score'].astype(int)
130
- # Convert kWh to Wh:
131
  df['gpu_energy_numeric'] = pd.to_numeric(df['total_gpu_energy'], errors='raise') * 1000
132
  df['Model'] = df['model'].apply(make_link)
133
  df['Score'] = df['energy_score'].apply(format_stars)
134
- ascending = True if sort_order == "Low to High" else False
135
  df = df.sort_values(by='gpu_energy_numeric', ascending=ascending)
136
  return generate_html_table_from_df(df)
137
 
138
- def get_all_model_names_html(sort_order="High to Low"):
 
 
 
139
  all_df = pd.DataFrame()
140
  for task in tasks:
141
  df = pd.read_csv('data/energy/' + task)
@@ -147,69 +98,11 @@ def get_all_model_names_html(sort_order="High to Low"):
147
  df['Score'] = df['energy_score'].apply(format_stars)
148
  all_df = pd.concat([all_df, df], ignore_index=True)
149
  all_df = all_df.drop_duplicates(subset=['model'])
150
- ascending = True if sort_order == "Low to High" else False
151
  all_df = all_df.sort_values(by='gpu_energy_numeric', ascending=ascending)
152
  return generate_html_table_from_df(all_df)
153
 
154
- def get_text_generation_model_names_html(model_class, sort_order="High to Low"):
155
- df = pd.read_csv('data/energy/text_generation.csv')
156
- if df.columns[0].startswith("Unnamed:"):
157
- df = df.iloc[:, 1:]
158
- if 'class' in df.columns:
159
- df = df[df['class'] == model_class]
160
- df['energy_score'] = df['energy_score'].astype(int)
161
- df['gpu_energy_numeric'] = pd.to_numeric(df['total_gpu_energy'], errors='raise') * 1000
162
- df['Model'] = df['model'].apply(make_link)
163
- df['Score'] = df['energy_score'].apply(format_stars)
164
- ascending = True if sort_order == "Low to High" else False
165
- df = df.sort_values(by='gpu_energy_numeric', ascending=ascending)
166
- return generate_html_table_from_df(df)
167
-
168
- # --- Update functions for dropdown changes ---
169
-
170
- # For Text Generation, two dropdowns: model class and sort order.
171
- def update_text_generation(selected_display, sort_order):
172
- mapping = {
173
- "A (Single Consumer GPU) <20B parameters": "A",
174
- "B (Single Cloud GPU) 20-66B parameters": "B",
175
- "C (Multiple Cloud GPUs) >66B parameters": "C"
176
- }
177
- model_class = mapping.get(selected_display, "A")
178
- return get_text_generation_model_names_html(model_class, sort_order)
179
-
180
- # For the other tabs, each update function simply takes the sort_order.
181
- def update_image_generation(sort_order):
182
- return get_model_names_html('image_generation.csv', sort_order)
183
-
184
- def update_text_classification(sort_order):
185
- return get_model_names_html('text_classification.csv', sort_order)
186
-
187
- def update_image_classification(sort_order):
188
- return get_model_names_html('image_classification.csv', sort_order)
189
-
190
- def update_image_captioning(sort_order):
191
- return get_model_names_html('image_captioning.csv', sort_order)
192
-
193
- def update_summarization(sort_order):
194
- return get_model_names_html('summarization.csv', sort_order)
195
-
196
- def update_asr(sort_order):
197
- return get_model_names_html('asr.csv', sort_order)
198
-
199
- def update_object_detection(sort_order):
200
- return get_model_names_html('object_detection.csv', sort_order)
201
-
202
- def update_sentence_similarity(sort_order):
203
- return get_model_names_html('sentence_similarity.csv', sort_order)
204
-
205
- def update_extractive_qa(sort_order):
206
- return get_model_names_html('question_answering.csv', sort_order)
207
-
208
- def update_all_tasks(sort_order):
209
- return get_all_model_names_html(sort_order)
210
-
211
  # --- Build the Gradio Interface ---
212
-
213
  demo = gr.Blocks(css="""
214
  .gr-dataframe table {
215
  table-layout: fixed;
@@ -224,142 +117,17 @@ demo = gr.Blocks(css="""
224
  """)
225
 
226
  with demo:
227
- gr.Markdown(
228
- """# AI Energy Score Leaderboard
229
- ### Welcome to the leaderboard for the [AI Energy Score Project!](https://huggingface.co/AIEnergyScore) — Select different tasks to see scored models."""
230
- )
231
-
232
- # Header links (using a row of components, including a Download Data link)
233
- with gr.Row():
234
- 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>')
235
- 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>')
236
- 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>')
237
- 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>')
238
- download_link = gr.HTML(get_zip_data_link())
239
- 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>')
240
 
241
  with gr.Tabs():
242
- # --- Text Generation Tab ---
243
- with gr.TabItem("Text Generation 💬"):
244
- with gr.Row():
245
- model_class_options = [
246
- "A (Single Consumer GPU) <20B parameters",
247
- "B (Single Cloud GPU) 20-66B parameters",
248
- "C (Multiple Cloud GPUs) >66B parameters"
249
- ]
250
- model_class_dropdown = gr.Dropdown(
251
- choices=model_class_options,
252
- label="Select Model Class",
253
- value=model_class_options[0]
254
- )
255
- sort_dropdown_tg = gr.Dropdown(
256
- choices=["Low to High", "High to Low"],
257
- label="Sort",
258
- value="High to Low"
259
- )
260
- tg_table = gr.HTML(get_text_generation_model_names_html("A", "High to Low"))
261
- # When either dropdown changes, update the table.
262
- model_class_dropdown.change(fn=update_text_generation, inputs=[model_class_dropdown, sort_dropdown_tg], outputs=tg_table)
263
- sort_dropdown_tg.change(fn=update_text_generation, inputs=[model_class_dropdown, sort_dropdown_tg], outputs=tg_table)
264
-
265
- # --- Image Generation Tab ---
266
- with gr.TabItem("Image Generation 📷"):
267
- sort_dropdown_img = gr.Dropdown(
268
- choices=["Low to High", "High to Low"],
269
- label="Sort",
270
- value="High to Low"
271
- )
272
- img_table = gr.HTML(get_model_names_html('image_generation.csv', "High to Low"))
273
- sort_dropdown_img.change(fn=update_image_generation, inputs=sort_dropdown_img, outputs=img_table)
274
-
275
- # --- Text Classification Tab ---
276
- with gr.TabItem("Text Classification 🎭"):
277
- sort_dropdown_tc = gr.Dropdown(
278
- choices=["Low to High", "High to Low"],
279
- label="Sort",
280
- value="High to Low"
281
- )
282
- tc_table = gr.HTML(get_model_names_html('text_classification.csv', "High to Low"))
283
- sort_dropdown_tc.change(fn=update_text_classification, inputs=sort_dropdown_tc, outputs=tc_table)
284
-
285
- # --- Image Classification Tab ---
286
- with gr.TabItem("Image Classification 🖼️"):
287
- sort_dropdown_ic = gr.Dropdown(
288
- choices=["Low to High", "High to Low"],
289
- label="Sort",
290
- value="High to Low"
291
- )
292
- ic_table = gr.HTML(get_model_names_html('image_classification.csv', "High to Low"))
293
- sort_dropdown_ic.change(fn=update_image_classification, inputs=sort_dropdown_ic, outputs=ic_table)
294
-
295
- # --- Image Captioning Tab ---
296
- with gr.TabItem("Image Captioning 📝"):
297
- sort_dropdown_icap = gr.Dropdown(
298
- choices=["Low to High", "High to Low"],
299
- label="Sort",
300
- value="High to Low"
301
- )
302
- icap_table = gr.HTML(get_model_names_html('image_captioning.csv', "High to Low"))
303
- sort_dropdown_icap.change(fn=update_image_captioning, inputs=sort_dropdown_icap, outputs=icap_table)
304
-
305
- # --- Summarization Tab ---
306
- with gr.TabItem("Summarization 📃"):
307
- sort_dropdown_sum = gr.Dropdown(
308
- choices=["Low to High", "High to Low"],
309
- label="Sort",
310
- value="High to Low"
311
- )
312
- sum_table = gr.HTML(get_model_names_html('summarization.csv', "High to Low"))
313
- sort_dropdown_sum.change(fn=update_summarization, inputs=sort_dropdown_sum, outputs=sum_table)
314
-
315
- # --- Automatic Speech Recognition Tab ---
316
- with gr.TabItem("Automatic Speech Recognition 💬"):
317
- sort_dropdown_asr = gr.Dropdown(
318
- choices=["Low to High", "High to Low"],
319
- label="Sort",
320
- value="High to Low"
321
- )
322
- asr_table = gr.HTML(get_model_names_html('asr.csv', "High to Low"))
323
- sort_dropdown_asr.change(fn=update_asr, inputs=sort_dropdown_asr, outputs=asr_table)
324
-
325
- # --- Object Detection Tab ---
326
- with gr.TabItem("Object Detection 🚘"):
327
- sort_dropdown_od = gr.Dropdown(
328
- choices=["Low to High", "High to Low"],
329
- label="Sort",
330
- value="High to Low"
331
- )
332
- od_table = gr.HTML(get_model_names_html('object_detection.csv', "High to Low"))
333
- sort_dropdown_od.change(fn=update_object_detection, inputs=sort_dropdown_od, outputs=od_table)
334
-
335
- # --- Sentence Similarity Tab ---
336
- with gr.TabItem("Sentence Similarity 📚"):
337
- sort_dropdown_ss = gr.Dropdown(
338
- choices=["Low to High", "High to Low"],
339
- label="Sort",
340
- value="High to Low"
341
- )
342
- ss_table = gr.HTML(get_model_names_html('sentence_similarity.csv', "High to Low"))
343
- sort_dropdown_ss.change(fn=update_sentence_similarity, inputs=sort_dropdown_ss, outputs=ss_table)
344
-
345
- # --- Extractive QA Tab ---
346
- with gr.TabItem("Extractive QA ❔"):
347
- sort_dropdown_qa = gr.Dropdown(
348
- choices=["Low to High", "High to Low"],
349
- label="Sort",
350
- value="High to Low"
351
- )
352
- qa_table = gr.HTML(get_model_names_html('question_answering.csv', "High to Low"))
353
- sort_dropdown_qa.change(fn=update_extractive_qa, inputs=sort_dropdown_qa, outputs=qa_table)
354
-
355
- # --- All Tasks Tab ---
356
  with gr.TabItem("All Tasks 💡"):
357
  sort_dropdown_all = gr.Dropdown(
358
  choices=["Low to High", "High to Low"],
359
  label="Sort",
360
- value="High to Low"
361
  )
362
- all_table = gr.HTML(get_all_model_names_html("High to Low"))
363
  sort_dropdown_all.change(fn=update_all_tasks, inputs=sort_dropdown_all, outputs=all_table)
364
 
365
  with gr.Accordion("📙 Citation", open=False):
@@ -372,4 +140,4 @@ with demo:
372
  )
373
  gr.Markdown("""Last updated: February 2025""")
374
 
375
- demo.launch()
 
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
  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:
92
  df = pd.read_csv('data/energy/' + task)
 
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
  """)
118
 
119
  with demo:
120
+ gr.HTML('<div style="text-align: center;"><img src="logo.png" alt="Logo" style="width: 200px;"></div>')
121
+ gr.Markdown('<div style="text-align: center; font-size: 1.2em;">Welcome to the AI Energy Score Leaderboard</div>', unsafe_allow_html=True)
 
 
 
 
 
 
 
 
 
 
 
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"],
127
  label="Sort",
128
+ value="Low to High"
129
  )
130
+ all_table = gr.HTML(get_all_model_names_html("Low to High"))
131
  sort_dropdown_all.change(fn=update_all_tasks, inputs=sort_dropdown_all, outputs=all_table)
132
 
133
  with gr.Accordion("📙 Citation", open=False):
 
140
  )
141
  gr.Markdown("""Last updated: February 2025""")
142
 
143
+ demo.launch()