|
import dash |
|
from dash import html, dcc, Input, Output, State |
|
import dash_ag_grid as dag |
|
import pandas as pd |
|
import numpy as np |
|
from datetime import datetime, timedelta |
|
import base64 |
|
import os |
|
|
|
|
|
MAIN_COLS = ['#P', 'Model', 'UGI π', 'W/10 π', 'NatInt π‘', 'Coding π»', 'Political Lean π', 'Ideology Name'] |
|
AXES_COLS_1 = ['govt', 'dipl', 'econ', 'scty'] |
|
AXES_COLS_2 = ['Federal-Unitary', 'Democratic-Autocratic', 'Security-Freedom', 'Nationalism-Internationalism', |
|
'Militarist-Pacifist', 'Assimilationist-Multiculturalist', 'Collectivize-Privatize', |
|
'Planned-LaissezFaire', 'Isolationism-Globalism', 'Irreligious-Religious', |
|
'Progressive-Traditional', 'Acceleration-Bioconservative'] |
|
|
|
def load_leaderboard_data(csv_file_path): |
|
try: |
|
df = pd.read_csv(csv_file_path, na_values=['NA']) |
|
|
|
|
|
for col in ['Release Date', 'Test Date']: |
|
df[col] = pd.to_datetime(df[col], format='%m/%d/%Y', errors='coerce') |
|
df[col] = df[col].dt.strftime('%Y-%m-%d') |
|
|
|
|
|
two_weeks_ago = (datetime.now() - timedelta(days=14)).strftime('%Y-%m-%d') |
|
|
|
|
|
df['Model_Link'] = df['Model Link'].fillna('') |
|
df['Model_Display'] = df['author/model_name'] |
|
|
|
|
|
df['is_new'] = df.apply( |
|
lambda row: 'π' if pd.notna(row["Test Date"]) and row["Test Date"] >= two_weeks_ago else '', |
|
axis=1 |
|
) |
|
|
|
|
|
df['pinned'] = False |
|
df['selected'] = False |
|
|
|
|
|
numeric_columns = df.select_dtypes(include=[np.number]).columns |
|
for col in numeric_columns: |
|
df[col] = df[col].apply(lambda x: -999999 if pd.isna(x) else round(x, 3)) |
|
|
|
|
|
df['Political Lean π'] = pd.to_numeric(df['Political Lean π'].str.rstrip('%'), errors='coerce') |
|
df['Political Lean π'] = df['Political Lean π'].apply(lambda x: -999999 if pd.isna(x) else x) |
|
|
|
|
|
df = df.replace({-999999: None}) |
|
|
|
return df |
|
except Exception as e: |
|
print(f"Error loading CSV file: {e}") |
|
return pd.DataFrame() |
|
|
|
def load_ideology_descriptions(): |
|
try: |
|
with open('ideologies.js', 'r', encoding='utf-8') as file: |
|
content = file.read() |
|
|
|
start_idx = content.find('[') |
|
end_idx = content.rfind(']') + 1 |
|
if start_idx == -1 or end_idx == 0: |
|
return {} |
|
|
|
ideology_data = content[start_idx:end_idx] |
|
|
|
ideology_data = ideology_data.replace('true', 'True').replace('false', 'False') |
|
ideology_data = eval(ideology_data) |
|
|
|
|
|
return {item['name']: item['desc'] for item in ideology_data} |
|
except Exception as e: |
|
print(f"Error loading ideologies.js: {e}") |
|
return {} |
|
|
|
|
|
IDEOLOGY_DESCRIPTIONS = load_ideology_descriptions() |
|
|
|
def get_kofi_button_base64(): |
|
current_dir = os.path.dirname(os.path.realpath(__file__)) |
|
|
|
|
|
images = {} |
|
for theme in ['light', 'dark']: |
|
filename = 'support_me_on_kofi_white.png' if theme == 'light' else 'support_me_on_kofi_dark.png' |
|
with open(os.path.join(current_dir, f"Images/{filename}"), "rb") as image_file: |
|
images[theme] = base64.b64encode(image_file.read()).decode('utf-8') |
|
return images |
|
|
|
|
|
app = dash.Dash(__name__) |
|
server = app.server |
|
|
|
|
|
app.index_string = ''' |
|
<!DOCTYPE html> |
|
<html> |
|
<head> |
|
{%metas%} |
|
<title>UGI Leaderboard</title> |
|
{%favicon%} |
|
{%css%} |
|
<style> |
|
:root { |
|
--bg-color: #ffffff; |
|
--text-color: #000000; |
|
--grid-bg: #ffffff; |
|
--grid-border: #ddd; |
|
--link-color: #007bff; |
|
--secondary-text: #666; |
|
--pinned-bg: #f5f5f5; |
|
--border-color: #ccc; |
|
} |
|
|
|
@media (prefers-color-scheme: dark) { |
|
:root { |
|
--bg-color: #0d1117; |
|
--text-color: #e6e6e6; |
|
--grid-bg: #161b22; |
|
--grid-border: #30363d; |
|
--link-color: #58a6ff; |
|
--secondary-text: #8b949e; |
|
--pinned-bg: #1c2128; |
|
--border-color: #30363d; |
|
} |
|
} |
|
|
|
body { |
|
font-family: 'Segoe UI', Arial, sans-serif; |
|
margin: 0; |
|
padding: 20px; |
|
background-color: var(--bg-color); |
|
color: var(--text-color); |
|
} |
|
|
|
/* Header and Title Styles */ |
|
.page-title { |
|
text-align: center; |
|
margin: 0; |
|
font-size: 38px; |
|
color: var(--text-color) !important; |
|
} |
|
|
|
.page-subtitle { |
|
text-align: center; |
|
margin: 0; |
|
font-size: 20px; |
|
font-weight: 600; |
|
color: var(--text-color) !important; |
|
} |
|
|
|
/* Filter Styles */ |
|
.model-type-filter label, |
|
#model-type-filter label, |
|
#na-model-filter label { |
|
color: var(--text-color) !important; |
|
margin-right: 10px; |
|
font-weight: bold; |
|
} |
|
|
|
.filter-description { |
|
color: var(--secondary-text) !important; |
|
} |
|
|
|
/* Grid Styles */ |
|
.ag-theme-alpine { |
|
--ag-font-family: 'Segoe UI', Arial, sans-serif; |
|
--ag-font-size: 14px; |
|
--ag-background-color: var(--grid-bg); |
|
--ag-border-color: var(--grid-border); |
|
--ag-header-background-color: var(--grid-bg); |
|
--ag-odd-row-background-color: var(--grid-bg); |
|
--ag-header-foreground-color: var(--text-color); |
|
--ag-foreground-color: var(--text-color); |
|
--ag-row-border-color: var(--grid-border); |
|
} |
|
|
|
.ag-floating-top { |
|
border-bottom: 3px solid var(--border-color) !important; |
|
} |
|
|
|
.ag-floating-top:empty { |
|
border-bottom: none !important; |
|
} |
|
|
|
.pinned-row { |
|
background-color: var(--pinned-bg) !important; |
|
font-weight: 500; |
|
} |
|
|
|
/* Text Alignment Classes */ |
|
.ag-left-aligned-header { |
|
text-align: left !important; |
|
} |
|
|
|
.ag-left-aligned-cell { |
|
text-align: left !important; |
|
} |
|
|
|
.wrap-text { |
|
white-space: normal !important; |
|
line-height: 1.2em; |
|
} |
|
|
|
.no-break { |
|
white-space: nowrap !important; |
|
} |
|
|
|
/* Border Classes */ |
|
.border-left { |
|
border-left: 2px solid var(--grid-border) !important; |
|
} |
|
|
|
.border-right { |
|
border-right: 2px solid var(--grid-border) !important; |
|
} |
|
|
|
/* Link Styles */ |
|
.model-link { |
|
color: var(--link-color) !important; |
|
text-decoration: none; |
|
} |
|
|
|
.model-link:hover { |
|
text-decoration: underline; |
|
} |
|
|
|
.source-link { |
|
color: var(--link-color) !important; |
|
text-decoration: none; |
|
} |
|
|
|
/* Details/Summary Styles */ |
|
.details-summary { |
|
cursor: pointer; |
|
font-weight: bold; |
|
font-size: 1.2em; |
|
margin-top: 20px; |
|
color: var(--text-color) !important; |
|
} |
|
|
|
.ideology-note { |
|
color: var(--secondary-text) !important; |
|
font-size: 0.9em; |
|
} |
|
|
|
/* Markdown Content */ |
|
.markdown-content { |
|
color: var(--text-color) !important; |
|
} |
|
|
|
.markdown-content a { |
|
color: var(--link-color) !important; |
|
} |
|
|
|
/* Ko-fi Button Visibility */ |
|
.kofi-light { |
|
display: none; |
|
} |
|
|
|
.kofi-dark { |
|
display: none; |
|
} |
|
|
|
@media (prefers-color-scheme: light) { |
|
.kofi-light { |
|
display: block; |
|
} |
|
} |
|
|
|
@media (prefers-color-scheme: dark) { |
|
.kofi-dark { |
|
display: block; |
|
} |
|
|
|
/* Dark Theme Specific Overrides */ |
|
.ag-theme-alpine { |
|
--ag-background-color: #161b22 !important; |
|
--ag-header-background-color: #161b22 !important; |
|
--ag-odd-row-background-color: #161b22 !important; |
|
--ag-row-background-color: #161b22 !important; |
|
--ag-header-foreground-color: #e6e6e6 !important; |
|
--ag-foreground-color: #e6e6e6 !important; |
|
--ag-row-border-color: #30363d !important; |
|
--ag-border-color: #30363d !important; |
|
--ag-secondary-border-color: #30363d !important; |
|
--ag-alpine-active-color: #58a6ff !important; |
|
--ag-selected-row-background-color: #1c2128 !important; |
|
--ag-row-hover-color: #1c2128 !important; |
|
} |
|
|
|
.ag-header-cell-filtered { |
|
background-color: rgba(88, 166, 255, 0.1) !important; |
|
} |
|
|
|
input[type="checkbox"] { |
|
accent-color: var(--link-color); |
|
} |
|
|
|
/* Ensure text colors in dark mode */ |
|
.page-title, |
|
.page-subtitle, |
|
.model-type-filter label, |
|
#model-type-filter label, |
|
#na-model-filter label { |
|
color: #e6e6e6 !important; |
|
} |
|
|
|
.filter-description, |
|
.ideology-note { |
|
color: #8b949e !important; |
|
} |
|
} |
|
a:visited { |
|
color: var(--link-color) !important; |
|
} |
|
|
|
.markdown-content a:visited { |
|
color: var(--link-color) !important; |
|
} |
|
</style> |
|
</head> |
|
<body> |
|
{%app_entry%} |
|
<footer> |
|
{%config%} |
|
{%scripts%} |
|
{%renderer%} |
|
</footer> |
|
</body> |
|
</html> |
|
''' |
|
|
|
|
|
df = load_leaderboard_data("ugi-leaderboard-data.csv") |
|
|
|
|
|
def create_numeric_column(field, width=125, sort=None, sortIndex=None, **kwargs): |
|
column = { |
|
"field": field, |
|
"width": width, |
|
"filter": "agNumberColumnFilter", |
|
"filterParams": { |
|
"defaultOption": "inRange", |
|
"filterOptions": ['equals', 'notEqual', 'greaterThan', 'greaterThanOrEqual', 'lessThan', 'lessThanOrEqual', 'inRange'] |
|
}, |
|
"headerClass": "ag-left-aligned-header wrap-text", |
|
"cellClass": "ag-left-aligned-cell", |
|
"wrapHeaderText": True, |
|
"autoHeaderHeight": True, |
|
"suppressSizeToFit": True, |
|
"sortingOrder": ['desc', 'asc'], |
|
"comparator": { |
|
"function": """ |
|
function(valueA, valueB, nodeA, nodeB, isInverted) { |
|
const a = nodeA.data.__sortValue; |
|
const b = nodeB.data.__sortValue; |
|
return a - b; |
|
} |
|
""" |
|
} |
|
} |
|
|
|
|
|
if 'filterParams' in kwargs: |
|
column['filterParams'].update(kwargs['filterParams']) |
|
|
|
if sort: |
|
column["sort"] = sort |
|
if sortIndex is not None: |
|
column["sortIndex"] = sortIndex |
|
return column |
|
|
|
def create_text_column(field, width=120): |
|
return { |
|
"field": field, |
|
"width": width, |
|
"filter": "agTextColumnFilter", |
|
"filterParams": { |
|
"defaultOption": "contains", |
|
"filterOptions": ['contains', 'notContains', 'startsWith', 'endsWith'] |
|
}, |
|
"headerClass": "ag-left-aligned-header wrap-text", |
|
"cellClass": "ag-left-aligned-cell", |
|
"wrapHeaderText": True, |
|
"autoHeaderHeight": True |
|
} |
|
|
|
|
|
columnDefs = [ |
|
{ |
|
"headerName": "π", |
|
"field": "pinned", |
|
"width": 55, |
|
"filter": False, |
|
"suppressMenu": True, |
|
"cellRenderer": "PinRenderer", |
|
"pinned": "left" |
|
}, |
|
{ |
|
"headerName": "", |
|
"field": "is_new", |
|
"width": 55, |
|
"filter": False, |
|
"suppressMenu": True, |
|
"pinned": "left" |
|
}, |
|
{ |
|
"field": "#P", |
|
"width": 115, |
|
"filter": "agNumberColumnFilter", |
|
"filterParams": { |
|
"defaultOption": "inRange", |
|
"filterOptions": ['equals', 'notEqual', 'greaterThan', 'greaterThanOrEqual', 'lessThan', 'lessThanOrEqual', 'inRange'] |
|
}, |
|
"headerClass": "ag-left-aligned-header wrap-text", |
|
"cellClass": "ag-left-aligned-cell", |
|
"wrapHeaderText": True, |
|
"autoHeaderHeight": True, |
|
"suppressSizeToFit": True, |
|
"sortingOrder": ['desc', 'asc'], |
|
"pinned": "left" |
|
}, |
|
{ |
|
"field": "Model_Display", |
|
"headerName": "Model", |
|
"cellRenderer": "ModelLink", |
|
"filter": "agTextColumnFilter", |
|
"filterParams": { |
|
"defaultOption": "contains", |
|
"filterOptions": ['contains', 'notContains', 'startsWith', 'endsWith'] |
|
}, |
|
"width": 380, |
|
"suppressMenu": False, |
|
"pinned": "left", |
|
"headerClass": "ag-left-aligned-header wrap-text", |
|
"wrapHeaderText": True, |
|
"autoHeaderHeight": True |
|
}, |
|
create_numeric_column("UGI π", width=120, sort="desc", sortIndex=0, filterParams={ |
|
"defaultOption": "greaterThanOrEqual" |
|
}), |
|
create_numeric_column("W/10 π", width=130, filterParams={ |
|
"defaultOption": "greaterThanOrEqual", |
|
"filterOptions": ['equals', 'notEqual', 'greaterThan', 'greaterThanOrEqual', 'lessThan', 'lessThanOrEqual', 'inRange'] |
|
}), |
|
{ |
|
"field": "NatInt π‘", |
|
"headerName": "NatInt π‘", |
|
"width": 140, |
|
"filter": "agNumberColumnFilter", |
|
"filterParams": { |
|
"defaultOption": "greaterThanOrEqual", |
|
"filterOptions": ['equals', 'notEqual', 'greaterThan', 'greaterThanOrEqual', 'lessThan', 'lessThanOrEqual', 'inRange'] |
|
}, |
|
"headerClass": "ag-left-aligned-header wrap-text", |
|
"cellClass": "ag-left-aligned-cell", |
|
"wrapHeaderText": True, |
|
"autoHeaderHeight": True, |
|
"suppressSizeToFit": True, |
|
"sortingOrder": ['desc', 'asc'] |
|
}, |
|
create_numeric_column("Coding π»", width=140, filterParams={ |
|
"defaultOption": "greaterThanOrEqual" |
|
}), |
|
{ |
|
"field": "Political Lean π", |
|
"width": 175, |
|
"filter": "agNumberColumnFilter", |
|
"filterParams": { |
|
"defaultOption": "inRange", |
|
"filterOptions": ['equals', 'notEqual', 'greaterThan', 'greaterThanOrEqual', 'lessThan', 'lessThanOrEqual', 'inRange'] |
|
}, |
|
"valueFormatter": { |
|
"function": "d3.format('.1f')(params.value) + '%'" |
|
}, |
|
"sortingOrder": ['desc', 'asc'], |
|
"headerClass": "ag-left-aligned-header wrap-text", |
|
"cellClass": "ag-left-aligned-cell", |
|
"wrapHeaderText": True, |
|
"autoHeaderHeight": True |
|
}, |
|
{ |
|
"headerName": "Ideology", |
|
"field": "Ideology Name", |
|
"width": 160, |
|
"filter": "agTextColumnFilter", |
|
"filterParams": { |
|
"defaultOption": "contains", |
|
"filterOptions": ['contains', 'notContains', 'startsWith', 'endsWith'] |
|
}, |
|
"headerClass": "ag-left-aligned-header wrap-text", |
|
"cellClass": "ag-left-aligned-cell", |
|
"wrapHeaderText": True, |
|
"autoHeaderHeight": True |
|
} |
|
] |
|
|
|
|
|
for i, col in enumerate(AXES_COLS_1): |
|
col_def = create_numeric_column(col, width=105) |
|
if i == 0: |
|
col_def["cellClass"] = ["ag-left-aligned-cell", "border-left"] |
|
elif i == len(AXES_COLS_1) - 1: |
|
col_def["cellClass"] = ["ag-left-aligned-cell", "border-right"] |
|
else: |
|
col_def["cellClass"] = ["ag-left-aligned-cell"] |
|
columnDefs.append(col_def) |
|
for col in AXES_COLS_2: |
|
columnDefs.append(create_numeric_column(col, width=175)) |
|
|
|
|
|
columnDefs.extend([ |
|
{ |
|
"field": "Release Date", |
|
"width": 130, |
|
"filter": "agDateColumnFilter", |
|
"valueFormatter": { |
|
"function": """ |
|
function(params) { |
|
if (!params.value) return ''; |
|
const [year, month, day] = params.value.split('-'); |
|
return `${month}/${day}/${year}`; |
|
} |
|
""" |
|
}, |
|
"comparator": { |
|
"function": """ |
|
function(valueA, valueB) { |
|
if (!valueA && !valueB) return 0; |
|
if (!valueA) return 1; |
|
if (!valueB) return -1; |
|
return valueA.localeCompare(valueB); |
|
} |
|
""" |
|
}, |
|
"cellClass": ["ag-left-aligned-cell", "border-left"], |
|
"headerClass": "ag-left-aligned-header wrap-text", |
|
"wrapHeaderText": True, |
|
"autoHeaderHeight": True, |
|
"sortable": True |
|
}, |
|
{ |
|
"field": "Test Date", |
|
"width": 130, |
|
"filter": "agDateColumnFilter", |
|
"valueFormatter": { |
|
"function": """ |
|
function(params) { |
|
if (!params.value) return ''; |
|
const [year, month, day] = params.value.split('-'); |
|
return `${month}/${day}/${year}`; |
|
} |
|
""" |
|
}, |
|
"comparator": { |
|
"function": """ |
|
function(valueA, valueB) { |
|
if (!valueA && !valueB) return 0; |
|
if (!valueA) return 1; |
|
if (!valueB) return -1; |
|
return valueA.localeCompare(valueB); |
|
} |
|
""" |
|
}, |
|
"cellClass": "ag-left-aligned-cell", |
|
"headerClass": "ag-left-aligned-header wrap-text", |
|
"wrapHeaderText": True, |
|
"autoHeaderHeight": True, |
|
"sortable": True |
|
} |
|
]) |
|
|
|
|
|
dashGridOptions = { |
|
"animateRows": True, |
|
"pagination": False, |
|
"enableCellTextSelection": True, |
|
"ensureDomOrder": True, |
|
"suppressRowClickSelection": True, |
|
"suppressCellFocus": True, |
|
"getRowId": "function(params) { return params.data.Model_Display; }", |
|
"pinnedTopRowData": [], |
|
"sortingOrder": ['desc', 'asc'], |
|
"suppressMaintainUnsortedOrder": True, |
|
"rowBuffer": 10, |
|
"maxBlocksInCache": 2, |
|
"theme": "ag-theme-alpine-dark" if "prefers-color-scheme: dark" else "ag-theme-alpine", |
|
"onGridReady": """ |
|
function(params) { |
|
params.api.addEventListener('sortChanged', function() { |
|
const sortModel = params.api.getSortModel(); |
|
if (sortModel && sortModel.length > 0) { |
|
const field = sortModel[0].colId; |
|
const isAsc = sortModel[0].sort === 'asc'; |
|
|
|
params.api.forEachNode((node, index) => { |
|
const value = node.data[field]; |
|
if (value === null || value === undefined || value === '' || isNaN(value)) { |
|
node.setDataValue('__sortValue', isAsc ? Number.MAX_SAFE_INTEGER : -Number.MAX_SAFE_INTEGER); |
|
} else { |
|
node.setDataValue('__sortValue', Number(value)); |
|
} |
|
}); |
|
|
|
params.api.onSortChanged(); |
|
} |
|
}); |
|
} |
|
""" |
|
} |
|
|
|
|
|
app.layout = html.Div([ |
|
|
|
html.Div([ |
|
html.Div([ |
|
html.A("Contact/Model Requests", href="mailto:[email protected]", className="model-link"), |
|
html.Span(" (or create a HF discussion)") |
|
], style={'float': 'left'}), |
|
html.Div([ |
|
html.A( |
|
html.Img( |
|
src=f"data:image/png;base64,{get_kofi_button_base64()['light']}", |
|
style={'width': '165px'}, |
|
className='kofi-light' |
|
), |
|
href="https://ko-fi.com/dontplantoend", |
|
target="_blank" |
|
), |
|
html.A( |
|
html.Img( |
|
src=f"data:image/png;base64,{get_kofi_button_base64()['dark']}", |
|
style={'width': '165px'}, |
|
className='kofi-dark' |
|
), |
|
href="https://ko-fi.com/dontplantoend", |
|
target="_blank" |
|
) |
|
], style={'float': 'right'}) |
|
], style={'overflow': 'hidden', 'marginBottom': '20px', 'padding': '0 20px'}), |
|
|
|
|
|
html.Div([ |
|
html.H1("π’ UGI Leaderboard", |
|
className="page-title", |
|
style={'fontSize': '38px'}), |
|
html.H2("Uncensored General Intelligence", |
|
className="page-subtitle"), |
|
], style={'marginBottom': '30px'}), |
|
|
|
html.Div([ |
|
html.Div("To filter columns, click the β‘ next to a column's name. On mobile, hold the column name for the menu to appear.", |
|
className='filter-description', |
|
style={'marginBottom': '20px'}), |
|
], style={'padding': '0 20px'}), |
|
|
|
|
|
html.Div([ |
|
html.Div([ |
|
html.Label("Display Models:", className="model-type-filter"), |
|
dcc.Checklist( |
|
id='model-type-filter', |
|
options=[ |
|
{'label': 'Finetune', 'value': 'Is Finetuned'}, |
|
{'label': 'Merge', 'value': 'Is Merged'}, |
|
{'label': 'Foundation', 'value': 'Is Foundation'}, |
|
{'label': 'Proprietary', 'value': 'proprietary'} |
|
], |
|
value=['Is Finetuned', 'Is Merged', 'Is Foundation', 'proprietary'], |
|
inline=True, |
|
style={'display': 'inline-block'} |
|
) |
|
], style={'float': 'left'}), |
|
html.Div([ |
|
dcc.Checklist( |
|
id='na-model-filter', |
|
options=[{'label': 'NA Models', 'value': 'show_na'}], |
|
value=[], |
|
inline=True, |
|
style={'display': 'inline-block'} |
|
) |
|
], style={'float': 'right'}) |
|
], style={'marginBottom': '20px', 'padding': '0 20px', 'overflow': 'hidden'}), |
|
|
|
|
|
html.Div([ |
|
dag.AgGrid( |
|
id='leaderboard-grid', |
|
columnDefs=columnDefs, |
|
rowData=df.to_dict('records'), |
|
defaultColDef={ |
|
"sortable": True, |
|
"resizable": True, |
|
"filter": "agNumberColumnFilter", |
|
"floatingFilter": False, |
|
"sortingOrder": ['desc', 'asc'], |
|
"filterParams": { |
|
"defaultOption": "between" |
|
}, |
|
"comparator": { |
|
"function": """ |
|
function(valueA, valueB, nodeA, nodeB, isInverted) { |
|
const isEmptyA = valueA === null || valueA === undefined || valueA === '' || isNaN(valueA); |
|
const isEmptyB = valueB === null || valueB === undefined || valueB === '' || isNaN(valueB); |
|
|
|
// Force empty values to bottom |
|
if (isEmptyA && !isEmptyB) return 1; |
|
if (!isEmptyA && isEmptyB) return -1; |
|
if (isEmptyA && isEmptyB) return 0; |
|
|
|
// Normal comparison for non-empty values |
|
if (typeof valueA === 'number' && typeof valueB === 'number') { |
|
return valueA - valueB; |
|
} |
|
return String(valueA).localeCompare(String(valueB)); |
|
} |
|
""" |
|
} |
|
}, |
|
dashGridOptions=dashGridOptions, |
|
dangerously_allow_code=True, |
|
className="ag-theme-alpine", |
|
style={"height": "600px", "width": "100%"} |
|
) |
|
], style={'marginBottom': '30px'}), |
|
|
|
|
|
html.Div([ |
|
html.H3("About"), |
|
|
|
html.P([html.Strong("UGI:"), " Uncensored General Intelligence. A measurement of the amount of uncensored/controversial information an LLM knows and is willing to tell the user. The leaderboard is made of roughly 100 questions/tasks, measuring both willingness to answer and accuracy in fact-based controversial questions. The leaderboard's questions are kept private in order to avoid the common problem of not knowing if a model is good or if it was just trained on the test questions."]), |
|
|
|
html.P([html.Strong("W/10:"), " Willingness/10. A more narrow subset of the UGI questions, solely focused on measuring how far a model can be pushed before going against its instructions or refusing to answer."]), |
|
|
|
html.P([html.Strong("NatInt:"), " Natural Intelligence. A common knowledge quiz covering real-world topics like pop culture trivia. Measures if the model understands a diverse range of topics, as opposed to mainly focusing on textbook information and the types of questions commonly tested on benchmarks."]), |
|
|
|
html.P([html.Strong("Coding:"), " A simple 50 question quiz measuring how vast a model's programming knowledge is. Each question is worth 2 points."]), |
|
|
|
html.P([ |
|
html.Strong("Political Lean:"), |
|
" Measures a model's tendency to hold left wing vs right wing political beliefs. Ranges between -100% and 100%, where left wing is left of zero (negative) and right wing is right of zero (positive). Uses the axes of the ", |
|
html.A("12axes", |
|
href="https://politicaltests.github.io/12axes/", |
|
target="_blank", |
|
style={'color': 'var(--link-color)'} |
|
), |
|
" test most aligned with modern left vs right issues:" |
|
], style={'marginBottom': '4px'}), |
|
html.Ul([ |
|
html.Li("Nationalism-Internationalism, Assimilationist-Multiculturalist, Collectivize-Privatize, Planned-LaissezFaire, Isolationism-Globalism, Irreligious-Religious, Progressive-Traditional, and Acceleration-Bioconservative."), |
|
html.Li("Blank if model didn't answer a sufficient number of questions.") |
|
], style={'marginTop': '0px', 'marginBottom': '16px'}), |
|
|
|
html.P("Aggregate Political Scores", style={'marginBottom': '4px'}), |
|
html.Ul([ |
|
html.Li("Govt: Higher = State authority, Lower = Individual liberty"), |
|
html.Li("Dipl: Higher = Global outlook, Lower = National interests"), |
|
html.Li("Econ: Higher = Economic equality, Lower = Market freedom"), |
|
html.Li("Scty: Higher = Progressive values, Lower = Traditional values") |
|
], style={'marginTop': '0px', 'marginBottom': '16px'}), |
|
|
|
html.P([ |
|
"For the 12 political axes, the percentage shown is how much the model aligns with the trait on the ", |
|
html.U("left side of the hyphen"), |
|
"." |
|
]), |
|
|
|
html.Br(), |
|
|
|
html.P("A high UGI but low W/10 could mean for example that the model can provide a lot of accurate sensitive information, but will refuse to form the information into something it sees as offensive or against its rules."), |
|
|
|
html.P("All local models are tested using Q6_K.gguf quants.") |
|
], style={ |
|
'maxWidth': '1200px', |
|
'margin': '0 auto', |
|
'padding': '0 20px', |
|
'color': 'var(--text-color)' |
|
}), |
|
|
|
|
|
html.Details([ |
|
html.Summary("12axes Ideology Descriptions", |
|
className="details-summary"), |
|
html.Div([ |
|
html.I("Only showing ideologies at least one model has.", |
|
className='ideology-note', |
|
style={'fontSize': '0.9em'}), |
|
dcc.Markdown("\n\n".join([ |
|
f"**{ideology}**: {IDEOLOGY_DESCRIPTIONS.get(ideology, 'No description available.')}" |
|
for ideology in sorted(set(df['Ideology Name'].dropna())) |
|
if ideology |
|
]), className='markdown-content'), |
|
html.Div([ |
|
html.A("Source", |
|
href="https://github.com/politicaltests/politicaltests.github.io/blob/main/12axes/ideologies.js", |
|
target="_blank", |
|
className="source-link") |
|
], style={'marginTop': '20px'}) |
|
], style={'paddingTop': '10px'}) |
|
], style={'marginTop': '30px', 'marginBottom': '50px', 'maxWidth': '1200px', 'margin': '30px auto 80px'}) |
|
], style={'maxWidth': '100%', 'margin': '0 auto'}) |
|
|
|
def debug_callback(value): |
|
print("Model filter value:", value) |
|
return value |
|
|
|
@app.callback( |
|
[Output('leaderboard-grid', 'rowData'), |
|
Output('model-type-filter', 'value')], |
|
[Input('model-type-filter', 'value'), |
|
Input('na-model-filter', 'value')], |
|
prevent_initial_call=False |
|
) |
|
def filter_models(selected_types, show_na): |
|
if selected_types is None: |
|
selected_types = [] |
|
|
|
updated_types = selected_types.copy() |
|
|
|
if not updated_types: |
|
return [], updated_types |
|
|
|
filtered_df = df.copy() |
|
mask = pd.Series(False, index=filtered_df.index) |
|
|
|
|
|
if 'Is Finetuned' in updated_types: |
|
if 'Is Merged' in updated_types: |
|
|
|
mask |= filtered_df['Is Finetuned'] |
|
else: |
|
|
|
mask |= (filtered_df['Is Finetuned'] & ~filtered_df['Is Merged']) |
|
elif 'Is Merged' in updated_types: |
|
|
|
mask |= filtered_df['Is Merged'] |
|
|
|
if 'Is Foundation' in updated_types: |
|
mask |= (filtered_df['Is Foundation'] & ~filtered_df['Total Parameters'].isna()) |
|
if 'proprietary' in updated_types: |
|
mask |= filtered_df['Total Parameters'].isna() |
|
|
|
filtered_df = filtered_df[mask] |
|
|
|
|
|
political_columns = ['Political Lean π', 'govt', 'dipl', 'econ', 'scty'] + AXES_COLS_2 |
|
has_na = filtered_df[political_columns].isna().any(axis=1) |
|
|
|
if show_na is None or not show_na: |
|
filtered_df = filtered_df[~has_na] |
|
|
|
filtered_df = filtered_df.sort_values('UGI π', ascending=False) |
|
return filtered_df.to_dict('records'), updated_types |
|
|
|
@app.callback( |
|
Output('ideology-descriptions', 'children'), |
|
[Input('leaderboard-grid', 'rowData')] |
|
) |
|
def update_ideology_descriptions(row_data): |
|
if not row_data: |
|
return [] |
|
|
|
|
|
ideology_descriptions = load_ideology_descriptions() |
|
|
|
|
|
unique_ideologies = sorted(set(row['Ideology Name'] for row in row_data if row.get('Ideology Name'))) |
|
|
|
|
|
markdown_content = [] |
|
for ideology in unique_ideologies: |
|
if ideology in ideology_descriptions: |
|
markdown_content.append(f"**{ideology}**: {ideology_descriptions[ideology]}") |
|
|
|
return dcc.Markdown("\n\n".join(markdown_content), className='markdown-content') |
|
|
|
if __name__ == '__main__': |
|
app.run_server(host='0.0.0.0', port=8050) |
|
app.clientside_callback( |
|
""" |
|
function(n_clicks, current_data) { |
|
if (!n_clicks) return current_data; |
|
const pinnedRows = current_data.filter(row => row.pinned); |
|
const unpinnedRows = current_data.filter(row => !row.pinned); |
|
return [...pinnedRows, ...unpinnedRows]; |
|
} |
|
""", |
|
Output('leaderboard-grid', 'rowData'), |
|
Input('leaderboard-grid', 'cellRendererData'), |
|
State('leaderboard-grid', 'rowData') |
|
) |