bgamazay commited on
Commit
c6df42e
Β·
verified Β·
1 Parent(s): 295d728

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +157 -47
app.py CHANGED
@@ -32,7 +32,7 @@ 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: #3fa45bff; font-size:1.5em;">{"β˜…" * score_int}</span>'
37
 
38
  def make_link(mname):
@@ -51,15 +51,12 @@ def extract_link_text(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 four columns:
56
- - Model (the link, with a fixed width based on the longest model name)
57
  - Provider (extracted from the model field)
58
- - GPU Energy (Wh) plus a horizontal bar whose width is proportional
59
- to the energy value relative to the maximum in the table.
60
- - Score (displayed as stars)
61
  """
62
- # Compute a static width (in pixels) for the Model column based on the longest model name.
63
  if not df.empty:
64
  max_length = max(len(extract_link_text(link)) for link in df['Model'])
65
  else:
@@ -73,7 +70,7 @@ def generate_html_table_from_df(df):
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="AI Provider extracted from the model name">Provider</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():
@@ -92,10 +89,53 @@ def generate_html_table_from_df(df):
92
  html += f'<td style="padding: 8px;">{row["Score"]}</td>'
93
  html += '</tr>'
94
  html += '</tbody></table>'
95
- # Wrap the table in a container so its edges match the dropdown menus.
96
  return f'<div class="table-container">{html}</div>'
97
 
98
- # --- Function to zip all CSV files ---
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
99
  def zip_csv_files():
100
  data_dir = "data/energy"
101
  zip_filename = "data.zip"
@@ -107,7 +147,6 @@ def zip_csv_files():
107
  return zip_filename
108
 
109
  def get_zip_data_link():
110
- """Creates a data URI download link for the ZIP file."""
111
  zip_filename = zip_csv_files()
112
  with open(zip_filename, "rb") as f:
113
  data = f.read()
@@ -127,11 +166,11 @@ def get_model_names_html(task, sort_order="Low to High"):
127
  df = df.iloc[:, 1:]
128
  df['energy_score'] = df['energy_score'].astype(int)
129
  df['gpu_energy_numeric'] = pd.to_numeric(df['total_gpu_energy'], errors='raise') * 1000
130
- # Add the Provider column (text before the slash in the model field)
131
  df['Provider'] = df['model'].apply(lambda x: str(x).split('/')[0])
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
 
@@ -143,13 +182,12 @@ def get_all_model_names_html(sort_order="Low to High"):
143
  df = df.iloc[:, 1:]
144
  df['energy_score'] = df['energy_score'].astype(int)
145
  df['gpu_energy_numeric'] = pd.to_numeric(df['total_gpu_energy'], errors='raise') * 1000
146
- # Add the Provider column here as well.
147
  df['Provider'] = df['model'].apply(lambda x: str(x).split('/')[0])
148
  df['Model'] = df['model'].apply(make_link)
149
  df['Score'] = df['energy_score'].apply(format_stars)
150
  all_df = pd.concat([all_df, df], ignore_index=True)
151
  all_df = all_df.drop_duplicates(subset=['model'])
152
- ascending = True if sort_order == "Low to High" else False
153
  all_df = all_df.sort_values(by='gpu_energy_numeric', ascending=ascending)
154
  return generate_html_table_from_df(all_df)
155
 
@@ -161,11 +199,10 @@ def get_text_generation_model_names_html(model_class, sort_order="Low to High"):
161
  df = df[df['class'] == model_class]
162
  df['energy_score'] = df['energy_score'].astype(int)
163
  df['gpu_energy_numeric'] = pd.to_numeric(df['total_gpu_energy'], errors='raise') * 1000
164
- # Add the Provider column here as well.
165
  df['Provider'] = df['model'].apply(lambda x: str(x).split('/')[0])
166
  df['Model'] = df['model'].apply(make_link)
167
  df['Score'] = df['energy_score'].apply(format_stars)
168
- ascending = True if sort_order == "Low to High" else False
169
  df = df.sort_values(by='gpu_energy_numeric', ascending=ascending)
170
  return generate_html_table_from_df(df)
171
 
@@ -177,34 +214,55 @@ def update_text_generation(selected_display, sort_order):
177
  "C (Multiple Cloud GPUs) >66B parameters": "C"
178
  }
179
  model_class = mapping.get(selected_display, "A")
180
- return get_text_generation_model_names_html(model_class, sort_order)
 
 
 
181
 
182
  def update_image_generation(sort_order):
183
- return get_model_names_html('image_generation.csv', sort_order)
 
 
184
 
185
  def update_text_classification(sort_order):
186
- return get_model_names_html('text_classification.csv', sort_order)
 
 
187
 
188
  def update_image_classification(sort_order):
189
- return get_model_names_html('image_classification.csv', sort_order)
 
 
190
 
191
  def update_image_captioning(sort_order):
192
- return get_model_names_html('image_captioning.csv', sort_order)
 
 
193
 
194
  def update_summarization(sort_order):
195
- return get_model_names_html('summarization.csv', sort_order)
 
 
196
 
197
  def update_asr(sort_order):
198
- return get_model_names_html('asr.csv', sort_order)
 
 
199
 
200
  def update_object_detection(sort_order):
201
- return get_model_names_html('object_detection.csv', sort_order)
 
 
202
 
203
  def update_sentence_similarity(sort_order):
204
- return get_model_names_html('sentence_similarity.csv', sort_order)
 
 
205
 
206
  def update_extractive_qa(sort_order):
207
- return get_model_names_html('question_answering.csv', sort_order)
 
 
208
 
209
  def update_all_tasks(sort_order):
210
  return get_all_model_names_html(sort_order)
@@ -229,7 +287,7 @@ demo = gr.Blocks(css="""
229
  """)
230
 
231
  with demo:
232
- # --- Header Links (at the very top, evenly spaced) ---
233
  gr.HTML(f'''
234
  <div style="display: flex; justify-content: space-evenly; align-items: center; margin-bottom: 20px;">
235
  <a href="https://huggingface.co/spaces/AIEnergyScore/submission_portal" style="text-decoration: none; font-weight: bold; font-size: 1.1em; color: black; font-family: 'Inter', sans-serif;">Submission Portal</a>
@@ -238,19 +296,26 @@ with demo:
238
  <a href="https://huggingface.github.io/AIEnergyScore/#documentation" style="text-decoration: none; font-weight: bold; font-size: 1.1em; color: black; font-family: 'Inter', sans-serif;">Documentation</a>
239
  {get_zip_data_link()}
240
  <a href="https://huggingface.co/spaces/AIEnergyScore/README/discussions" style="text-decoration: none; font-weight: bold; font-size: 1.1em; color: black; font-family: 'Inter', sans-serif;">Community</a>
 
241
  ''')
242
 
243
- # --- Logo (centered) ---
244
  gr.HTML('''
245
- <div style="margin-top: 0px;">
246
  <img src="https://huggingface.co/spaces/AIEnergyScore/Leaderboard/resolve/main/logo.png"
247
  alt="Logo"
248
- style="display: block; margin: 0 auto; max-width: 300px; height: auto;">
 
249
  ''')
250
- # --- Subtitle (centered) ---
251
- gr.Markdown('<div style="text-align: center;">Welcome to the AI Energy Score leaderboard. Select different tasks to see scored models.</div>')
252
 
253
- # --- Tabs for the different tasks ---
 
 
 
 
 
 
254
  with gr.Tabs():
255
  # --- Text Generation Tab ---
256
  with gr.TabItem("Text Generation πŸ’¬"):
@@ -270,9 +335,18 @@ with demo:
270
  label="Sort",
271
  value="Low to High"
272
  )
 
273
  tg_table = gr.HTML(get_text_generation_model_names_html("A", "Low to High"))
274
- model_class_dropdown.change(fn=update_text_generation, inputs=[model_class_dropdown, sort_dropdown_tg], outputs=tg_table)
275
- sort_dropdown_tg.change(fn=update_text_generation, inputs=[model_class_dropdown, sort_dropdown_tg], outputs=tg_table)
 
 
 
 
 
 
 
 
276
 
277
  # --- Image Generation Tab ---
278
  with gr.TabItem("Image Generation πŸ“·"):
@@ -282,7 +356,11 @@ with demo:
282
  value="Low to High"
283
  )
284
  img_table = gr.HTML(get_model_names_html('image_generation.csv', "Low to High"))
285
- sort_dropdown_img.change(fn=update_image_generation, inputs=sort_dropdown_img, outputs=img_table)
 
 
 
 
286
 
287
  # --- Text Classification Tab ---
288
  with gr.TabItem("Text Classification 🎭"):
@@ -292,7 +370,11 @@ with demo:
292
  value="Low to High"
293
  )
294
  tc_table = gr.HTML(get_model_names_html('text_classification.csv', "Low to High"))
295
- sort_dropdown_tc.change(fn=update_text_classification, inputs=sort_dropdown_tc, outputs=tc_table)
 
 
 
 
296
 
297
  # --- Image Classification Tab ---
298
  with gr.TabItem("Image Classification πŸ–ΌοΈ"):
@@ -302,7 +384,11 @@ with demo:
302
  value="Low to High"
303
  )
304
  ic_table = gr.HTML(get_model_names_html('image_classification.csv', "Low to High"))
305
- sort_dropdown_ic.change(fn=update_image_classification, inputs=sort_dropdown_ic, outputs=ic_table)
 
 
 
 
306
 
307
  # --- Image Captioning Tab ---
308
  with gr.TabItem("Image Captioning πŸ“"):
@@ -312,7 +398,11 @@ with demo:
312
  value="Low to High"
313
  )
314
  icap_table = gr.HTML(get_model_names_html('image_captioning.csv', "Low to High"))
315
- sort_dropdown_icap.change(fn=update_image_captioning, inputs=sort_dropdown_icap, outputs=icap_table)
 
 
 
 
316
 
317
  # --- Summarization Tab ---
318
  with gr.TabItem("Summarization πŸ“ƒ"):
@@ -322,7 +412,11 @@ with demo:
322
  value="Low to High"
323
  )
324
  sum_table = gr.HTML(get_model_names_html('summarization.csv', "Low to High"))
325
- sort_dropdown_sum.change(fn=update_summarization, inputs=sort_dropdown_sum, outputs=sum_table)
 
 
 
 
326
 
327
  # --- Automatic Speech Recognition Tab ---
328
  with gr.TabItem("Automatic Speech Recognition πŸ’¬"):
@@ -332,7 +426,11 @@ with demo:
332
  value="Low to High"
333
  )
334
  asr_table = gr.HTML(get_model_names_html('asr.csv', "Low to High"))
335
- sort_dropdown_asr.change(fn=update_asr, inputs=sort_dropdown_asr, outputs=asr_table)
 
 
 
 
336
 
337
  # --- Object Detection Tab ---
338
  with gr.TabItem("Object Detection 🚘"):
@@ -342,7 +440,11 @@ with demo:
342
  value="Low to High"
343
  )
344
  od_table = gr.HTML(get_model_names_html('object_detection.csv', "Low to High"))
345
- sort_dropdown_od.change(fn=update_object_detection, inputs=sort_dropdown_od, outputs=od_table)
 
 
 
 
346
 
347
  # --- Sentence Similarity Tab ---
348
  with gr.TabItem("Sentence Similarity πŸ“š"):
@@ -352,7 +454,11 @@ with demo:
352
  value="Low to High"
353
  )
354
  ss_table = gr.HTML(get_model_names_html('sentence_similarity.csv', "Low to High"))
355
- sort_dropdown_ss.change(fn=update_sentence_similarity, inputs=sort_dropdown_ss, outputs=ss_table)
 
 
 
 
356
 
357
  # --- Extractive QA Tab ---
358
  with gr.TabItem("Extractive QA ❔"):
@@ -362,9 +468,13 @@ with demo:
362
  value="Low to High"
363
  )
364
  qa_table = gr.HTML(get_model_names_html('question_answering.csv', "Low to High"))
365
- sort_dropdown_qa.change(fn=update_extractive_qa, inputs=sort_dropdown_qa, outputs=qa_table)
 
 
 
 
366
 
367
- # --- All Tasks Tab ---
368
  with gr.TabItem("All Tasks πŸ’‘"):
369
  sort_dropdown_all = gr.Dropdown(
370
  choices=["Low to High", "High to Low"],
 
32
  score_int = int(score)
33
  except Exception:
34
  score_int = 0
35
+ # Render stars in green with a slightly larger font.
36
  return f'<span style="color: #3fa45bff; font-size:1.5em;">{"β˜…" * score_int}</span>'
37
 
38
  def make_link(mname):
 
51
 
52
  def generate_html_table_from_df(df):
53
  """
54
+ Generates an HTML table with four columns:
55
+ - Model (with link)
 
56
  - Provider (extracted from the model field)
57
+ - GPU Energy (Wh) plus a horizontal bar
58
+ - Score (as stars)
 
59
  """
 
60
  if not df.empty:
61
  max_length = max(len(extract_link_text(link)) for link in df['Model'])
62
  else:
 
70
  html += '<th style="text-align: left; padding: 8px;" title="Model name with link to Hugging Face">Model</th>'
71
  html += '<th style="text-align: left; padding: 8px;" title="AI Provider extracted from the model name">Provider</th>'
72
  html += '<th style="text-align: left; padding: 8px;" title="GPU energy consumed in Watt-hours for 1,000 queries">GPU Energy (Wh)</th>'
73
+ html += '<th style="text-align: left; padding: 8px;" title="Energy efficiency score">Score</th>'
74
  html += '</tr></thead>'
75
  html += '<tbody>'
76
  for _, row in df.iterrows():
 
89
  html += f'<td style="padding: 8px;">{row["Score"]}</td>'
90
  html += '</tr>'
91
  html += '</tbody></table>'
 
92
  return f'<div class="table-container">{html}</div>'
93
 
94
+ # --- Functions for creating the efficiency difference callout cards ---
95
+ def get_efficiency_diff_for_all():
96
+ """Calculates the efficiency difference across all models."""
97
+ all_df = pd.DataFrame()
98
+ for task in tasks:
99
+ df = pd.read_csv('data/energy/' + task)
100
+ if df.columns[0].startswith("Unnamed:"):
101
+ df = df.iloc[:, 1:]
102
+ df['gpu_energy_numeric'] = pd.to_numeric(df['total_gpu_energy'], errors='raise') * 1000
103
+ all_df = pd.concat([all_df, df], ignore_index=True)
104
+ if all_df.empty:
105
+ return "<div>No data available</div>"
106
+ min_val = all_df['gpu_energy_numeric'].min()
107
+ max_val = all_df['gpu_energy_numeric'].max()
108
+ diff = max_val - min_val
109
+ # A colorful gradient card for global stats.
110
+ return (
111
+ f"<div style='background: linear-gradient(135deg, #f6d365, #fda085); padding: 15px; "
112
+ f"border-radius: 8px; margin: 10px; color: #333;'>"
113
+ f"<strong>All Models:</strong> Efficiency difference is <strong>{diff:.2f} Wh</strong> "
114
+ f"(min: {min_val:.2f} Wh, max: {max_val:.2f} Wh)"
115
+ f"</div>"
116
+ )
117
+
118
+ def get_efficiency_diff_for_task(task_filename):
119
+ """Calculates the efficiency difference for models in a given task."""
120
+ df = pd.read_csv('data/energy/' + task_filename)
121
+ if df.columns[0].startswith("Unnamed:"):
122
+ df = df.iloc[:, 1:]
123
+ df['gpu_energy_numeric'] = pd.to_numeric(df['total_gpu_energy'], errors='raise') * 1000
124
+ if df.empty:
125
+ return "<div>No data available</div>"
126
+ min_val = df['gpu_energy_numeric'].min()
127
+ max_val = df['gpu_energy_numeric'].max()
128
+ diff = max_val - min_val
129
+ # A different gradient for the selected task
130
+ return (
131
+ f"<div style='background: linear-gradient(135deg, #a8e063, #56ab2f); padding: 15px; "
132
+ f"border-radius: 8px; margin: 10px; color: #333;'>"
133
+ f"<strong>Selected Task:</strong> Efficiency difference is <strong>{diff:.2f} Wh</strong> "
134
+ f"(min: {min_val:.2f} Wh, max: {max_val:.2f} Wh)"
135
+ f"</div>"
136
+ )
137
+
138
+ # --- Function to zip all CSV files (unchanged) ---
139
  def zip_csv_files():
140
  data_dir = "data/energy"
141
  zip_filename = "data.zip"
 
147
  return zip_filename
148
 
149
  def get_zip_data_link():
 
150
  zip_filename = zip_csv_files()
151
  with open(zip_filename, "rb") as f:
152
  data = f.read()
 
166
  df = df.iloc[:, 1:]
167
  df['energy_score'] = df['energy_score'].astype(int)
168
  df['gpu_energy_numeric'] = pd.to_numeric(df['total_gpu_energy'], errors='raise') * 1000
169
+ # Add Provider column (text before the slash in the model field)
170
  df['Provider'] = df['model'].apply(lambda x: str(x).split('/')[0])
171
  df['Model'] = df['model'].apply(make_link)
172
  df['Score'] = df['energy_score'].apply(format_stars)
173
+ ascending = (sort_order == "Low to High")
174
  df = df.sort_values(by='gpu_energy_numeric', ascending=ascending)
175
  return generate_html_table_from_df(df)
176
 
 
182
  df = df.iloc[:, 1:]
183
  df['energy_score'] = df['energy_score'].astype(int)
184
  df['gpu_energy_numeric'] = pd.to_numeric(df['total_gpu_energy'], errors='raise') * 1000
 
185
  df['Provider'] = df['model'].apply(lambda x: str(x).split('/')[0])
186
  df['Model'] = df['model'].apply(make_link)
187
  df['Score'] = df['energy_score'].apply(format_stars)
188
  all_df = pd.concat([all_df, df], ignore_index=True)
189
  all_df = all_df.drop_duplicates(subset=['model'])
190
+ ascending = (sort_order == "Low to High")
191
  all_df = all_df.sort_values(by='gpu_energy_numeric', ascending=ascending)
192
  return generate_html_table_from_df(all_df)
193
 
 
199
  df = df[df['class'] == model_class]
200
  df['energy_score'] = df['energy_score'].astype(int)
201
  df['gpu_energy_numeric'] = pd.to_numeric(df['total_gpu_energy'], errors='raise') * 1000
 
202
  df['Provider'] = df['model'].apply(lambda x: str(x).split('/')[0])
203
  df['Model'] = df['model'].apply(make_link)
204
  df['Score'] = df['energy_score'].apply(format_stars)
205
+ ascending = (sort_order == "Low to High")
206
  df = df.sort_values(by='gpu_energy_numeric', ascending=ascending)
207
  return generate_html_table_from_df(df)
208
 
 
214
  "C (Multiple Cloud GPUs) >66B parameters": "C"
215
  }
216
  model_class = mapping.get(selected_display, "A")
217
+ table_html = get_text_generation_model_names_html(model_class, sort_order)
218
+ # Update the task-specific callout for text generation
219
+ task_diff_html = get_efficiency_diff_for_task('text_generation.csv')
220
+ return table_html, task_diff_html
221
 
222
  def update_image_generation(sort_order):
223
+ table_html = get_model_names_html('image_generation.csv', sort_order)
224
+ task_diff_html = get_efficiency_diff_for_task('image_generation.csv')
225
+ return table_html, task_diff_html
226
 
227
  def update_text_classification(sort_order):
228
+ table_html = get_model_names_html('text_classification.csv', sort_order)
229
+ task_diff_html = get_efficiency_diff_for_task('text_classification.csv')
230
+ return table_html, task_diff_html
231
 
232
  def update_image_classification(sort_order):
233
+ table_html = get_model_names_html('image_classification.csv', sort_order)
234
+ task_diff_html = get_efficiency_diff_for_task('image_classification.csv')
235
+ return table_html, task_diff_html
236
 
237
  def update_image_captioning(sort_order):
238
+ table_html = get_model_names_html('image_captioning.csv', sort_order)
239
+ task_diff_html = get_efficiency_diff_for_task('image_captioning.csv')
240
+ return table_html, task_diff_html
241
 
242
  def update_summarization(sort_order):
243
+ table_html = get_model_names_html('summarization.csv', sort_order)
244
+ task_diff_html = get_efficiency_diff_for_task('summarization.csv')
245
+ return table_html, task_diff_html
246
 
247
  def update_asr(sort_order):
248
+ table_html = get_model_names_html('asr.csv', sort_order)
249
+ task_diff_html = get_efficiency_diff_for_task('asr.csv')
250
+ return table_html, task_diff_html
251
 
252
  def update_object_detection(sort_order):
253
+ table_html = get_model_names_html('object_detection.csv', sort_order)
254
+ task_diff_html = get_efficiency_diff_for_task('object_detection.csv')
255
+ return table_html, task_diff_html
256
 
257
  def update_sentence_similarity(sort_order):
258
+ table_html = get_model_names_html('sentence_similarity.csv', sort_order)
259
+ task_diff_html = get_efficiency_diff_for_task('sentence_similarity.csv')
260
+ return table_html, task_diff_html
261
 
262
  def update_extractive_qa(sort_order):
263
+ table_html = get_model_names_html('question_answering.csv', sort_order)
264
+ task_diff_html = get_efficiency_diff_for_task('question_answering.csv')
265
+ return table_html, task_diff_html
266
 
267
  def update_all_tasks(sort_order):
268
  return get_all_model_names_html(sort_order)
 
287
  """)
