init
Browse files- app.py +920 -0
- metadata/medical_data.json +16 -0
- metadata/medical_mm_data.json +310 -0
- requirements.txt +3 -0
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
|