AppleSwing commited on
Commit
f041cb6
·
verified ·
1 Parent(s): 3094acc

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +318 -321
app.py CHANGED
@@ -65,340 +65,337 @@ def json_to_row(path: str, metrics: dict) -> dict:
65
  "E2E(s)": f2(e2e_s),
66
  "Batch size": batch_size,
67
  "GPU": gpu_type,
68
- "Cost": f2(cost),
69
- "Accuracy(%)": pct(acc),
 
 
 
 
 
 
 
 
70
  }
71
  return row
72
 
73
 
74
- def load_all_results() -> Tuple[pd.DataFrame, List[str]]:
75
- ds = load_dataset(RESULT_DIR, split="train", token=True)
76
- rows_list = []
77
- file_paths = []
78
- for item in ds:
79
- path = item["path"]
80
- content = item["content"]
81
- metrics = json.loads(content)
82
- row = json_to_row(path, metrics)
83
- rows_list.append(row)
84
- file_paths.append(path)
85
-
86
- df = pd.DataFrame(rows_list)
87
- return df, file_paths
88
-
89
-
90
- def update_table(
91
- dataset_filter,
92
- method_filter,
93
- precision_filter,
94
- model_type_filter,
95
- gpu_filter
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
96
  ):
97
- df_all, all_paths = load_all_results()
98
-
99
- df_filtered = df_all.copy()
100
-
101
- if dataset_filter and dataset_filter != "All":
102
- df_filtered = df_filtered[df_filtered["Dataset"] == dataset_filter]
103
- if method_filter and method_filter != "All":
104
- df_filtered = df_filtered[df_filtered["Method"] == method_filter]
105
- if precision_filter and precision_filter != "All":
106
- df_filtered = df_filtered[df_filtered["Precision"] == precision_filter]
107
- if model_type_filter and model_type_filter != "All":
108
- df_filtered = df_filtered[df_filtered["Model type"] == model_type_filter]
109
- if gpu_filter and gpu_filter != "All":
110
- df_filtered = df_filtered[df_filtered["GPU"] == gpu_filter]
111
-
112
- return df_filtered
113
-
114
-
115
- def get_unique_values(column_name: str) -> list:
116
- df_all, _ = load_all_results()
117
- unique_vals = sorted(df_all[column_name].dropna().unique().tolist())
118
- return ["All"] + unique_vals
119
-
120
-
121
- # FIXED CSS with proper background colors and contrast
122
- custom_css = """
123
- /* Force white background for the entire app */
124
- body, .gradio-container {
125
- background-color: #ffffff !important;
126
- color: #000000 !important;
127
- }
128
-
129
- /* Header Styling */
130
- .header-container {
131
- background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
132
- padding: 30px 40px;
133
- margin-bottom: 30px;
134
- border-radius: 12px;
135
- box-shadow: 0 4px 6px rgba(0,0,0,0.1);
136
- }
137
-
138
- .header-container h1 {
139
- color: #ffffff !important;
140
- font-size: 32px;
141
- font-weight: 700;
142
- margin: 0;
143
- text-shadow: 0 2px 4px rgba(0,0,0,0.2);
144
- }
145
-
146
- .header-container p {
147
- color: #f0f0f0 !important;
148
- font-size: 16px;
149
- margin: 10px 0 0 0;
150
- opacity: 0.95;
151
- }
152
-
153
- /* Main Layout Container */
154
- #main-container {
155
- display: flex;
156
- gap: 20px;
157
- height: calc(100vh - 200px);
158
- min-height: 600px;
159
- }
160
-
161
- /* Sidebar Filters */
162
- #sidebar {
163
- width: 350px;
164
- flex-shrink: 0;
165
- background-color: #ffffff !important;
166
- border-radius: 12px;
167
- padding: 20px;
168
- box-shadow: 0 2px 8px rgba(0,0,0,0.1);
169
- overflow-y: auto;
170
- border: 1px solid #e0e0e0;
171
- }
172
-
173
- #sidebar h3 {
174
- color: #333333 !important;
175
- font-size: 20px;
176
- font-weight: 600;
177
- margin-bottom: 20px;
178
- padding-bottom: 10px;
179
- border-bottom: 2px solid #667eea;
180
- }
181
-
182
- .filter-group {
183
- background-color: #f8f9fa !important;
184
- padding: 15px;
185
- border-radius: 8px;
186
- margin-bottom: 15px;
187
- border: 1px solid #e9ecef;
188
- }
189
-
190
- .filter-group label {
191
- color: #333333 !important;
192
- font-weight: 500;
193
- font-size: 14px;
194
- display: block;
195
- margin-bottom: 8px;
196
- }
197
-
198
- /* Dropdown styling */
199
- .filter-group select,
200
- .filter-group input {
201
- background-color: #ffffff !important;
202
- color: #000000 !important;
203
- border: 1px solid #ced4da !important;
204
- border-radius: 6px;
205
- padding: 8px 12px;
206
- }
207
-
208
- /* Table Container */
209
- #table-container {
210
- flex: 1;
211
- background-color: #ffffff !important;
212
- border-radius: 12px;
213
- padding: 0;
214
- box-shadow: 0 2px 8px rgba(0,0,0,0.1);
215
- overflow: hidden;
216
- display: flex;
217
- flex-direction: column;
218
- border: 1px solid #e0e0e0;
219
- }
220
-
221
- /* CRITICAL: Fixed height table wrapper with scrolling */
222
- .table-wrapper {
223
- flex: 1;
224
- overflow-y: auto !important;
225
- overflow-x: auto !important;
226
- max-height: calc(100vh - 280px) !important;
227
- min-height: 400px;
228
- }
229
-
230
- /* Table Styling */
231
- table {
232
- width: 100%;
233
- border-collapse: collapse;
234
- background-color: #ffffff !important;
235
- color: #000000 !important;
236
- }
237
-
238
- /* Sticky header */
239
- thead {
240
- position: sticky;
241
- top: 0;
242
- z-index: 10;
243
- background-color: #667eea !important;
244
- }
245
-
246
- thead th {
247
- background-color: #667eea !important;
248
- color: #ffffff !important;
249
- padding: 16px 12px;
250
- text-align: left;
251
- font-weight: 600;
252
- font-size: 14px;
253
- border-bottom: 2px solid #5568d3;
254
- white-space: nowrap;
255
- }
256
-
257
- tbody tr {
258
- background-color: #ffffff !important;
259
- border-bottom: 1px solid #e9ecef;
260
- transition: background-color 0.2s;
261
- }
262
-
263
- tbody tr:nth-child(even) {
264
- background-color: #f8f9fa !important;
265
- }
266
-
267
- tbody tr:hover {
268
- background-color: #e7f1ff !important;
269
- }
270
-
271
- tbody td {
272
- padding: 12px;
273
- color: #333333 !important;
274
- font-size: 13px;
275
- border-bottom: 1px solid #e9ecef;
276
- }
277
-
278
- /* Links in table */
279
- tbody td a {
280
- color: #667eea !important;
281
- text-decoration: none;
282
- font-weight: 500;
283
- }
284
-
285
- tbody td a:hover {
286
- color: #764ba2 !important;
287
- text-decoration: underline;
288
- }
289
-
290
- /* Hide Gradio footer */
291
- footer {
292
- display: none !important;
293
- }
294
-
295
- /* Ensure all text elements have proper contrast */
296
- * {
297
- color: inherit;
298
- }
299
-
300
- label, p, span, div {
301
- color: #333333 !important;
302
- }
303
-
304
- /* Responsive Design */
305
- @media (max-width: 1200px) {
306
- #main-container {
307
- flex-direction: column;
308
- height: auto;
309
- }
310
 
311
- #sidebar {
312
- width: 100%;
313
- margin-bottom: 20px;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
314
  }
315
-
316
- .table-wrapper {
317
- max-height: 600px !important;
318
  }
319
- }
320
- """
321
-
322
- with gr.Blocks(css=custom_css, title="MoE-CAP Dashboard") as demo:
323
- # Header
324
- with gr.Row():
325
- gr.HTML("""
326
- <div class="header-container">
327
- <h1>🚀 MoE-CAP Results Dashboard</h1>
328
- <p>Explore and analyze model evaluation results across different datasets, methods, and configurations</p>
329
- </div>
330
- """)
331
-
332
- # Main layout with sidebar and table
333
- with gr.Row(elem_id="main-container"):
334
- # Sidebar with filters
335
- with gr.Column(elem_id="sidebar", scale=0):
336
- gr.HTML("<h3>🔍 Filter Options</h3>")
337
-
338
- with gr.Group(elem_classes="filter-group"):
339
- gr.HTML("<label>📊 Dataset</label>")
340
- dataset_dropdown = gr.Dropdown(
341
- choices=get_unique_values("Dataset"),
342
- value="All",
343
- label="",
344
- interactive=True
 
 
 
 
 
 
 
 
345
  )