288
 
289
  with demo:
290
+ # --- Header Links ---
291
  gr.HTML(f'''
292
  <div style="display: flex; justify-content: space-evenly; align-items: center; margin-bottom: 20px;">
293
  <a href="https://huggingface.co/spaces/AIEnergyScore/submission_portal" style="text-decoration: none; font-weight: bold; font-size: 1.1em; color: black; font-family: 'Inter', sans-serif;">Submission Portal</a>
 
296
  <a href="https://huggingface.github.io/AIEnergyScore/#documentation" style="text-decoration: none; font-weight: bold; font-size: 1.1em; color: black; font-family: 'Inter', sans-serif;">Documentation</a>
297
  {get_zip_data_link()}
298
  <a href="https://huggingface.co/spaces/AIEnergyScore/README/discussions" style="text-decoration: none; font-weight: bold; font-size: 1.1em; color: black; font-family: 'Inter', sans-serif;">Community</a>
299
+ </div>
300
  ''')
301
 
302
+ # --- Logo and Subtitle ---
303
  gr.HTML('''
304
+ <div style="margin-top: 0px; text-align: center;">
305
  <img src="https://huggingface.co/spaces/AIEnergyScore/Leaderboard/resolve/main/logo.png"
306
  alt="Logo"
307
+ style="max-width: 300px; height: auto; margin-bottom: 10px;">
308
+ </div>
309
  ''')
