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 def load_leaderboard_data(csv_file_path): try: df = pd.read_csv(csv_file_path, na_values=['NA']) # Add type sort value def get_type_sort_value(row): if row['Base']: return 0 # B return 4 df['model_type_sort'] = df.apply(get_type_sort_value, axis=1) # Store model name and link separately df['Model_Link'] = df['Model Link'].fillna('') df['Model_Display'] = df['author/model_name'] # Add pinned and selected columns df['pinned'] = False df['selected'] = False # Round numeric columns and handle NA values numeric_columns = df.select_dtypes(include=[np.number]).columns for col in numeric_columns: df[col] = df[col].apply(lambda x: None if pd.isna(x) else round(x, 3)) # Sort with multiple keys in the required order df = df.sort_values( by=['Score', '8k 🪡', '16k 🪡'], ascending=[False, False, False] # Score -> 8k -> 16k ) return df except Exception as e: print(f"Error loading CSV file: {e}") return pd.DataFrame() # Initialize the Dash app app = dash.Dash(__name__, external_stylesheets=[ "https://use.fontawesome.com/releases/v5.15.4/css/all.css" ]) server = app.server # Custom CSS app.index_string = ''' {%metas%} Fey's Multi-Needle & Behavior Leaderboard {%favicon%} {%css%} {%app_entry%} ''' # Load data df = load_leaderboard_data("fmnb-leaderboard-data.csv") # Define helper functions 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; } """ } } # Update filterParams if provided in kwargs 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 } # Define column configurations columnDefs = [ { "headerName": "📌", "field": "pinned", "width": 55, "filter": False, "suppressMenu": True, "cellRenderer": "PinRenderer", "sortable": False, "pinned": "left" }, { "field": "Model_Display", "headerName": "Model", "cellRenderer": "ModelLink", "filter": "agTextColumnFilter", "filterParams": { "defaultOption": "contains", "filterOptions": ['contains', 'notContains', 'startsWith', 'endsWith'] }, "width": 420, "suppressMenu": False, "pinned": "left", "headerClass": "ag-left-aligned-header wrap-text", "wrapHeaderText": True, "autoHeaderHeight": True }, { "field": "Score", "FontWeight": 700, "width": 110, "filter": "agNumberColumnFilter", "filterParams": { "defaultOption": "greaterThanOrEqual" }, "headerClass": "ag-left-aligned-header wrap-text", "cellClass": ["ag-left-aligned-cell", "border-left"], "wrapHeaderText": True, "autoHeaderHeight": True, "suppressSizeToFit": True, "sortingOrder": ['desc', 'asc'], "cellRenderer": "ScoreRenderer" }, { "headerName": "Behavior", "headerClass": "ag-left-aligned-header wrap-text", "cellClass": ["ag-left-aligned-cell", "border-left"], "field": "Behavior", "width": 120, "filter": False, "suppressMenu": True, "cellRenderer": "BehaviorRenderer", "sortable": True, "sortingOrder": ['asc', 'desc'] }, { "field": "8k 🪡", "headerName": "8k 🪡", "width": 100, "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", "border-left"], "wrapHeaderText": True, "autoHeaderHeight": True, "suppressSizeToFit": True, "sortingOrder": ['desc', 'asc'] }, create_numeric_column("16k 🪡", width=100, filterParams={ "defaultOption": "greaterThanOrEqual" }), # Misc Columns { "field": "Size", "width": 100, "filter": "agNumberColumnFilter", "filterParams": { "defaultOption": "equals", "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'], }, { "field": "model_type_sort", "hide": True }, { "headerName": "Type", "field": "model_type_sort", # sort field directly "width": 90, "filter": False, "suppressMenu": True, "cellRenderer": "TypeRenderer", "sortable": True, "sortingOrder": ['asc', 'desc'] }, { "headerName": "Settings", "field": "Settings", "width": 120, "filter": False, "suppressMenu": True, "cellClass": "ag-left-aligned-cell", }, { "headerName": "New", "field": "New", "width": 70, "filter": False, "suppressMenu": True, "cellClass": "ag-left-aligned-cell", } ] # Define the grid options with postSort dashGridOptions = { "animateRows": True, "pagination": False, "enableCellTextSelection": True, "ensureDomOrder": True, "suppressRowClickSelection": True, "suppressCellFocus": True, "getRowId": "params => params.data.Model_Display", "pinnedTopRowData": [], "suppressMaintainUnsortedOrder": True, "suppressMultiSort": True, "rowBuffer": 10, "maxBlocksInCache": 2, "icons": { "menu": '' }, "theme": "ag-theme-alpine-dark" if "prefers-color-scheme: dark" else "ag-theme-alpine", "columnState": { "function": """ function() { return { columnVisibility: {} }; } """ } } # Define the layout app.layout = html.Div([ dcc.Store(id='pinned-models-store', data=[]), # Title html.Div([ html.H1("🪡 Fey's MNB Leaderboard 🪡", className="page-title", style={'fontSize': '38px'}), html.H2("Multi-Needle & Behavior Evaluation", className="page-subtitle"), ], style={'marginBottom': '30px'}), # Notice # html.Div( # html.P( # "None", # style={'textAlign': 'center', 'color': 'red', 'fontSize': '0.9em'} # ) # ), # Grid 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%"}, enableEnterpriseModules=False, getRowId="params.data.Model_Display" ) ], style={'marginBottom': '10px'}), # Description html.Div([ html.H3("Info", style={'fontSize': '22px', 'marginBottom': '0px'}), html.P([html.Strong(""), "This latest reiteration of the leaderboard has finally made it to Hugging Face with extended functionality based on the UGI leaderboard, enjoy!"], style={'marginTop': '7px', 'marginBottom': '4px'}), html.P([html.Strong("Score:"), " Primarily based on the scoring in the multi-needle test at 8k / 16k context, weighted towards 16k."], style={'marginTop': '7px', 'marginBottom': '4px'}), html.P([html.Strong("Behavior:"), " Qualitative assessment of the model's behavior during the evaluation. User discretion is advised, as it only has a minor impact on the final score."], style={'marginTop': '7px', 'marginBottom': '4px'}), html.P([html.Strong("Difficulty:"), " The current difficulty is only set at a medium level. (Silver Tier 1)"], style={'marginTop': '7px', 'marginBottom': '4px'}), html.P([html.Strong("Version:"), " 4.0"], style={'marginTop': '7px', 'marginBottom': '4px'}), html.Br(), html.Details([ html.Summary("Recommended Settings", style={ 'fontWeight': 'bold', 'fontSize': '1em', 'marginLeft': '0px', 'cursor': 'pointer' }), html.Ul([ html.Br(), html.Li(["1: Recommended to manually set a RoPE Frequency of 2650000 with Nemo based models when using >8k context.",html.Br(),"LLama.cpp: --rope-freq-base 2650000 (RoPE Base in KoboldCpp)",html.Br(),"EXL2: rope_alpha 2.65"]), html.Br(), html.Li("2: Recommended to set as an additional stopping token when using these models with ChatML."), ], style={'marginTop': '0px', 'marginBottom': '16px', 'marginLeft': '40px'}) ], style={'marginBottom': '16px'}), ], style={ 'maxWidth': '1200px', 'margin': '0 auto', 'padding': '0 20px', 'color': 'var(--text-color)' }), ], style={'maxWidth': '100%', 'margin': '0 auto'}) if __name__ == '__main__': app.run_server(host='0.0.0.0', port=8050) app.clientside_callback( """ function(n_clicks) { if (!window.gridApi) return; const pinnedRows = window.gridApi.getGridOption('pinnedTopRowData') || []; if (pinnedRows.length > 0) { const pinnedIds = new Set(pinnedRows.map(row => row.Model_Display)); const currentRows = []; window.gridApi.forEachNode(node => { if (!pinnedIds.has(node.data.Model_Display)) { currentRows.push(node.data); } }); window.gridApi.setGridOption('rowData', currentRows); } return window.dash_clientside.no_update; } """, Output('leaderboard-grid', 'rowData'), Input('model-type-filter', 'value') )