346
-
347
- with gr.Group(elem_classes="filter-group"):
348
- gr.HTML("<label>⚙️ Method</label>")
349
- method_dropdown = gr.Dropdown(
350
- choices=get_unique_values("Method"),
351
- value="All",
352
- label="",
353
- interactive=True
 
 
 
 
 
 
 
 
354
  )
355
-
356
- with gr.Group(elem_classes="filter-group"):
357
- gr.HTML("<label>🎯 Precision</label>")
358
- precision_dropdown = gr.Dropdown(
359
- choices=get_unique_values("Precision"),
360
- value="All",
361
- label="",
362
- interactive=True
363
  )
364
-
365
- with gr.Group(elem_classes="filter-group"):
366
- gr.HTML("<label>🤖 Model Type</label>")
367
- model_type_dropdown = gr.Dropdown(
368
- choices=get_unique_values("Model type"),
369
- value="All",
370
- label="",
371
- interactive=True
372
  )
373
-
374
- with gr.Group(elem_classes="filter-group"):
375
- gr.HTML("<label>🖥️ GPU</label>")
376
- gpu_dropdown = gr.Dropdown(
377
- choices=get_unique_values("GPU"),
378
- value="All",
379
- label="",
380
- interactive=True
381
  )
382
-
383
- # Table container with proper scrolling
384
- with gr.Column(elem_id="table-container", scale=1):
385
- gr.HTML('<div class="table-wrapper">')
386
- dataframe_output = gr.Dataframe(
387
- value=update_table("All", "All", "All", "All", "All"),
388
- interactive=False,
389
- wrap=False,
390
- datatype=["html"] + ["str"] * 9,
391
- column_widths=["25%", "10%", "10%", "10%", "10%", "8%", "8%", "8%", "8%", "10%"]
392
- )
393
- gr.HTML('</div>')
394
-
395
- # Update table when filters change
396
- for dropdown in [dataset_dropdown, method_dropdown, precision_dropdown, model_type_dropdown, gpu_dropdown]:
397
- dropdown.change(
398
- fn=update_table,
399
- inputs=[dataset_dropdown, method_dropdown, precision_dropdown, model_type_dropdown, gpu_dropdown],
400
- outputs=dataframe_output
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
401
  )