310
+ gr.Markdown('<div style="text-align: center; font-size: 1.2em;">Welcome to the AI Energy Score leaderboard. Select different tasks to see scored models.</div>')
 
311
 
312
+ # --- Callout Cards (Row at the Top) ---
313
+ with gr.Row():
314
+ all_models_card = gr.HTML(get_efficiency_diff_for_all())
315
+ # Initially, we show the stats for text_generation as default for the selected task.
316
+ selected_task_card = gr.HTML(get_efficiency_diff_for_task('text_generation.csv'))
317
+
318
+ # --- Tabs for the Different Tasks ---
319
  with gr.Tabs():
320
  # --- Text Generation Tab ---
321
  with gr.TabItem("Text Generation πŸ’¬"):
 
335
  label="Sort",
336
  value="Low to High"
337
  )
338
+ # Two outputs: the table and the task callout card.
339
  tg_table = gr.HTML(get_text_generation_model_names_html("A", "Low to High"))
340
+ model_class_dropdown.change(
341
+ fn=update_text_generation,
342
+ inputs=[model_class_dropdown, sort_dropdown_tg],
343
+ outputs=[tg_table, selected_task_card]
344
+ )
345
+ sort_dropdown_tg.change(
346
+ fn=update_text_generation,
347
+ inputs=[model_class_dropdown, sort_dropdown_tg],
348
+ outputs=[tg_table, selected_task_card]
349
+ )
350
 
