Spaces:
Running
on
CPU Upgrade
Running
on
CPU Upgrade
from .config import * | |
from .db import * | |
from .models import * | |
import pandas as pd | |
def get_leaderboard(reveal_prelim = False, hide_battle_votes = False, sort_by_elo = False, hide_proprietary = False): | |
conn = get_db() | |
cursor = conn.cursor() | |
if hide_battle_votes: | |
sql = ''' | |
SELECT m.name, | |
SUM(CASE WHEN v.username NOT LIKE '%_battle' AND v.vote = 1 THEN 1 ELSE 0 END) as upvote, | |
SUM(CASE WHEN v.username NOT LIKE '%_battle' AND v.vote = -1 THEN 1 ELSE 0 END) as downvote | |
FROM model m | |
LEFT JOIN vote v ON m.name = v.model | |
GROUP BY m.name | |
''' | |
else: | |
sql = ''' | |
SELECT name, | |
SUM(CASE WHEN vote = 1 THEN 1 ELSE 0 END) as upvote, | |
SUM(CASE WHEN vote = -1 THEN 1 ELSE 0 END) as downvote | |
FROM model | |
LEFT JOIN vote ON model.name = vote.model | |
GROUP BY name | |
''' | |
cursor.execute(sql) | |
data = cursor.fetchall() | |
df = pd.DataFrame(data, columns=['name', 'upvote', 'downvote']) | |
df['name'] = df['name'].replace(model_names).replace('Anonymous Sparkle', 'Fish Speech v1.5') | |
# Calculate total votes and win rate | |
df['votes'] = df['upvote'] + df['downvote'] | |
df['win_rate'] = (df['upvote'] / df['votes'] * 100).round(1) | |
# Remove models with no votes | |
df = df[df['votes'] > 0] | |
# Filter out rows with insufficient votes if not revealing preliminary results | |
if not reveal_prelim: | |
df = df[df['votes'] > 500] | |
## Calculate ELO SCORE (kept as secondary metric) | |
df['elo'] = 1200 | |
for i in range(len(df)): | |
for j in range(len(df)): | |
if i != j: | |
try: | |
expected_a = 1 / (1 + 10 ** ((df['elo'].iloc[j] - df['elo'].iloc[i]) / 400)) | |
expected_b = 1 / (1 + 10 ** ((df['elo'].iloc[i] - df['elo'].iloc[j]) / 400)) | |
actual_a = df['upvote'].iloc[i] / df['votes'].iloc[i] if df['votes'].iloc[i] > 0 else 0.5 | |
actual_b = df['upvote'].iloc[j] / df['votes'].iloc[j] if df['votes'].iloc[j] > 0 else 0.5 | |
df.iloc[i, df.columns.get_loc('elo')] += 32 * (actual_a - expected_a) | |
df.iloc[j, df.columns.get_loc('elo')] += 32 * (actual_b - expected_b) | |
except Exception as e: | |
print(f"Error in ELO calculation for rows {i} and {j}: {str(e)}") | |
continue | |
df['elo'] = round(df['elo']) | |
# Sort based on user preference | |
sort_column = 'elo' if sort_by_elo else 'win_rate' | |
df = df.sort_values(by=sort_column, ascending=False) | |
df['order'] = ['#' + str(i + 1) for i in range(len(df))] | |
# Select and order columns for display | |
df = df[['order', 'name', 'win_rate', 'votes', 'elo']] | |
# Remove proprietary models if filter is enabled | |
if hide_proprietary: | |
df = df[~df['name'].isin(closed_source)] | |
# Convert DataFrame to markdown table with CSS styling | |
markdown_table = """ | |
<style> | |
/* Reset any Gradio table styles */ | |
.leaderboard-table, | |
.leaderboard-table th, | |
.leaderboard-table td { | |
border: none !important; | |
border-collapse: separate !important; | |
border-spacing: 0 !important; | |
} | |
.leaderboard-container { | |
background: var(--background-fill-primary); | |
border: 1px solid var(--border-color-primary); | |
border-radius: 12px; | |
padding: 4px; | |
margin: 10px 0; | |
width: 100%; | |
overflow-x: auto; /* Enable horizontal scroll */ | |
} | |
.leaderboard-scroll { | |
max-height: 600px; | |
overflow-y: auto; | |
border-radius: 8px; | |
} | |
.leaderboard-table { | |
width: 100%; | |
border-spacing: 0; | |
border-collapse: separate; | |
font-size: 15px; | |
line-height: 1.5; | |
table-layout: auto; /* Allow flexible column widths */ | |
} | |
.leaderboard-table th { | |
background: var(--background-fill-secondary); | |
color: var(--body-text-color); | |
font-weight: 600; | |
text-align: left; | |
padding: 12px 16px; | |
position: sticky; | |
top: 0; | |
z-index: 1; | |
} | |
.leaderboard-table th:after { | |
content: ''; | |
position: absolute; | |
left: 0; | |
bottom: 0; | |
width: 100%; | |
border-bottom: 1px solid var(--border-color-primary); | |
} | |
.leaderboard-table td { | |
padding: 12px 16px; | |
color: var(--body-text-color); | |
} | |
.leaderboard-table tr td { | |
border-bottom: 1px solid var(--border-color-primary); | |
} | |
.leaderboard-table tr:last-child td { | |
border-bottom: none; | |
} | |
.leaderboard-table tr:hover td { | |
background: var(--background-fill-secondary); | |
} | |
/* Column-specific styles */ | |
.leaderboard-table .col-rank { | |
width: 70px; | |
min-width: 70px; /* Prevent rank from shrinking */ | |
} | |
.leaderboard-table .col-model { | |
min-width: 200px; /* Minimum width before scrolling */ | |
} | |
.leaderboard-table .col-winrate { | |
width: 100px; | |
min-width: 100px; /* Prevent win rate from shrinking */ | |
} | |
.leaderboard-table .col-votes { | |
width: 100px; | |
min-width: 100px; /* Prevent votes from shrinking */ | |
} | |
.leaderboard-table .col-arena { | |
width: 100px; | |
min-width: 100px; /* Prevent arena score from shrinking */ | |
} | |
.win-rate { | |
display: inline-block; | |
font-weight: 600; | |
padding: 4px 8px; | |
border-radius: 6px; | |
min-width: 65px; | |
text-align: center; | |
} | |
.win-rate-excellent { | |
background-color: var(--color-accent); | |
color: var(--color-accent-foreground); | |
} | |
.win-rate-good { | |
background-color: var(--color-accent-soft); | |
color: var(--body-text-color); | |
} | |
.win-rate-average { | |
background-color: var(--background-fill-secondary); | |
color: var(--body-text-color); | |
border: 1px solid var(--border-color-primary); | |
} | |
.win-rate-below { | |
background-color: var(--error-background-fill); | |
color: var(--body-text-color); | |
} | |
.model-link { | |
color: var(--body-text-color) !important; | |
text-decoration: none !important; | |
border-bottom: 2px dashed rgba(128, 128, 128, 0.3); | |
} | |
.model-link:hover { | |
color: var(--color-accent) !important; | |
border-bottom-color: var(--color-accent) !important; | |
} | |
.proprietary-badge { | |
display: inline-block; | |
font-size: 12px; | |
padding: 2px 6px; | |
border-radius: 4px; | |
background-color: var(--background-fill-secondary); | |
color: var(--body-text-color); | |
margin-left: 6px; | |
border: 1px solid var(--border-color-primary); | |
} | |
</style> | |
<div class="leaderboard-container"> | |
<div class="leaderboard-scroll"> | |
<table class="leaderboard-table"> | |
<thead> | |
<tr> | |
<th class="col-rank">Rank</th> | |
<th class="col-model">Model</th> | |
<th class="col-winrate">Win Rate</th> | |
<th class="col-votes">Votes</th> | |
""" + ("""<th class="col-arena">Arena Score</th>""" if sort_by_elo else "") + """ | |
</tr> | |
</thead> | |
<tbody> | |
""" | |
def get_win_rate_class(win_rate): | |
if win_rate >= 60: | |
return "win-rate-excellent" | |
elif win_rate >= 55: | |
return "win-rate-good" | |
elif win_rate >= 45: | |
return "win-rate-average" | |
else: | |
return "win-rate-below" | |
for _, row in df.iterrows(): | |
win_rate_class = get_win_rate_class(row['win_rate']) | |
win_rate_html = f'<span class="win-rate {win_rate_class}">{row["win_rate"]}%</span>' | |
# Add link to model name if available and proprietary badge if closed source | |
model_name = row['name'] | |
original_model_name = model_name | |
if model_name in model_links: | |
model_name = f'<a href="{model_links[model_name]}" target="_blank" class="model-link">{model_name}</a>' | |
if original_model_name in closed_source: | |
model_name += '<span class="proprietary-badge">Proprietary</span>' | |
markdown_table += f'''<tr> | |
<td class="col-rank">{row['order']}</td> | |
<td class="col-model">{model_name}</td> | |
<td class="col-winrate">{win_rate_html}</td> | |
<td class="col-votes">{row['votes']:,}</td>''' + ( | |
f'''<td class="col-arena">{int(row['elo'])}</td>''' if sort_by_elo else "" | |
) + "</tr>\n" | |
markdown_table += "</tbody></table></div></div>" | |
return markdown_table | |