402
 
 
 
 
 
 
 
 
 
 
403
  if __name__ == "__main__":
404
- demo.launch(share=False)
 
 
65
  "E2E(s)": f2(e2e_s),
66
  "Batch size": batch_size,
67
  "GPU": gpu_type,
68
+ "Accuracy(%)": pct(acc),
69
+ "Cost($)": cost,
70
+ "Decoding T/s": f2(metrics.get("decoding_throughput")),
71
+ "Prefill T/s": f2(metrics.get("prefill_tp")),
72
+ "Prefill<br>S-MBU(%)": pct(metrics.get("prefill_smbu")),
73
+ "Prefill<br>S-MFU(%)": pct(metrics.get("prefill_smfu")),
74
+ "Decoding<br>S-MBU(%)": pct(metrics.get("decoding_smbu")),
75
+ "Decoding<br>S-MFU(%)": pct(metrics.get("decoding_smfu")),
76
+ "TTFT(s)": f2(metrics.get("ttft")),
77
+ "TPOT(s)": f2(metrics.get("tpot")),
78
  }
79
  return row
80
 
81
 
82
+ def build_leaderboard_from_files(files: List[gr.File], prev_rows: list | None = None):
83
+ if prev_rows is None:
84
+ prev_rows = []
85
+
86
+ if not files and prev_rows:
87
+ df = pd.DataFrame(prev_rows)
88
+ raw_models = set()
89
+ for cell in df["Model"].tolist():
90
+ if isinstance(cell, str) and "href" in cell:
91
+ try:
92
+ name = cell.split(">", 1)[1].split("<", 1)[0]
93
+ except Exception:
94
+ name = cell
95
+ else:
96
+ name = cell
97
+ raw_models.add(name)
98
+ links = []
99
+ for name in sorted(raw_models):
100
+ if isinstance(name, str) and "/" in name:
101
+ hf_url = f"https://huggingface.co/{name}"
102
+ links.append(f"[{name}]({hf_url})")
103
+ else:
104
+ links.append(str(name))
105
+ models_str = ", ".join(links)
106
+ summary_md = f"**Loaded {len(prev_rows)} result files.** \n**Models:** {models_str}"
107
+ table_html = df.to_html(escape=False, index=False, classes="metrics-table")
108
+ return summary_md, table_html, prev_rows
109
+
110
+ new_rows = []
111
+ if files:
112
+ for f in files:
113
+ path = f.name
114
+ try:
115
+ with open(path, "r", encoding="utf-8") as fp:
116
+ metrics = json.load(fp)
117
+ new_rows.append(json_to_row(path, metrics))
118
+ except Exception:
119
+ continue
120
+
121
+ all_rows = prev_rows + new_rows
122
+
123
+ if not all_rows:
124
+ empty_html = "<p>No files loaded.</p>"
125
+ return "No files uploaded.", empty_html, []
126
+
127
+ df = pd.DataFrame(all_rows)
128
+
129
+ raw_models = set()
130
+ for cell in df["Model"].tolist():
131
+ if isinstance(cell, str) and "href" in cell:
132
+ try:
133
+ name = cell.split(">", 1)[1].split("<", 1)[0]
134
+ except Exception:
135
+ name = cell
136
+ else:
137
+ name = cell
138
+ raw_models.add(name)
139
+ links = []
140
+ for name in sorted(raw_models):
141
+ if isinstance(name, str) and "/" in name:
142
+ hf_url = f"https://huggingface.co/{name}"
143
+ links.append(f"[{name}]({hf_url})")
144
+ else:
145
+ links.append(str(name))
146
+ models_str = ", ".join(links)
147
+ summary_md = f"**Loaded {len(all_rows)} result files.** \n**Models:** {models_str}"
148
+
149
+ table_html = df.to_html(escape=False, index=False, classes="metrics-table")
150
+
151
+ return summary_md, table_html, all_rows
152
+
153
+
154
+ def load_from_dir(
155
+ dir_path: str,
156
+ selected_tasks: List[str] | None = None,
157
+ selected_frameworks: List[str] | None = None,
158
+ selected_model_types: List[str] | None = None,
159
+ selected_precisions: List[str] | None = None,
160
+ force_refresh: bool = False,
161
  ):