351
  # --- Image Generation Tab ---
352
  with gr.TabItem("Image Generation πŸ“·"):
 
356
  value="Low to High"
357
  )
358
  img_table = gr.HTML(get_model_names_html('image_generation.csv', "Low to High"))
359
+ sort_dropdown_img.change(
360
+ fn=update_image_generation,
361
+ inputs=sort_dropdown_img,
362
+ outputs=[img_table, selected_task_card]
363
+ )
364
 
365
  # --- Text Classification Tab ---
366
  with gr.TabItem("Text Classification 🎭"):
 
370
  value="Low to High"
371
  )
372
  tc_table = gr.HTML(get_model_names_html('text_classification.csv', "Low to High"))
373
+ sort_dropdown_tc.change(
374
+ fn=update_text_classification,
375
+ inputs=sort_dropdown_tc,
376
+ outputs=[tc_table, selected_task_card]
377
+ )
378
 
379
  # --- Image Classification Tab ---
380
  with gr.TabItem("Image Classification πŸ–ΌοΈ"):
 
384
  value="Low to High"
385
  )
386
  ic_table = gr.HTML(get_model_names_html('image_classification.csv', "Low to High"))
387
+ sort_dropdown_ic.change(
388
+ fn=update_image_classification,
389
+ inputs=sort_dropdown_ic,
390
+ outputs=[ic_table, selected_task_card]
391
+ )
392
 
