wangrongsheng commited on
Commit
5e28d59
·
verified ·
1 Parent(s): 009e4b1
app.py ADDED
@@ -0,0 +1,920 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import pandas as pd
3
+ import numpy as np
4
+ from datetime import datetime, timedelta
5
+ import random
6
+ import json
7
+ import os
8
+
9
+ # 全局变量存储置顶行
10
+ pinned_rows_global = set()
11
+
12
+ # 从JSON文件读取医疗大语言模型排行榜数据
13
+ def generate_llm_data():
14
+ """从metadata/medical_data.json读取医疗大语言模型排行榜数据"""
15
+ try:
16
+ # 读取JSON文件
17
+ json_path = "metadata/medical_data.json"
18
+ with open(json_path, 'r', encoding='utf-8') as f:
19
+ data = json.load(f)
20
+
21
+ # 转换为DataFrame
22
+ df = pd.DataFrame(data)
23
+
24
+ # 处理null值,将其替换为"-"
25
+ df = df.fillna("-")
26
+
27
+ # 保持使用链接的原始URL格式,稍后在界面中处理
28
+ # 与多模态页面保持一致,不在数据预处理阶段转换HTML
29
+
30
+ # 根据平均分排序(处理null值的情况)
31
+ # 先将平均分为null的行移到最后
32
+ df_with_score = df[df['平均分'] != "-"].copy()
33
+ df_without_score = df[df['平均分'] == "-"].copy()
34
+
35
+ # 对有平均分的数据按平均分降序排序
36
+ if not df_with_score.empty:
37
+ df_with_score = df_with_score.sort_values('平均分', ascending=False)
38
+
39
+ # 合并数据
40
+ df_sorted = pd.concat([df_with_score, df_without_score], ignore_index=True)
41
+
42
+ # 添加排名
43
+ df_sorted['排名'] = range(1, len(df_sorted) + 1)
44
+
45
+ # 重新排列列的顺序:排名、模型名称、平均分、其他字段
46
+ # 获取所有列名
47
+ all_columns = list(df_sorted.columns)
48
+
49
+ # 定义新的列顺序:排名、模型名称、平均分
50
+ new_columns = ['排名', '模型名称', '平均分']
51
+
52
+ # 添加其他列(除了已经包含的列)
53
+ other_columns = [col for col in all_columns if col not in new_columns]
54
+ new_columns.extend(other_columns)
55
+
56
+ # 重新排列列
57
+ df_sorted = df_sorted[new_columns]
58
+
59
+ return df_sorted
60
+
61
+ except FileNotFoundError:
62
+ print(f"警告: 找不到文件 {json_path},使用默认数据")
63
+ # 如果文件不存在,返回空的DataFrame
64
+ return pd.DataFrame()
65
+
66
+ # 从JSON文件读取医疗多模态大模型排行榜数据
67
+ def generate_multimodal_data():
68
+ """从metadata/medical_mm_data.json读取医疗多模态大模型排行榜数据"""
69
+ try:
70
+ # 读取JSON文件
71
+ json_path = "metadata/medical_mm_data.json"
72
+ with open(json_path, 'r', encoding='utf-8') as f:
73
+ data = json.load(f)
74
+
75
+ # 转换为DataFrame
76
+ df = pd.DataFrame(data)
77
+
78
+ # 处理null值,将其替换为"-"
79
+ df = df.fillna("-")
80
+
81
+ # 过滤掉类型为"研究"的数据
82
+ df = df[df['类型'] != '研究']
83
+
84
+ # 保持使用链接的原始URL格式,稍后在界面中处理
85
+ # Gradio Dataframe不支持HTML,我们需要在界面层面处理链接显示
86
+
87
+ # 根据平均分排序(处理null值的情况)
88
+ # 先将平均分为null的行移到最后
89
+ df_with_score = df[df['平均分'] != "-"].copy()
90
+ df_without_score = df[df['平均分'] == "-"].copy()
91
+
92
+ # 对有平均分的数据按平均分降序排序
93
+ if not df_with_score.empty:
94
+ df_with_score = df_with_score.sort_values('平均分', ascending=False)
95
+
96
+ # 合并数据
97
+ df_sorted = pd.concat([df_with_score, df_without_score], ignore_index=True)
98
+
99
+ # 添加排名
100
+ df_sorted['排名'] = range(1, len(df_sorted) + 1)
101
+
102
+ # 重新排列列的顺序:排名、模型名称、平均分、其他字段(删除徽章列)
103
+ # 获取所有列名
104
+ all_columns = list(df_sorted.columns)
105
+
106
+ # 定义新的列顺序:排名、模型名称、平均分
107
+ new_columns = ['排名', '模型名称', '平均分']
108
+
109
+ # 添加其他列(除了已经包含的列)
110
+ other_columns = [col for col in all_columns if col not in new_columns]
111
+ new_columns.extend(other_columns)
112
+
113
+ # 重新排列列
114
+ df_sorted = df_sorted[new_columns]
115
+
116
+ return df_sorted
117
+
118
+ except FileNotFoundError:
119
+ print(f"警告: 找不到文件 {json_path},使用默认数据")
120
+ # 如果文件不存在,返回空的DataFrame
121
+ return pd.DataFrame()
122
+
123
+ def get_llm_leaderboard():
124
+ """获取医疗大语言模型排行榜数据"""
125
+ return generate_llm_data()
126
+
127
+ def generate_llm_html_table(df=None, sort_column=None, sort_order="desc", pinned_rows=None):
128
+ """生成医疗大语言模型排行榜的HTML表格"""
129
+ if df is None:
130
+ df = get_llm_leaderboard()
131
+
132
+ if df.empty:
133
+ return "<p>暂无数据</p>"
134
+
135
+ if pinned_rows is None:
136
+ pinned_rows = set()
137
+
138
+ # 如果指定了排序列,则进行排序
139
+ if sort_column and sort_column in df.columns:
140
+ # 特殊处理排名列:按平均分排序而不是按排名数值排序
141
+ if sort_column == '���名':
142
+ # 按平均分排序来实现排名排序
143
+ df_for_sort = df.copy()
144
+ df_for_sort['平均分_numeric'] = pd.to_numeric(df_for_sort['平均分'], errors='coerce')
145
+
146
+ # 降序表示按平均分从高到低(排名1,2,3...),升序表示按平均分从低到高(排名倒序)
147
+ if sort_order == "desc":
148
+ # 降序:按平均分从高到低,对应排名1,2,3...
149
+ sorted_indices = df_for_sort.sort_values('平均分_numeric', ascending=False, na_position='last').index
150
+ else:
151
+ # 升序:按平均分从低到高,对应排名倒序
152
+ sorted_indices = df_for_sort.sort_values('平均分_numeric', ascending=True, na_position='last').index
153
+
154
+ df = df.loc[sorted_indices].reset_index(drop=True)
155
+ # 处理其他数值列的排序
156
+ elif sort_column in ['平均分', 'MMMU-Med', 'VQA-RAD', 'SLAKE', 'PathVQA', 'PMC-VQA', 'OMVQA', 'MedXQA']:
157
+ # 保存原始数据
158
+ original_data = df.copy()
159
+
160
+ # 创建用于排序的数值列
161
+ df_for_sort = df.copy()
162
+ df_for_sort[sort_column + '_numeric'] = pd.to_numeric(df_for_sort[sort_column], errors='coerce')
163
+
164
+ # 按数值列排序
165
+ if sort_order == "asc":
166
+ sorted_indices = df_for_sort.sort_values(sort_column + '_numeric', ascending=True, na_position='last').index
167
+ else:
168
+ sorted_indices = df_for_sort.sort_values(sort_column + '_numeric', ascending=False, na_position='last').index
169
+
170
+ # 使用排序后的索引重新排列原始数据
171
+ df = original_data.loc[sorted_indices].reset_index(drop=True)
172
+ else:
173
+ # 文本列排序
174
+ ascending = sort_order == "asc"
175
+ df = df.sort_values(sort_column, ascending=ascending, na_position='last').reset_index(drop=True)
176
+
177
+ # 处理置顶行 - 基于排名号而不是索引
178
+ if pinned_rows:
179
+ # 将用户输入的排名号转换为对应的行
180
+ pinned_df = df[df['排名'].isin(pinned_rows)].copy()
181
+ unpinned_df = df[~df['排名'].isin(pinned_rows)].copy()
182
+
183
+ # 置顶行按排名从小到大排序(保持排名顺序)
184
+ if not pinned_df.empty:
185
+ pinned_df = pinned_df.sort_values('排名', ascending=True)
186
+
187
+ # 未置顶行保持当前的排序(不强制按排名排序)
188
+ # 这样可以保持用户选择的排序方式
189
+
190
+ # 合并数据:置顶行在前,其他行在后
191
+ if not pinned_df.empty:
192
+ display_df = pd.concat([pinned_df, unpinned_df], ignore_index=True)
193
+ else:
194
+ display_df = unpinned_df
195
+ else:
196
+ # 没有置顶时,保持当前排序(不强制按排名排序)
197
+ display_df = df.reset_index(drop=True)
198
+
199
+ # 添加行ID用于显示
200
+ display_df['row_id'] = display_df.index
201
+
202
+ # 生成HTML表格
203
+ html = """
204
+ <div style="overflow-x: auto; width: 100%;">
205
+ <style>
206
+ .sort-btn {
207
+ background: none;
208
+ border: none;
209
+ cursor: pointer;
210
+ margin-left: 5px;
211
+ font-size: 12px;
212
+ color: #007bff;
213
+ padding: 2px 4px;
214
+ border-radius: 3px;
215
+ }
216
+ .sort-btn:hover {
217
+ background-color: #e9ecef;
218
+ }
219
+ .sort-btn:active {
220
+ background-color: #dee2e6;
221
+ }
222
+ .pin-btn {
223
+ background: none;
224
+ border: none;
225
+ cursor: pointer;
226
+ font-size: 16px;
227
+ padding: 2px 4px;
228
+ margin-right: 8px;
229
+ border-radius: 3px;
230
+ }
231
+ .pin-btn:hover {
232
+ background-color: #e9ecef;
233
+ }
234
+ .pinned-row {
235
+ background-color: #e3f2fd !important;
236
+ border-left: 4px solid #2196f3 !important;
237
+ }
238
+ </style>
239
+ <table style="width: 100%; border-collapse: collapse; margin: 20px 0; font-size: 14px;">
240
+ <thead>
241
+ <tr style="background-color: #f8f9fa; border-bottom: 2px solid #dee2e6;">
242
+ """
243
+
244
+ # 添加表头(钉子列 + 其他列)
245
+ html += '<th style="padding: 12px 8px; text-align: center; border: 1px solid #dee2e6; font-weight: bold; width: 50px;">📌</th>'
246
+
247
+ for col in display_df.columns:
248
+ if col == 'row_id': # 跳过内部使用的row_id列
249
+ continue
250
+ html += f'''
251
+ <th style="padding: 12px 8px; text-align: left; border: 1px solid #dee2e6; font-weight: bold;">
252
+ {col}
253
+ </th>
254
+ '''
255
+
256
+ html += """
257
+ </tr>
258
+ </thead>
259
+ <tbody>
260
+ """
261
+
262
+ # 添加数据行
263
+ for idx, row in display_df.iterrows():
264
+ row_rank = row['排名'] # 使用排名号而不是row_id
265
+ is_pinned = row_rank in pinned_rows if pinned_rows else False
266
+
267
+ # 为前三名添加特殊样式,置顶行添加置顶样式
268
+ row_style = ""
269
+ if is_pinned:
270
+ row_style = "background-color: #e3f2fd; border-left: 4px solid #2196f3;"
271
+ elif row['排名'] <= 3:
272
+ row_style = "background-color: #fff3cd;"
273
+ elif idx % 2 == 0:
274
+ row_style = "background-color: #f8f9fa;"
275
+
276
+ html += f'<tr style="{row_style}">'
277
+
278
+ # 添加钉子状态显示列
279
+ pin_icon = "📌" if is_pinned else "📍"
280
+ html += f'''
281
+ <td style="padding: 10px 8px; border: 1px solid #dee2e6; text-align: center;">
282
+ <span title="排名: {row_rank}">
283
+ {pin_icon}
284
+ </span>
285
+ </td>
286
+ '''
287
+
288
+ for col in display_df.columns:
289
+ if col == 'row_id': # 跳过内部使用的row_id列
290
+ continue
291
+
292
+ cell_value = row[col]
293
+ cell_style = "padding: 10px 8px; border: 1px solid #dee2e6; text-align: left;"
294
+
295
+ # 特殊处理使用链接列
296
+ if col == "使用链接" and cell_value != "-" and pd.notna(cell_value):
297
+ cell_content = f'<a href="{cell_value}" target="_blank" style="color: #007bff; text-decoration: none;">尝试使用</a>'
298
+ # 特殊处理平均分列
299
+ elif col == "平均分" and cell_value != "-":
300
+ cell_style += " font-weight: bold; color: #28a745;"
301
+ cell_content = str(cell_value)
302
+ else:
303
+ cell_content = str(cell_value) if pd.notna(cell_value) else "-"
304
+
305
+ html += f'<td style="{cell_style}">{cell_content}</td>'
306
+
307
+ html += '</tr>'
308
+
309
+ html += """
310
+ </tbody>
311
+ </table>
312
+ <script>
313
+ // 简化的脚本,只保留必要功能
314
+ console.log('医疗大语言模型排行榜已加载');
315
+ </script>
316
+ </div>
317
+ """
318
+
319
+ return html
320
+
321
+ def get_multimodal_leaderboard():
322
+ """获取医疗多模态大模型排行榜数据"""
323
+ return generate_multimodal_data()
324
+
325
+ def filter_llm_leaderboard(type_filter, min_score):
326
+ """根据条件筛选医疗大语言模型排行榜"""
327
+ df = get_llm_leaderboard()
328
+
329
+ if df.empty:
330
+ return df
331
+
332
+ # 筛选类型
333
+ if type_filter != "全部":
334
+ df = df[df["类型"] == type_filter]
335
+
336
+ # 筛选分数(只对有平均分的数据进行筛选)
337
+ if min_score > 0:
338
+ # 过滤掉平均分为"-"的行,然后筛选分数
339
+ df_with_score = df[df["平均分"] != "-"].copy()
340
+
341
+ if not df_with_score.empty:
342
+ df_with_score = df_with_score[df_with_score["平均分"] >= min_score]
343
+
344
+ # 如果用户设置了最低分数,则不显示没有平均分的模型
345
+ df = df_with_score
346
+
347
+ # 筛选后保持原始排名顺序(基于平均分的排名)
348
+ if not df.empty:
349
+ # 按原始排名排序,保持基于平均分的排名顺序
350
+ df = df.sort_values("排名", ascending=True).reset_index(drop=True)
351
+
352
+ return df
353
+
354
+ def filter_multimodal_leaderboard(type_filter, min_score):
355
+ """根据条件筛选医疗多模态大模型排行榜"""
356
+ df = get_multimodal_leaderboard()
357
+
358
+ if df.empty:
359
+ return df
360
+
361
+ # 筛选类型
362
+ if type_filter != "全部":
363
+ df = df[df["类型"] == type_filter]
364
+
365
+ # 筛选分数(只对有平均分的数据进行筛选)
366
+ if min_score > 0:
367
+ # 过滤掉平均分为"-"的行,然后筛选分数
368
+ df_with_score = df[df["平均分"] != "-"].copy()
369
+
370
+ if not df_with_score.empty:
371
+ df_with_score = df_with_score[df_with_score["平均分"] >= min_score]
372
+
373
+ # 如果用户设置了最低分数,则不显示没有平均分的模型
374
+ df = df_with_score
375
+
376
+ # 筛选后保持原始排名顺序(基于平均分的排名)
377
+ if not df.empty:
378
+ # 按原始排名排序,保持基于平均分的排名顺序
379
+ df = df.sort_values("排名", ascending=True).reset_index(drop=True)
380
+
381
+ return df
382
+
383
+ def generate_multimodal_html_table(df=None, sort_column=None, sort_order="desc", pinned_rows=None):
384
+ """生成医疗多模态大模型排行榜的HTML表格"""
385
+ if df is None:
386
+ df = get_multimodal_leaderboard()
387
+
388
+ if df.empty:
389
+ return "<p>暂无数据</p>"
390
+
391
+ if pinned_rows is None:
392
+ pinned_rows = set()
393
+
394
+ # 如果指定了排序列,则进行排序
395
+ if sort_column and sort_column in df.columns:
396
+ # 特殊处理排名列:按平均分排序而不是按排名数值排序
397
+ if sort_column == '排名':
398
+ # 按平均分排序来实现排名排序
399
+ df_for_sort = df.copy()
400
+ df_for_sort['平均分_numeric'] = pd.to_numeric(df_for_sort['平均分'], errors='coerce')
401
+
402
+ # 降序表示按平均分从高到低(排名1,2,3...),升序表示按平均分从低到高(排名倒序)
403
+ if sort_order == "desc":
404
+ # ��序:按平均分从高到低,对应排名1,2,3...
405
+ sorted_indices = df_for_sort.sort_values('平均分_numeric', ascending=False, na_position='last').index
406
+ else:
407
+ # 升序:按平均分从低到高,对应排名倒序
408
+ sorted_indices = df_for_sort.sort_values('平均分_numeric', ascending=True, na_position='last').index
409
+
410
+ df = df.loc[sorted_indices].reset_index(drop=True)
411
+ # 处理其他数值列的排序
412
+ elif sort_column in ['平均分', 'MMMU-Med', 'VQA-RAD', 'SLAKE', 'PathVQA', 'PMC-VQA', 'OMVQA', 'MedXQA']:
413
+ # 保存原始数据
414
+ original_data = df.copy()
415
+
416
+ # 创建用于排序的数值列
417
+ df_for_sort = df.copy()
418
+ df_for_sort[sort_column + '_numeric'] = pd.to_numeric(df_for_sort[sort_column], errors='coerce')
419
+
420
+ # 按数值列排序
421
+ if sort_order == "asc":
422
+ sorted_indices = df_for_sort.sort_values(sort_column + '_numeric', ascending=True, na_position='last').index
423
+ else:
424
+ sorted_indices = df_for_sort.sort_values(sort_column + '_numeric', ascending=False, na_position='last').index
425
+
426
+ # 使用排序后的索引重新排列原始数据
427
+ df = original_data.loc[sorted_indices].reset_index(drop=True)
428
+ else:
429
+ # 文本列排序
430
+ ascending = sort_order == "asc"
431
+ df = df.sort_values(sort_column, ascending=ascending, na_position='last').reset_index(drop=True)
432
+
433
+ # 处理置顶行 - 基于排名号而不是索引
434
+ if pinned_rows:
435
+ # 将用户输入的排名号转换为对应的行
436
+ pinned_df = df[df['排名'].isin(pinned_rows)].copy()
437
+ unpinned_df = df[~df['排名'].isin(pinned_rows)].copy()
438
+
439
+ # 置顶行按排名从小到大排序(保持排名顺序)
440
+ if not pinned_df.empty:
441
+ pinned_df = pinned_df.sort_values('排名', ascending=True)
442
+
443
+ # 未置顶行保持当前的排序(不强制按排名排序)
444
+ # 这样可以保持用户选择的排序方式
445
+
446
+ # 合并数据:置顶行在前,其他行在后
447
+ if not pinned_df.empty:
448
+ display_df = pd.concat([pinned_df, unpinned_df], ignore_index=True)
449
+ else:
450
+ display_df = unpinned_df
451
+ else:
452
+ # 没有置顶时,保持当前排序(不强制按排名排序)
453
+ display_df = df.reset_index(drop=True)
454
+
455
+ # 添加行ID用于显示
456
+ display_df['row_id'] = display_df.index
457
+
458
+ # 生成HTML表格
459
+ html = """
460
+ <div style="overflow-x: auto; width: 100%;">
461
+ <style>
462
+ .sort-btn {
463
+ background: none;
464
+ border: none;
465
+ cursor: pointer;
466
+ margin-left: 5px;
467
+ font-size: 12px;
468
+ color: #007bff;
469
+ padding: 2px 4px;
470
+ border-radius: 3px;
471
+ }
472
+ .sort-btn:hover {
473
+ background-color: #e9ecef;
474
+ }
475
+ .sort-btn:active {
476
+ background-color: #dee2e6;
477
+ }
478
+ .pin-btn {
479
+ background: none;
480
+ border: none;
481
+ cursor: pointer;
482
+ font-size: 16px;
483
+ padding: 2px 4px;
484
+ margin-right: 8px;
485
+ border-radius: 3px;
486
+ }
487
+ .pin-btn:hover {
488
+ background-color: #e9ecef;
489
+ }
490
+ .pinned-row {
491
+ background-color: #e3f2fd !important;
492
+ border-left: 4px solid #2196f3 !important;
493
+ }
494
+ </style>
495
+ <table style="width: 100%; border-collapse: collapse; margin: 20px 0; font-size: 14px;">
496
+ <thead>
497
+ <tr style="background-color: #f8f9fa; border-bottom: 2px solid #dee2e6;">
498
+ """
499
+
500
+ # 添加表头(钉子列 + 其他列)
501
+ html += '<th style="padding: 12px 8px; text-align: center; border: 1px solid #dee2e6; font-weight: bold; width: 50px;">📌</th>'
502
+
503
+ for col in display_df.columns:
504
+ if col == 'row_id': # 跳过内部使用的row_id列
505
+ continue
506
+ html += f'''
507
+ <th style="padding: 12px 8px; text-align: left; border: 1px solid #dee2e6; font-weight: bold;">
508
+ {col}
509
+ </th>
510
+ '''
511
+
512
+ html += """
513
+ </tr>
514
+ </thead>
515
+ <tbody>
516
+ """
517
+
518
+ # 添加数据行
519
+ for idx, row in display_df.iterrows():
520
+ row_rank = row['排名'] # 使用排名号而不是row_id
521
+ is_pinned = row_rank in pinned_rows if pinned_rows else False
522
+
523
+ # 为前三名添加特殊样式,置顶行添加置顶样式
524
+ row_style = ""
525
+ if is_pinned:
526
+ row_style = "background-color: #e3f2fd; border-left: 4px solid #2196f3;"
527
+ elif row['排名'] <= 3:
528
+ row_style = "background-color: #fff3cd;"
529
+ elif idx % 2 == 0:
530
+ row_style = "background-color: #f8f9fa;"
531
+
532
+ html += f'<tr style="{row_style}">'
533
+
534
+ # 添加钉子状态显示列
535
+ pin_icon = "📌" if is_pinned else "📍"
536
+ html += f'''
537
+ <td style="padding: 10px 8px; border: 1px solid #dee2e6; text-align: center;">
538
+ <span title="排名: {row_rank}">
539
+ {pin_icon}
540
+ </span>
541
+ </td>
542
+ '''
543
+
544
+ for col in display_df.columns:
545
+ if col == 'row_id': # 跳过内部使用的row_id列
546
+ continue
547
+
548
+ cell_value = row[col]
549
+ cell_style = "padding: 10px 8px; border: 1px solid #dee2e6; text-align: left;"
550
+
551
+ # 特殊处理使用链接列
552
+ if col == "使用链接" and cell_value != "-" and pd.notna(cell_value):
553
+ cell_content = f'<a href="{cell_value}" target="_blank" style="color: #007bff; text-decoration: none;">尝试使用</a>'
554
+ # 特殊处理平均分列
555
+ elif col == "平均分" and cell_value != "-":
556
+ cell_style += " font-weight: bold; color: #28a745;"
557
+ cell_content = str(cell_value)
558
+ else:
559
+ cell_content = str(cell_value) if pd.notna(cell_value) else "-"
560
+
561
+ html += f'<td style="{cell_style}">{cell_content}</td>'
562
+
563
+ html += '</tr>'
564
+
565
+ html += """
566
+ </tbody>
567
+ </table>
568
+ <script>
569
+ // 简化的脚本,只保留必要功能
570
+ console.log('医疗多模态大模型排行榜已加载');
571
+ </script>
572
+ </div>
573
+ """
574
+
575
+ return html
576
+
577
+ # 创建Gradio界面
578
+ with gr.Blocks(title="医疗大模型排行榜", theme=gr.themes.Soft(), css="""
579
+ .responsive-table {
580
+ width: 100%;
581
+ overflow-x: auto;
582
+ }
583
+ .responsive-table table {
584
+ width: 100%;
585
+ min-width: 800px;
586
+ }
587
+ /* 确保表格内容不会被截断 */
588
+ .responsive-table td {
589
+ white-space: nowrap;
590
+ overflow: hidden;
591
+ text-overflow: ellipsis;
592
+ }
593
+ /* 平均分列样式 */
594
+ .responsive-table td:nth-child(3) {
595
+ font-weight: bold;
596
+ }
597
+ """) as demo:
598
+ gr.Markdown("# 🤖 医疗大模型排行榜")
599
+ gr.Markdown("欢迎来到 RS Medical LLM Leaderboard 排行榜!这里展示了医疗领域大语言模型和医疗多模态模型的性能排名。我们是一个中立的评估机构,旨在将模型性能公平的进行比较。我们将在未来推出医版 Arena 平台。")
600
+
601
+ with gr.Tabs():
602
+ # 医疗大语言模型排行榜标签页
603
+ with gr.TabItem("💬 医疗大语言模型排行榜"):
604
+ # 筛选选项放在上方
605
+ with gr.Row():
606
+ llm_type_filter = gr.Dropdown(
607
+ choices=["全部", "开源", "商业"],
608
+ value="全部",
609
+ label="模型类型",
610
+ scale=1
611
+ )
612
+ llm_min_score = gr.Slider(
613
+ minimum=0,
614
+ maximum=80,
615
+ value=0,
616
+ step=5,
617
+ label="最低平均分",
618
+ scale=2
619
+ )
620
+ llm_refresh_btn = gr.Button("🔄 刷新数据", variant="primary", scale=1)
621
+
622
+ # 排序选项
623
+ with gr.Row():
624
+ llm_sort_column = gr.Dropdown(
625
+ choices=["排名", "模型名称", "平均分", "MMMU-Med", "VQA-RAD", "SLAKE", "PathVQA", "PMC-VQA", "OMVQA", "MedXQA", "最后更新", "类型"],
626
+ value="排名",
627
+ label="排序列",
628
+ scale=2
629
+ )
630
+ llm_sort_order = gr.Radio(
631
+ choices=[("升序 ↑", "asc"), ("降序 ↓", "desc")],
632
+ value="desc",
633
+ label="排序方式",
634
+ scale=1
635
+ )
636
+ with gr.Column(scale=1):
637
+ llm_default_sort_btn = gr.Button("↩️ 默认排序", variant="primary", scale=1)
638
+
639
+ # 置顶控制
640
+ with gr.Row():
641
+ llm_pin_input = gr.Textbox(
642
+ label="置顶行号(用逗号分隔多个行号,如:1,3,5)",
643
+ placeholder="输入要置顶的行号",
644
+ scale=2
645
+ )
646
+ with gr.Column(scale=1):
647
+ llm_pin_btn = gr.Button("📌 应用置顶", variant="primary", scale=1)
648
+ llm_clear_pin_btn = gr.Button("🗑️ 清除置顶", variant="primary", scale=1)
649
+
650
+ # 置顶状态(隐藏)
651
+ llm_pinned_state = gr.State(value=set())
652
+
653
+ # 使用HTML组件显示带链接的表格
654
+ llm_leaderboard_html = gr.HTML(
655
+ value=generate_llm_html_table(pinned_rows=set()),
656
+ label="医疗大语言模型排行榜"
657
+ )
658
+
659
+ # 医疗多模态大模型排行榜标签页
660
+ with gr.TabItem("👁️ 医疗多模态大模型排��榜"):
661
+ # 筛选选项放在上方
662
+ with gr.Row():
663
+ multimodal_type_filter = gr.Dropdown(
664
+ choices=["全部", "开源", "商业"],
665
+ value="全部",
666
+ label="模型类型",
667
+ scale=1
668
+ )
669
+ multimodal_min_score = gr.Slider(
670
+ minimum=0,
671
+ maximum=80,
672
+ value=0,
673
+ step=5,
674
+ label="最低平均分",
675
+ scale=2
676
+ )
677
+ multimodal_refresh_btn = gr.Button("🔄 刷新数据", variant="primary", scale=1)
678
+
679
+ # 排序选项
680
+ with gr.Row():
681
+ sort_column = gr.Dropdown(
682
+ choices=["排名", "模型名称", "平均分", "MMMU-Med", "VQA-RAD", "SLAKE", "PathVQA", "PMC-VQA", "OMVQA", "MedXQA", "最后更新", "类型"],
683
+ value="排名",
684
+ label="排序列",
685
+ scale=2
686
+ )
687
+ sort_order = gr.Radio(
688
+ choices=[("升序 ↑", "asc"), ("降序 ↓", "desc")],
689
+ value="desc",
690
+ label="排序方式",
691
+ scale=1
692
+ )
693
+ with gr.Column(scale=1):
694
+ # sort_btn = gr.Button("🔄 应用排序", variant="secondary", scale=1)
695
+ default_sort_btn = gr.Button("↩️ 默认排序", variant="primary", scale=1)
696
+
697
+ # 置顶控制
698
+ with gr.Row():
699
+ pin_input = gr.Textbox(
700
+ label="置顶行号(用逗号分隔多个行号,如:1,3,5)",
701
+ placeholder="输入要置顶的行号",
702
+ scale=2
703
+ )
704
+ with gr.Column(scale=1):
705
+ pin_btn = gr.Button("📌 应用置顶", variant="primary", scale=1)
706
+ clear_pin_btn = gr.Button("🗑️ 清除置顶", variant="primary", scale=1)
707
+
708
+ # 置顶状态(隐藏)
709
+ pinned_state = gr.State(value=set())
710
+
711
+ # 使用HTML组件显示带链接的表格
712
+ multimodal_leaderboard_html = gr.HTML(
713
+ value=generate_multimodal_html_table(pinned_rows=set()),
714
+ label="医疗多模态大模型排行榜"
715
+ )
716
+
717
+ # 事件处理函数
718
+ def update_llm_leaderboard_html(type_filter, min_score, sort_col=None, sort_ord="desc", pinned_rows=None):
719
+ if pinned_rows is None:
720
+ pinned_rows = set()
721
+ filtered_df = filter_llm_leaderboard(type_filter, min_score)
722
+ return generate_llm_html_table(filtered_df, sort_col, sort_ord, pinned_rows)
723
+
724
+ def sort_llm_table(type_filter, min_score, sort_col, sort_ord, pinned_rows):
725
+ filtered_df = filter_llm_leaderboard(type_filter, min_score)
726
+ return generate_llm_html_table(filtered_df, sort_col, sort_ord, pinned_rows)
727
+
728
+ def default_sort_llm_table(type_filter, min_score, pinned_rows):
729
+ """恢复默认排序(按平均分排名)"""
730
+ filtered_df = filter_llm_leaderboard(type_filter, min_score)
731
+ html_table = generate_llm_html_table(filtered_df, None, "desc", pinned_rows)
732
+ # 返回表格和重置后的排序选项
733
+ return html_table, "排名", "desc"
734
+
735
+ def apply_llm_pin(pin_input_text, type_filter, min_score, sort_col, sort_ord, current_pinned):
736
+ """应用置顶设置"""
737
+ try:
738
+ if pin_input_text.strip():
739
+ # 解析输入的排名号(用户输入的是1,2,3...)
740
+ pin_numbers = [int(x.strip()) for x in pin_input_text.split(',') if x.strip()]
741
+ # 直接使用排名号,不需要转换
742
+ new_pinned = set(n for n in pin_numbers if n > 0)
743
+ else:
744
+ new_pinned = set()
745
+
746
+ filtered_df = filter_llm_leaderboard(type_filter, min_score)
747
+ html_table = generate_llm_html_table(filtered_df, sort_col, sort_ord, new_pinned)
748
+ return html_table, new_pinned
749
+ except ValueError:
750
+ # 如果输入格式错误,保持当前状态
751
+ filtered_df = filter_llm_leaderboard(type_filter, min_score)
752
+ html_table = generate_llm_html_table(filtered_df, sort_col, sort_ord, current_pinned)
753
+ return html_table, current_pinned
754
+
755
+ def clear_llm_pin(type_filter, min_score, sort_col, sort_ord):
756
+ """清除所有置顶"""
757
+ filtered_df = filter_llm_leaderboard(type_filter, min_score)
758
+ html_table = generate_llm_html_table(filtered_df, sort_col, sort_ord, set())
759
+ return html_table, set(), ""
760
+
761
+ def update_multimodal_leaderboard_html(type_filter, min_score, sort_col=None, sort_ord="desc", pinned_rows=None):
762
+ if pinned_rows is None:
763
+ pinned_rows = set()
764
+ filtered_df = filter_multimodal_leaderboard(type_filter, min_score)
765
+ return generate_multimodal_html_table(filtered_df, sort_col, sort_ord, pinned_rows)
766
+
767
+ def sort_multimodal_table(type_filter, min_score, sort_col, sort_ord, pinned_rows):
768
+ filtered_df = filter_multimodal_leaderboard(type_filter, min_score)
769
+ return generate_multimodal_html_table(filtered_df, sort_col, sort_ord, pinned_rows)
770
+
771
+ def default_sort_multimodal_table(type_filter, min_score, pinned_rows):
772
+ """恢复默认排序(按平均分排名)"""
773
+ filtered_df = filter_multimodal_leaderboard(type_filter, min_score)
774
+ html_table = generate_multimodal_html_table(filtered_df, None, "desc", pinned_rows)
775
+ # 返回表格和重置后的排序选项
776
+ return html_table, "排名", "desc"
777
+
778
+ def apply_pin(pin_input_text, type_filter, min_score, sort_col, sort_ord, current_pinned):
779
+ """应用置顶设置"""
780
+ try:
781
+ if pin_input_text.strip():
782
+ # 解析输入的排名号(用户输入的是1,2,3...)
783
+ pin_numbers = [int(x.strip()) for x in pin_input_text.split(',') if x.strip()]
784
+ # 直接使用排名号,不需要转换
785
+ new_pinned = set(n for n in pin_numbers if n > 0)
786
+ else:
787
+ new_pinned = set()
788
+
789
+ filtered_df = filter_multimodal_leaderboard(type_filter, min_score)
790
+ html_table = generate_multimodal_html_table(filtered_df, sort_col, sort_ord, new_pinned)
791
+ return html_table, new_pinned
792
+ except ValueError:
793
+ # 如果输入格式错误,保持当前状态
794
+ filtered_df = filter_multimodal_leaderboard(type_filter, min_score)
795
+ html_table = generate_multimodal_html_table(filtered_df, sort_col, sort_ord, current_pinned)
796
+ return html_table, current_pinned
797
+
798
+ def clear_pin(type_filter, min_score, sort_col, sort_ord):
799
+ """清除所有置顶"""
800
+ filtered_df = filter_multimodal_leaderboard(type_filter, min_score)
801
+ html_table = generate_multimodal_html_table(filtered_df, sort_col, sort_ord, set())
802
+ return html_table, set(), ""
803
+
804
+ # 绑定事件 - 医疗大语言模型
805
+ llm_type_filter.change(
806
+ fn=sort_llm_table,
807
+ inputs=[llm_type_filter, llm_min_score, llm_sort_column, llm_sort_order, llm_pinned_state],
808
+ outputs=llm_leaderboard_html
809
+ )
810
+
811
+ llm_min_score.change(
812
+ fn=sort_llm_table,
813
+ inputs=[llm_type_filter, llm_min_score, llm_sort_column, llm_sort_order, llm_pinned_state],
814
+ outputs=llm_leaderboard_html
815
+ )
816
+
817
+ llm_refresh_btn.click(
818
+ fn=sort_llm_table,
819
+ inputs=[llm_type_filter, llm_min_score, llm_sort_column, llm_sort_order, llm_pinned_state],
820
+ outputs=llm_leaderboard_html
821
+ )
822
+
823
+ # 排序功能绑定 - 医疗大语言模型
824
+ llm_sort_column.change(
825
+ fn=sort_llm_table,
826
+ inputs=[llm_type_filter, llm_min_score, llm_sort_column, llm_sort_order, llm_pinned_state],
827
+ outputs=llm_leaderboard_html
828
+ )
829
+
830
+ llm_sort_order.change(
831
+ fn=sort_llm_table,
832
+ inputs=[llm_type_filter, llm_min_score, llm_sort_column, llm_sort_order, llm_pinned_state],
833
+ outputs=llm_leaderboard_html
834
+ )
835
+
836
+ # 默认排序按钮绑定 - 医疗大语言模型
837
+ llm_default_sort_btn.click(
838
+ fn=default_sort_llm_table,
839
+ inputs=[llm_type_filter, llm_min_score, llm_pinned_state],
840
+ outputs=[llm_leaderboard_html, llm_sort_column, llm_sort_order]
841
+ )
842
+
843
+ # 置顶功能绑定 - 医疗大语言模型
844
+ llm_pin_btn.click(
845
+ fn=apply_llm_pin,
846
+ inputs=[llm_pin_input, llm_type_filter, llm_min_score, llm_sort_column, llm_sort_order, llm_pinned_state],
847
+ outputs=[llm_leaderboard_html, llm_pinned_state]
848
+ )
849
+
850
+ llm_clear_pin_btn.click(
851
+ fn=clear_llm_pin,
852
+ inputs=[llm_type_filter, llm_min_score, llm_sort_column, llm_sort_order],
853
+ outputs=[llm_leaderboard_html, llm_pinned_state, llm_pin_input]
854
+ )
855
+
856
+ # 绑定事件 - 医疗多模态大模型
857
+ multimodal_type_filter.change(
858
+ fn=sort_multimodal_table,
859
+ inputs=[multimodal_type_filter, multimodal_min_score, sort_column, sort_order, pinned_state],
860
+ outputs=multimodal_leaderboard_html
861
+ )
862
+
863
+ multimodal_min_score.change(
864
+ fn=sort_multimodal_table,
865
+ inputs=[multimodal_type_filter, multimodal_min_score, sort_column, sort_order, pinned_state],
866
+ outputs=multimodal_leaderboard_html
867
+ )
868
+
869
+ multimodal_refresh_btn.click(
870
+ fn=sort_multimodal_table,
871
+ inputs=[multimodal_type_filter, multimodal_min_score, sort_column, sort_order, pinned_state],
872
+ outputs=multimodal_leaderboard_html
873
+ )
874
+
875
+ # 排序功能绑定
876
+ # sort_btn.click(
877
+ # fn=sort_multimodal_table,
878
+ # inputs=[multimodal_type_filter, multimodal_min_score, sort_column, sort_order, pinned_state],
879
+ # outputs=multimodal_leaderboard_html
880
+ # )
881
+
882
+ sort_column.change(
883
+ fn=sort_multimodal_table,
884
+ inputs=[multimodal_type_filter, multimodal_min_score, sort_column, sort_order, pinned_state],
885
+ outputs=multimodal_leaderboard_html
886
+ )
887
+
888
+ sort_order.change(
889
+ fn=sort_multimodal_table,
890
+ inputs=[multimodal_type_filter, multimodal_min_score, sort_column, sort_order, pinned_state],
891
+ outputs=multimodal_leaderboard_html
892
+ )
893
+
894
+ # 默认排序按钮绑定
895
+ default_sort_btn.click(
896
+ fn=default_sort_multimodal_table,
897
+ inputs=[multimodal_type_filter, multimodal_min_score, pinned_state],
898
+ outputs=[multimodal_leaderboard_html, sort_column, sort_order]
899
+ )
900
+
901
+ # 置顶功能绑定
902
+ pin_btn.click(
903
+ fn=apply_pin,
904
+ inputs=[pin_input, multimodal_type_filter, multimodal_min_score, sort_column, sort_order, pinned_state],
905
+ outputs=[multimodal_leaderboard_html, pinned_state]
906
+ )
907
+
908
+ clear_pin_btn.click(
909
+ fn=clear_pin,
910
+ inputs=[multimodal_type_filter, multimodal_min_score, sort_column, sort_order],
911
+ outputs=[multimodal_leaderboard_html, pinned_state, pin_input]
912
+ )
913
+
914
+ if __name__ == "__main__":
915
+ demo.launch(
916
+ # server_name="0.0.0.0",
917
+ # server_port=7863,
918
+ share=False,
919
+ show_error=True
920
+ )
metadata/medical_data.json ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [
2
+ {
3
+ "模型名称": "GPT-4.1",
4
+ "MMMU-Med": 89.6,
5
+ "VQA-RAD": 75.6,
6
+ "SLAKE": 77.7,
7
+ "PathVQA": 89.1,
8
+ "PMC-VQA": 77.0,
9
+ "OMVQA": 30.9,
10
+ "MedXQA": 49.9,
11
+ "平均分": 70.0,
12
+ "最后更新": "2025-07-14",
13
+ "类型": "商业",
14
+ "使用链接": "https://www.google.com/ "
15
+ }
16
+ ]
metadata/medical_mm_data.json ADDED
@@ -0,0 +1,310 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [
2
+ {
3
+ "模型名称": "GPT-4.1",
4
+ "MMMU-Med": 75.2,
5
+ "VQA-RAD": 65.0,
6
+ "SLAKE": 72.2,
7
+ "PathVQA": 55.5,
8
+ "PMC-VQA": 55.2,
9
+ "OMVQA": 75.5,
10
+ "MedXQA": 45.2,
11
+ "平均分": 63.4,
12
+ "最后更新": "2025-07-14",
13
+ "类型": "商业",
14
+ "使用链接": "https://www.google.com/ "
15
+ },
16
+ {
17
+ "模型名称": "Claude Sonnet 4",
18
+ "MMMU-Med": 74.6,
19
+ "VQA-RAD": 67.6,
20
+ "SLAKE": 70.6,
21
+ "PathVQA": 54.2,
22
+ "PMC-VQA": 54.4,
23
+ "OMVQA": 65.5,
24
+ "MedXQA": 43.3,
25
+ "平均分": 61.5,
26
+ "最后更新": "2025-07-14",
27
+ "类型": "商业",
28
+ "使用链接": "https://www.google.com/ "
29
+ },
30
+ {
31
+ "模型名称": "Gemini-2.5-Flash",
32
+ "MMMU-Med": 76.9,
33
+ "VQA-RAD": 68.5,
34
+ "SLAKE": 75.8,
35
+ "PathVQA": 55.4,
36
+ "PMC-VQA": 55.4,
37
+ "OMVQA": 71.0,
38
+ "MedXQA": 52.8,
39
+ "平均分": 65.1,
40
+ "最后更新": "2025-07-14",
41
+ "类型": "商业",
42
+ "使用链接": "https://www.google.com/ "
43
+ },
44
+ {
45
+ "模型名称": "BiomedGPT♡",
46
+ "MMMU-Med": 24.9,
47
+ "VQA-RAD": 16.6,
48
+ "SLAKE": 13.6,
49
+ "PathVQA": 11.3,
50
+ "PMC-VQA": 27.6,
51
+ "OMVQA": 27.9,
52
+ "MedXQA": null,
53
+ "平均分": null,
54
+ "最后更新": "2025-07-14",
55
+ "类型": "开源",
56
+ "使用链接": "https://www.google.com/ "
57
+ },
58
+ {
59
+ "模型名称": "Med-R1-2B◇",
60
+ "MMMU-Med": 34.8,
61
+ "VQA-RAD": 39.6,
62
+ "SLAKE": 54.5,
63
+ "PathVQA": 15.3,
64
+ "PMC-VQA": 47.4,
65
+ "OMVQA": null,
66
+ "MedXQA": 21.1,
67
+ "平均分": null,
68
+ "最后更新": "2025-07-14",
69
+ "类型": "开源",
70
+ "使用链接": "https://www.google.com/ "
71
+ },
72
+ {
73
+ "模型名称": "MedVLM-R1-2B",
74
+ "MMMU-Med": 42.6,
75
+ "VQA-RAD": 48.6,
76
+ "SLAKE": 56.0,
77
+ "PathVQA": 32.5,
78
+ "PMC-VQA": 47.6,
79
+ "OMVQA": 77.7,
80
+ "MedXQA": 20.4,
81
+ "平均分": 45.4,
82
+ "最后更新": "2025-07-14",
83
+ "类型": "开源",
84
+ "使用链接": "https://www.google.com/ "
85
+ },
86
+ {
87
+ "模型名称": "MedGemma-4B-IT",
88
+ "MMMU-Med": 43.7,
89
+ "VQA-RAD": 72.5,
90
+ "SLAKE": 76.4,
91
+ "PathVQA": 48.8,
92
+ "PMC-VQA": 49.9,
93
+ "OMVQA": 69.8,
94
+ "MedXQA": 22.3,
95
+ "平均分": 54.8,
96
+ "最后更新": "2025-07-14",
97
+ "类型": "开源",
98
+ "使用链接": "https://www.google.com/ "
99
+ },
100
+ {
101
+ "模型名称": "LLaVA-Med-7B",
102
+ "MMMU-Med": 29.3,
103
+ "VQA-RAD": 37.7,
104
+ "SLAKE": 48.0,
105
+ "PathVQA": 38.8,
106
+ "PMC-VQA": 30.5,
107
+ "OMVQA": 44.3,
108
+ "MedXQA": 20.3,
109
+ "平均分": 37.8,
110
+ "最后更新": "2025-07-14",
111
+ "类型": "开源",
112
+ "使用链接": "https://www.google.com/ "
113
+ },
114
+ {
115
+ "模型名称": "HuatuoGPT-V-7B",
116
+ "MMMU-Med": 47.3,
117
+ "VQA-RAD": 30.0,
118
+ "SLAKE": 67.8,
119
+ "PathVQA": 48.0,
120
+ "PMC-VQA": 53.3,
121
+ "OMVQA": 74.2,
122
+ "MedXQA": 21.6,
123
+ "平均分": 54.2,
124
+ "最后更新": "2025-07-14",
125
+ "类型": "开源",
126
+ "使用链接": "https://www.google.com/ "
127
+ },
128
+ {
129
+ "模型名称": "BioMediX2-8B",
130
+ "MMMU-Med": 39.8,
131
+ "VQA-RAD": 44.9,
132
+ "SLAKE": 57.7,
133
+ "PathVQA": 37.0,
134
+ "PMC-VQA": 43.5,
135
+ "OMVQA": 63.3,
136
+ "MedXQA": 21.8,
137
+ "平均分": 44.6,
138
+ "最后更新": "2025-07-14",
139
+ "类型": "开源",
140
+ "使用链接": "https://www.google.com/ "
141
+ },
142
+ {
143
+ "模型名称": "Qwen2.5VL-7B",
144
+ "MMMU-Med": 50.0,
145
+ "VQA-RAD": 50.6,
146
+ "SLAKE": 47.4,
147
+ "PathVQA": 44.1,
148
+ "PMC-VQA": 51.9,
149
+ "OMVQA": 63.6,
150
+ "MedXQA": 22.3,
151
+ "平均分": 50.0,
152
+ "最后更新": "2025-07-14",
153
+ "类型": "开源",
154
+ "使用链接": "https://www.google.com/ "
155
+ },
156
+ {
157
+ "模型名称": "InternVL2.5-8B",
158
+ "MMMU-Med": 53.5,
159
+ "VQA-RAD": 59.4,
160
+ "SLAKE": 69.0,
161
+ "PathVQA": 42.1,
162
+ "PMC-VQA": 51.3,
163
+ "OMVQA": 81.3,
164
+ "MedXQA": 21.7,
165
+ "平均分": 54.0,
166
+ "最后更新": "2025-07-14",
167
+ "类型": "开源",
168
+ "使用链接": "https://www.google.com/ "
169
+ },
170
+ {
171
+ "模型名称": "InternVL3-8B",
172
+ "MMMU-Med": 59.2,
173
+ "VQA-RAD": 61.4,
174
+ "SLAKE": 72.8,
175
+ "PathVQA": 48.6,
176
+ "PMC-VQA": 53.8,
177
+ "OMVQA": 79.1,
178
+ "MedXQA": 22.4,
179
+ "平均分": 57.3,
180
+ "最后更新": "2025-07-14",
181
+ "类型": "开源",
182
+ "使用链接": "https://www.google.com/ "
183
+ },
184
+ {
185
+ "模型名称": "Lingshu-7B",
186
+ "MMMU-Med": 54.0,
187
+ "VQA-RAD": 67.9,
188
+ "SLAKE": 83.1,
189
+ "PathVQA": 61.9,
190
+ "PMC-VQA": 56.3,
191
+ "OMVQA": 82.9,
192
+ "MedXQA": 26.7,
193
+ "平均分": 61.8,
194
+ "最后更新": "2025-07-14",
195
+ "类型": "开源",
196
+ "使用链接": "https://www.google.com/ "
197
+ },
198
+ {
199
+ "模型名称": "HealthGPT-14B",
200
+ "MMMU-Med": 49.6,
201
+ "VQA-RAD": 65.0,
202
+ "SLAKE": 66.1,
203
+ "PathVQA": 56.7,
204
+ "PMC-VQA": 56.4,
205
+ "OMVQA": 75.2,
206
+ "MedXQA": 24.7,
207
+ "平均分": 56.2,
208
+ "最后更新": "2025-07-14",
209
+ "类型": "开源",
210
+ "使用链接": "https://www.google.com/ "
211
+ },
212
+ {
213
+ "模型名称": "HuatuoGPT-V-34B",
214
+ "MMMU-Med": 51.8,
215
+ "VQA-RAD": 61.4,
216
+ "SLAKE": 69.5,
217
+ "PathVQA": 44.4,
218
+ "PMC-VQA": 56.6,
219
+ "OMVQA": 74.0,
220
+ "MedXQA": 22.1,
221
+ "平均分": 54.3,
222
+ "最后更新": "2025-07-14",
223
+ "类型": "开源",
224
+ "使用链接": "https://www.google.com/ "
225
+ },
226
+ {
227
+ "模型名称": "MedDr-40B♡",
228
+ "MMMU-Med": 25.2,
229
+ "VQA-RAD": 42.0,
230
+ "SLAKE": 53.5,
231
+ "PathVQA": 13.9,
232
+ "PMC-VQA": 64.3,
233
+ "OMVQA": null,
234
+ "MedXQA": null,
235
+ "平均分": null,
236
+ "最后更新": "2025-07-14",
237
+ "类型": "开源",
238
+ "使用链接": "https://www.google.com/ "
239
+ },
240
+ {
241
+ "模型名称": "InternVL3-14B",
242
+ "MMMU-Med": 63.1,
243
+ "VQA-RAD": 66.1,
244
+ "SLAKE": 72.8,
245
+ "PathVQA": 48.0,
246
+ "PMC-VQA": 54.1,
247
+ "OMVQA": 78.9,
248
+ "MedXQA": 23.1,
249
+ "平均分": 58.0,
250
+ "最后更新": "2025-07-14",
251
+ "类型": "开源",
252
+ "使用链接": "https://www.google.com/ "
253
+ },
254
+ {
255
+ "模型名称": "Qwen2.5V-32B",
256
+ "MMMU-Med": 59.6,
257
+ "VQA-RAD": 71.2,
258
+ "SLAKE": 71.2,
259
+ "PathVQA": 41.9,
260
+ "PMC-VQA": 54.5,
261
+ "OMVQA": 68.8,
262
+ "MedXQA": 25.2,
263
+ "平均分": 56.1,
264
+ "最后更新": "2025-07-14",
265
+ "类型": "开源",
266
+ "使用链接": "https://www.google.com/ "
267
+ },
268
+ {
269
+ "模型名称": "InternVL2.5-38B",
270
+ "MMMU-Med": 64.5,
271
+ "VQA-RAD": 70.6,
272
+ "SLAKE": 75.2,
273
+ "PathVQA": 57.2,
274
+ "PMC-VQA": 79.9,
275
+ "OMVQA": 24.4,
276
+ "MedXQA": 41.1,
277
+ "平均分": 59.0,
278
+ "最后更新": "2025-07-14",
279
+ "类型": "开源",
280
+ "使用链接": "https://www.google.com/ "
281
+ },
282
+ {
283
+ "模型名称": "InternVL3-38B",
284
+ "MMMU-Med": 65.2,
285
+ "VQA-RAD": 72.7,
286
+ "SLAKE": 71.0,
287
+ "PathVQA": 51.0,
288
+ "PMC-VQA": 56.6,
289
+ "OMVQA": 79.8,
290
+ "MedXQA": 25.2,
291
+ "平均分": 59.4,
292
+ "最后更新": "2025-07-14",
293
+ "类型": "开源",
294
+ "使用链接": "https://www.google.com/ "
295
+ },
296
+ {
297
+ "模型名称": "Lingshu-32B",
298
+ "MMMU-Med": 62.3,
299
+ "VQA-RAD": 76.5,
300
+ "SLAKE": 89.2,
301
+ "PathVQA": 65.9,
302
+ "PMC-VQA": 57.9,
303
+ "OMVQA": 83.4,
304
+ "MedXQA": 30.9,
305
+ "平均分": 66.6,
306
+ "最后更新": "2025-07-14",
307
+ "类型": "开源",
308
+ "使用链接": "https://www.google.com/ "
309
+ }
310
+ ]
requirements.txt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ gradio==5.9.1
2
+ pandas>=1.5.0
3
+ numpy>=1.24.0