162
+ try:
163
+ pattern = f"hf://datasets/{dir_path}/**/*.json"
164
+ dl_mode = "force_redownload" if force_refresh else None
165
+
166
+ print(f"Fetching from {pattern} (mode={dl_mode})...")
167
+ ds = load_dataset(
168
+ "json",
169
+ data_files={"train": pattern},
170
+ split="train",
171
+ download_mode=dl_mode,
172
+ )
173
+ except Exception as e:
174
+ empty_html = "<p>No files loaded or Dataset not found.</p>"
175
+ return empty_html
176
+
177
+ rows = []
178
+ for i, example in enumerate(ds):
179
+ if isinstance(example, dict):
180
+ metrics = example.get("metrics") or example.get("json") or example
181
+ else:
182
+ metrics = example
183
+ rows.append(json_to_row(f"{dir_path}#{i}", metrics))
184
+
185
+ if not rows:
186
+ empty_html = "<p>No records found.</p>"
187
+ return empty_html
188
+
189
+ df = pd.DataFrame(rows)
190
+
191
+ # Dataset filter
192
+ if selected_tasks is not None:
193
+ lower_selected = [x.lower() for x in selected_tasks]
194
+ df = df[df["Dataset"].astype(str).str.lower().isin(lower_selected)]
195
+
196
+
197
+ # Inference framework filter (Method)
198
+ if selected_frameworks is not None:
199
+ lower_selected = [str(x).lower() for x in selected_frameworks]
200
+ df = df[df["Method"].astype(str).str.lower().isin(lower_selected)]
201
+
202
+ # Model type filter
203
+ if selected_model_types is not None:
204
+ lower_selected = [str(x).lower() for x in selected_model_types]
205
+ df = df[df["Model type"].astype(str).str.lower().isin(lower_selected)]
206
+
207
+ # Precision filter
208
+ if selected_precisions is not None:
209
+ lower_selected = [str(x).lower() for x in selected_precisions]
210
+ df = df[df["Precision"].astype(str).str.lower().isin(lower_selected)]
211
+
212
+ if df.empty:
213
+ empty_html = "<p>No records found.</p>"
214
+ return empty_html
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
215
 