393
  # --- Image Captioning Tab ---
394
  with gr.TabItem("Image Captioning πŸ“"):
 
398
  value="Low to High"
399
  )
400
  icap_table = gr.HTML(get_model_names_html('image_captioning.csv', "Low to High"))
401
+ sort_dropdown_icap.change(
402
+ fn=update_image_captioning,
403
+ inputs=sort_dropdown_icap,
404
+ outputs=[icap_table, selected_task_card]
405
+ )
406
 
407
  # --- Summarization Tab ---
408
  with gr.TabItem("Summarization πŸ“ƒ"):
 
412
  value="Low to High"
413
  )
414
  sum_table = gr.HTML(get_model_names_html('summarization.csv', "Low to High"))
415
+ sort_dropdown_sum.change(
416
+ fn=update_summarization,
417
+ inputs=sort_dropdown_sum,
418
+ outputs=[sum_table, selected_task_card]
419
+ )
420
 
421
  # --- Automatic Speech Recognition Tab ---
422
  with gr.TabItem("Automatic Speech Recognition πŸ’¬"):
 
426
  value="Low to High"
427
  )
428
  asr_table = gr.HTML(get_model_names_html('asr.csv', "Low to High"))
429
+ sort_dropdown_asr.change(
430
+ fn=update_asr,
431
+ inputs=sort_dropdown_asr,
432
+ outputs=[asr_table, selected_task_card]
433
+ )
434
 
435
  # --- Object Detection Tab ---
436
  with gr.TabItem("Object Detection 🚘"):
 
440
  value="Low to High"
441
  )
442
  od_table = gr.HTML(get_model_names_html('object_detection.csv', "Low to High"))
443
+ sort_dropdown_od.change(
444
+ fn=update_object_detection,
445
+ inputs=sort_dropdown_od,
446
+ outputs=[od_table, selected_task_card]
447
+ )
448
 
449
  # --- Sentence Similarity Tab ---
450
  with gr.TabItem("Sentence Similarity πŸ“š"):
 
454
  value="Low to High"
455
  )
456
  ss_table = gr.HTML(get_model_names_html('sentence_similarity.csv', "Low to High"))
457
+ sort_dropdown_ss.change(
458
+ fn=update_sentence_similarity,
459
+ inputs=sort_dropdown_ss,
460
+ outputs=[ss_table, selected_task_card]
461
+ )
462
 
463
  # --- Extractive QA Tab ---
464
  with gr.TabItem("Extractive QA ❔"):
 
468
  value="Low to High"
469
  )
470
  qa_table = gr.HTML(get_model_names_html('question_answering.csv', "Low to High"))
471
+ sort_dropdown_qa.change(
472
+ fn=update_extractive_qa,
473
+ inputs=sort_dropdown_qa,
474
+ outputs=[qa_table, selected_task_card]
475
+ )
476
 
477
+ # --- All Tasks Tab (only table update) ---
478
  with gr.TabItem("All Tasks πŸ’‘"):
479
  sort_dropdown_all = gr.Dropdown(
480
  choices=["Low to High", "High to Low"],