216
+ df = df.fillna("-")
217
+ raw_models = set()
218
+
219
+
220
+ for cell in df["Model"].tolist():
221
+ if isinstance(cell, str) and "href" in cell:
222
+ try:
223
+ name = cell.split(">", 1)[1].split("<", 1)[0]
224
+ except Exception:
225
+ name = cell
226
+ else:
227
+ name = cell
228
+ raw_models.add(name)
229
+
230
+ links = []
231
+ for name in sorted(raw_models):
232
+ if isinstance(name, str) and "/" in name:
233
+ hf_url = f"https://huggingface.co/{name}"
234
+ links.append(f"[{name}]({hf_url})")
235
+ else:
236
+ links.append(str(name))
237
+ models_str = ", ".join(links)
238
+
239
+ # summary_md = (
240
+ # f"**Loaded {len(df)} result files from dataset `{dir_path}`.** \n"
241
+ # f"**Models:** {models_str}"
242
+ # )
243
+
244
+ table_html = df.to_html(escape=False, index=False, classes="metrics-table")
245
+ return table_html
246
+
247
+
248
+ def auto_refresh_from_dir(
249
+ dir_path: str,
250
+ selected_tasks: List[str] | None = None,
251
+ selected_frameworks: List[str] | None = None,
252
+ selected_model_types: List[str] | None = None,
253
+ selected_precisions: List[str] | None = None,
254
+ ):
255
+ return load_from_dir(
256
+ dir_path,
257
+ selected_tasks=selected_tasks,
258
+ selected_frameworks=selected_frameworks,
259
+ selected_model_types=selected_model_types,
260
+ selected_precisions=selected_precisions,
261
+ force_refresh=True,
262
+ )
263
+
264
+
265
+ # Gradio UI
266
+
267
+ def build_app() -> gr.Blocks:
268
+ row_css = """
269
+ .gradio-container table.metrics-table th,
270
+ .gradio-container table.metrics-table td {
271
+ padding-top: 10px;
272
+ padding-bottom: 10px;
273
+ padding-left: 8px;
274
+ padding-right: 8px;
275
+ border: 1px solid #e5e7eb;
276
  }
277
+ .gradio-container table.metrics-table {
278
+ border-collapse: collapse;
279
+ width: 100%;
280
  }
281
+ """
282
+
283
+ with gr.Blocks(title="MoE-CAP Dashboard", css=row_css) as demo:
284
+ gr.Markdown("# MoE-CAP Dashboard")
285
+
286
+ with gr.Row():
287
+ with gr.Column(scale=1):
288
+ gr.Markdown(
289
+ "### Tasks\n"
290
+ "- Mathematics Problem-Solving Performance "
291
+ "[**GSM8K**](https://arxiv.org/abs/2110-14168)\n\n"
292
+ "- Long-Context Understanding — "
293
+ "[**LongBench**](https://arxiv.org/abs/2412.15204)\n"
294
+ "- Massive Multitask Language Understanding "
295
+ "[**MMLU**](https://arxiv.org/abs/2009.03300)\n"
296
+ "- Mathematical Reasoning — "
297
+ "[**NuminaMath**](http://faculty.bicmr.pku.edu.cn/~dongbin/Publications/numina_dataset.pdf)\n"
298
+ "- Extreme Long-Context Evaluation — "
299
+ "[**RULER**](https://arxiv.org/abs/2404.06654)\n\n"
300
+
301
+ "### Columns and Metrics\n"
302
+ "- End-to-End Latency (s) \n"
303
+ "- Batch Size \n"
304
+ "- GPU Type \n"
305
+ "- Accuracy (%) \n"
306
+ "- Cost ($) \n"
307
+ "- Decoding Throughput (tokens/s) \n"
308
+ "- Prefill Throughput (tokens/s) \n"
309
+ "- Prefill S-MBU (%) \n"
310
+ "- Prefill S-MFU (%) \n"
311
+ "- Decoding S-MBU (%) \n"
312
+ "- Decoding S-MFU (%) \n"
313
+ "- TTFT (s) \n"
314
+ "- TPOT (s)"
315
  )
316
+
317
+ with gr.Column(scale=1):
318
+
319
+ dir_path = gr.State(RESULT_DIR)
320
+
321
+ # 1) Tasks filter
322
+ task_filter = gr.CheckboxGroup(
323
+ label="Tasks",
324
+ choices=[
325
+ ("GSM8K", "gsm8k"),
326
+ ("LongBench", "longbench"),
327
+ ("MMLU", "mmlu"),
328
+ ("NuminaMath", "numinamath"),
329
+ ("RULER", "ruler")
330
+ ],
331
+ value=["gsm8k", "longbench", "mmlu", "numinamath", "ruler"]
332
  )
333
+
334
+ # 2) Inference frameworks filter
335
+ framework_filter = gr.CheckboxGroup(
336
+ label="Inference frameworks",
337
+ choices=["sglang", "vllm"],
338
+ value=["sglang", "vllm"],
 
 
339
  )
340
+ # 3) Model types filter
341
+ model_type_filter = gr.CheckboxGroup(
342
+ label="Model types",
343
+ choices=["instruct", "thinking"],
344
+ value=["instruct", "thinking"],
 
 
 
345
  )
346
+ # 4) Precision filter
347
+ precision_filter = gr.CheckboxGroup(
348
+ label="Precision",
349
+ choices=["bfloat16", "fp8"],
350
+ value=["bfloat16", "fp8"],
 
 
 
351
  )
352
+
353
+ # summary_output = gr.Markdown(label="Directory Summary")
354
+ leaderboard_output = gr.HTML(label="Directory Metrics")
355
+
356
+ # demo.load(
357
+ # fn=load_from_dir,
358
+ # inputs=[dir_path, task_filter, framework_filter, model_type_filter, precision_filter],
359
+ # outputs=[leaderboard_output],
360
+ # )
361
+
362
+ demo.load(
363
+ fn=auto_refresh_from_dir,
364
+ inputs=[dir_path, task_filter, framework_filter, model_type_filter, precision_filter],
365
+ outputs=[leaderboard_output],
366
+ )
367
+
368
+
369
+ task_filter.change(
370
+ fn=load_from_dir,
371
+ inputs=[dir_path, task_filter, framework_filter, model_type_filter, precision_filter],
372
+ outputs=[leaderboard_output],
373
+ )
374
+ framework_filter.change(
375
+ fn=load_from_dir,
376
+ inputs=[dir_path, task_filter, framework_filter, model_type_filter, precision_filter],
377
+ outputs=[leaderboard_output],
378
+ )
379
+ model_type_filter.change(
380
+ fn=load_from_dir,
381
+ inputs=[dir_path, task_filter, framework_filter, model_type_filter, precision_filter],
382
+ outputs=[leaderboard_output],
383
+ )
384
+ precision_filter.change(
385
+ fn=load_from_dir,
386
+ inputs=[dir_path, task_filter, framework_filter, model_type_filter, precision_filter],
387
+ outputs=[leaderboard_output],
388
  )
389
 
390
+ timer = gr.Timer(60.0)
391
+ timer.tick(
392
+ fn=auto_refresh_from_dir,
393
+ inputs=[dir_path, task_filter, framework_filter, model_type_filter, precision_filter],
394
+ outputs=[leaderboard_output],
395
+ )
396
+
397
+ return demo
398
+
399
  if __name__ == "__main__":
400
+ app = build_app()
401
+ app.launch()