Spaces:
Sleeping
Sleeping
Define Multi FinBen Model list. Display only matched models
Browse files
frontend/src/pages/LeaderboardPage/components/Leaderboard/hooks/useDataUtils.js
CHANGED
|
@@ -4,6 +4,7 @@ import {
|
|
| 4 |
parseSearchQuery,
|
| 5 |
getValueByPath,
|
| 6 |
} from "../utils/searchUtils";
|
|
|
|
| 7 |
|
| 8 |
// Calculate min/max averages
|
| 9 |
export const useAverageRange = (data) => {
|
|
@@ -38,8 +39,9 @@ export const useColorGenerator = (minAverage, maxAverage) => {
|
|
| 38 |
// Process data with boolean standardization
|
| 39 |
export const useProcessedData = (data, averageMode, visibleColumns) => {
|
| 40 |
return useMemo(() => {
|
|
|
|
| 41 |
let processed = data.map((item) => {
|
| 42 |
-
//
|
| 43 |
const greekDatasets = ['multifin', 'qa', 'fns', 'finnum', 'fintext'];
|
| 44 |
const greekScores = greekDatasets
|
| 45 |
.filter(dataset => item.evaluations[dataset]?.normalized_score !== undefined)
|
|
@@ -49,21 +51,21 @@ export const useProcessedData = (data, averageMode, visibleColumns) => {
|
|
| 49 |
? greekScores.reduce((a, b) => a + b, 0) / greekScores.length
|
| 50 |
: null;
|
| 51 |
|
| 52 |
-
//
|
| 53 |
const enhancedEvaluations = {
|
| 54 |
...item.evaluations,
|
| 55 |
greek_average: greekAverage
|
| 56 |
};
|
| 57 |
|
| 58 |
-
//
|
| 59 |
const includedEvaluations = {};
|
| 60 |
-
//
|
| 61 |
Object.entries(item.evaluations).forEach(([key, value]) => {
|
| 62 |
if (!greekDatasets.includes(key)) {
|
| 63 |
includedEvaluations[key] = value;
|
| 64 |
}
|
| 65 |
});
|
| 66 |
-
//
|
| 67 |
if (greekAverage !== null) {
|
| 68 |
includedEvaluations.greek_average = { normalized_score: greekAverage };
|
| 69 |
}
|
|
@@ -98,7 +100,7 @@ export const useProcessedData = (data, averageMode, visibleColumns) => {
|
|
| 98 |
return {
|
| 99 |
...item,
|
| 100 |
features: standardizedFeatures,
|
| 101 |
-
evaluations: enhancedEvaluations, //
|
| 102 |
model: {
|
| 103 |
...item.model,
|
| 104 |
has_chat_template: Boolean(item.model.has_chat_template),
|
|
@@ -107,7 +109,58 @@ export const useProcessedData = (data, averageMode, visibleColumns) => {
|
|
| 107 |
};
|
| 108 |
});
|
| 109 |
|
| 110 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 111 |
if (a.model.average_score === null && b.model.average_score === null)
|
| 112 |
return 0;
|
| 113 |
if (a.model.average_score === null) return 1;
|
|
@@ -115,7 +168,7 @@ export const useProcessedData = (data, averageMode, visibleColumns) => {
|
|
| 115 |
return b.model.average_score - a.model.average_score;
|
| 116 |
});
|
| 117 |
|
| 118 |
-
return
|
| 119 |
...item,
|
| 120 |
static_rank: index + 1,
|
| 121 |
}));
|
|
|
|
| 4 |
parseSearchQuery,
|
| 5 |
getValueByPath,
|
| 6 |
} from "../utils/searchUtils";
|
| 7 |
+
import { ALLOWED_MODELS, isModelAllowed } from "../constants/allowedModels";
|
| 8 |
|
| 9 |
// Calculate min/max averages
|
| 10 |
export const useAverageRange = (data) => {
|
|
|
|
| 39 |
// Process data with boolean standardization
|
| 40 |
export const useProcessedData = (data, averageMode, visibleColumns) => {
|
| 41 |
return useMemo(() => {
|
| 42 |
+
// First filter and process existing models
|
| 43 |
let processed = data.map((item) => {
|
| 44 |
+
// Calculate average score for Greek datasets
|
| 45 |
const greekDatasets = ['multifin', 'qa', 'fns', 'finnum', 'fintext'];
|
| 46 |
const greekScores = greekDatasets
|
| 47 |
.filter(dataset => item.evaluations[dataset]?.normalized_score !== undefined)
|
|
|
|
| 51 |
? greekScores.reduce((a, b) => a + b, 0) / greekScores.length
|
| 52 |
: null;
|
| 53 |
|
| 54 |
+
// Add Greek average to evaluations object
|
| 55 |
const enhancedEvaluations = {
|
| 56 |
...item.evaluations,
|
| 57 |
greek_average: greekAverage
|
| 58 |
};
|
| 59 |
|
| 60 |
+
// Calculate average score for all visible evaluations (including greek_average, but excluding specific Greek datasets)
|
| 61 |
const includedEvaluations = {};
|
| 62 |
+
// Copy all non-Greek evaluation data
|
| 63 |
Object.entries(item.evaluations).forEach(([key, value]) => {
|
| 64 |
if (!greekDatasets.includes(key)) {
|
| 65 |
includedEvaluations[key] = value;
|
| 66 |
}
|
| 67 |
});
|
| 68 |
+
// Add Greek average
|
| 69 |
if (greekAverage !== null) {
|
| 70 |
includedEvaluations.greek_average = { normalized_score: greekAverage };
|
| 71 |
}
|
|
|
|
| 100 |
return {
|
| 101 |
...item,
|
| 102 |
features: standardizedFeatures,
|
| 103 |
+
evaluations: enhancedEvaluations, // Use enhanced evaluations
|
| 104 |
model: {
|
| 105 |
...item.model,
|
| 106 |
has_chat_template: Boolean(item.model.has_chat_template),
|
|
|
|
| 109 |
};
|
| 110 |
});
|
| 111 |
|
| 112 |
+
// Create mapping of existing models, check which ones are in the allowed list
|
| 113 |
+
const existingModelsMap = {};
|
| 114 |
+
const filteredModels = [];
|
| 115 |
+
|
| 116 |
+
processed.forEach(model => {
|
| 117 |
+
if (isModelAllowed(model.model.name)) {
|
| 118 |
+
existingModelsMap[model.model.name] = model;
|
| 119 |
+
filteredModels.push(model);
|
| 120 |
+
}
|
| 121 |
+
});
|
| 122 |
+
|
| 123 |
+
// Add "missing" entries, create placeholders for models in the allowed list that don't exist
|
| 124 |
+
ALLOWED_MODELS.forEach(allowedModelName => {
|
| 125 |
+
// Check if a matching model already exists
|
| 126 |
+
const modelExists = Object.keys(existingModelsMap).some(name =>
|
| 127 |
+
name.toLowerCase().includes(allowedModelName.toLowerCase())
|
| 128 |
+
);
|
| 129 |
+
|
| 130 |
+
if (!modelExists) {
|
| 131 |
+
// Create a "missing" placeholder
|
| 132 |
+
filteredModels.push({
|
| 133 |
+
id: `missing-${allowedModelName}`,
|
| 134 |
+
model: {
|
| 135 |
+
name: allowedModelName,
|
| 136 |
+
average_score: null,
|
| 137 |
+
type: "Unknown",
|
| 138 |
+
},
|
| 139 |
+
evaluations: {
|
| 140 |
+
greek_average: null
|
| 141 |
+
},
|
| 142 |
+
features: {
|
| 143 |
+
is_moe: false,
|
| 144 |
+
is_flagged: false,
|
| 145 |
+
is_highlighted_by_maintainer: false,
|
| 146 |
+
is_merged: false,
|
| 147 |
+
is_not_available_on_hub: true,
|
| 148 |
+
},
|
| 149 |
+
metadata: {
|
| 150 |
+
submission_date: new Date().toISOString(),
|
| 151 |
+
},
|
| 152 |
+
isMissing: true, // Mark as missing
|
| 153 |
+
});
|
| 154 |
+
}
|
| 155 |
+
});
|
| 156 |
+
|
| 157 |
+
// Sort the results
|
| 158 |
+
filteredModels.sort((a, b) => {
|
| 159 |
+
// Place missing models at the end
|
| 160 |
+
if (a.isMissing && !b.isMissing) return 1;
|
| 161 |
+
if (!a.isMissing && b.isMissing) return -1;
|
| 162 |
+
|
| 163 |
+
// If both are missing or both are not missing, sort by average score
|
| 164 |
if (a.model.average_score === null && b.model.average_score === null)
|
| 165 |
return 0;
|
| 166 |
if (a.model.average_score === null) return 1;
|
|
|
|
| 168 |
return b.model.average_score - a.model.average_score;
|
| 169 |
});
|
| 170 |
|
| 171 |
+
return filteredModels.map((item, index) => ({
|
| 172 |
...item,
|
| 173 |
static_rank: index + 1,
|
| 174 |
}));
|
frontend/src/pages/LeaderboardPage/components/Leaderboard/utils/columnUtils.js
CHANGED
|
@@ -510,7 +510,7 @@ export const createColumns = (
|
|
| 510 |
onTogglePin,
|
| 511 |
hasPinnedRows = false
|
| 512 |
) => {
|
| 513 |
-
//
|
| 514 |
const getColumnSize = (defaultSize) =>
|
| 515 |
hasPinnedRows ? "auto" : `${defaultSize}px`;
|
| 516 |
|
|
@@ -561,6 +561,30 @@ export const createColumns = (
|
|
| 561 |
rankingMode === "static"
|
| 562 |
? row.original.static_rank
|
| 563 |
: row.original.dynamic_rank;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 564 |
|
| 565 |
return (
|
| 566 |
<RankIndicator
|
|
@@ -577,30 +601,57 @@ export const createColumns = (
|
|
| 577 |
accessorFn: (row) => row.model.type,
|
| 578 |
header: createHeaderCell("Type"),
|
| 579 |
sortingFn: typeColumnSort,
|
| 580 |
-
cell: ({ row }) =>
|
| 581 |
-
|
| 582 |
-
|
| 583 |
-
|
| 584 |
-
|
| 585 |
-
|
| 586 |
-
|
| 587 |
-
}}
|
| 588 |
-
>
|
| 589 |
-
<Tooltip title={row.original.model.type}>
|
| 590 |
-
<Typography
|
| 591 |
sx={{
|
| 592 |
-
|
| 593 |
-
|
| 594 |
-
|
| 595 |
-
|
| 596 |
-
'"Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji", sans-serif',
|
| 597 |
}}
|
| 598 |
>
|
| 599 |
-
|
| 600 |
-
|
| 601 |
-
|
| 602 |
-
|
| 603 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 604 |
size: TABLE_DEFAULTS.COLUMNS.COLUMN_SIZES["model.type_icon"],
|
| 605 |
},
|
| 606 |
{
|
|
@@ -609,6 +660,29 @@ export const createColumns = (
|
|
| 609 |
cell: ({ row }) => {
|
| 610 |
const textSearch = extractTextSearch(searchValue);
|
| 611 |
const modelName = row.original.model.name;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 612 |
|
| 613 |
return (
|
| 614 |
<Box
|
|
@@ -743,6 +817,34 @@ export const createColumns = (
|
|
| 743 |
|
| 744 |
const isAverageColumn = field === "model.average_score";
|
| 745 |
const hasNoValue = value === null || value === undefined;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 746 |
|
| 747 |
return (
|
| 748 |
<Box sx={commonStyles.cellContainer}>
|
|
|
|
| 510 |
onTogglePin,
|
| 511 |
hasPinnedRows = false
|
| 512 |
) => {
|
| 513 |
+
// Adjust column sizes based on the presence of pinned rows
|
| 514 |
const getColumnSize = (defaultSize) =>
|
| 515 |
hasPinnedRows ? "auto" : `${defaultSize}px`;
|
| 516 |
|
|
|
|
| 561 |
rankingMode === "static"
|
| 562 |
? row.original.static_rank
|
| 563 |
: row.original.dynamic_rank;
|
| 564 |
+
const isMissing = row.original.isMissing === true;
|
| 565 |
+
|
| 566 |
+
// Don't display rank for missing models
|
| 567 |
+
if (isMissing) {
|
| 568 |
+
return (
|
| 569 |
+
<Box
|
| 570 |
+
sx={{
|
| 571 |
+
display: "flex",
|
| 572 |
+
alignItems: "center",
|
| 573 |
+
justifyContent: "center",
|
| 574 |
+
width: "100%",
|
| 575 |
+
}}
|
| 576 |
+
>
|
| 577 |
+
<Typography
|
| 578 |
+
sx={{
|
| 579 |
+
color: "text.secondary",
|
| 580 |
+
fontStyle: "italic",
|
| 581 |
+
}}
|
| 582 |
+
>
|
| 583 |
+
-
|
| 584 |
+
</Typography>
|
| 585 |
+
</Box>
|
| 586 |
+
);
|
| 587 |
+
}
|
| 588 |
|
| 589 |
return (
|
| 590 |
<RankIndicator
|
|
|
|
| 601 |
accessorFn: (row) => row.model.type,
|
| 602 |
header: createHeaderCell("Type"),
|
| 603 |
sortingFn: typeColumnSort,
|
| 604 |
+
cell: ({ row }) => {
|
| 605 |
+
const isMissing = row.original.isMissing === true;
|
| 606 |
+
|
| 607 |
+
// Don't display type icon for missing models
|
| 608 |
+
if (isMissing) {
|
| 609 |
+
return (
|
| 610 |
+
<Box
|
|
|
|
|
|
|
|
|
|
|
|
|
| 611 |
sx={{
|
| 612 |
+
display: "flex",
|
| 613 |
+
alignItems: "center",
|
| 614 |
+
justifyContent: "center",
|
| 615 |
+
width: "100%",
|
|
|
|
| 616 |
}}
|
| 617 |
>
|
| 618 |
+
<Typography
|
| 619 |
+
sx={{
|
| 620 |
+
color: "text.secondary",
|
| 621 |
+
fontStyle: "italic",
|
| 622 |
+
}}
|
| 623 |
+
>
|
| 624 |
+
-
|
| 625 |
+
</Typography>
|
| 626 |
+
</Box>
|
| 627 |
+
);
|
| 628 |
+
}
|
| 629 |
+
|
| 630 |
+
return (
|
| 631 |
+
<Box
|
| 632 |
+
sx={{
|
| 633 |
+
display: "flex",
|
| 634 |
+
alignItems: "center",
|
| 635 |
+
justifyContent: "center",
|
| 636 |
+
width: "100%",
|
| 637 |
+
}}
|
| 638 |
+
>
|
| 639 |
+
<Tooltip title={row.original.model.type}>
|
| 640 |
+
<Typography
|
| 641 |
+
sx={{
|
| 642 |
+
fontSize: "1.2rem",
|
| 643 |
+
cursor: "help",
|
| 644 |
+
lineHeight: 1,
|
| 645 |
+
fontFamily:
|
| 646 |
+
'"Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji", sans-serif',
|
| 647 |
+
}}
|
| 648 |
+
>
|
| 649 |
+
{getModelTypeIcon(row.original.model.type)}
|
| 650 |
+
</Typography>
|
| 651 |
+
</Tooltip>
|
| 652 |
+
</Box>
|
| 653 |
+
);
|
| 654 |
+
},
|
| 655 |
size: TABLE_DEFAULTS.COLUMNS.COLUMN_SIZES["model.type_icon"],
|
| 656 |
},
|
| 657 |
{
|
|
|
|
| 660 |
cell: ({ row }) => {
|
| 661 |
const textSearch = extractTextSearch(searchValue);
|
| 662 |
const modelName = row.original.model.name;
|
| 663 |
+
const isMissing = row.original.isMissing === true;
|
| 664 |
+
|
| 665 |
+
// Display special style for missing models
|
| 666 |
+
if (isMissing) {
|
| 667 |
+
return (
|
| 668 |
+
<Box
|
| 669 |
+
sx={{
|
| 670 |
+
width: "100%",
|
| 671 |
+
display: "flex",
|
| 672 |
+
alignItems: "center",
|
| 673 |
+
}}
|
| 674 |
+
>
|
| 675 |
+
<Typography
|
| 676 |
+
sx={{
|
| 677 |
+
color: "text.secondary",
|
| 678 |
+
fontStyle: "italic",
|
| 679 |
+
}}
|
| 680 |
+
>
|
| 681 |
+
{modelName}
|
| 682 |
+
</Typography>
|
| 683 |
+
</Box>
|
| 684 |
+
);
|
| 685 |
+
}
|
| 686 |
|
| 687 |
return (
|
| 688 |
<Box
|
|
|
|
| 817 |
|
| 818 |
const isAverageColumn = field === "model.average_score";
|
| 819 |
const hasNoValue = value === null || value === undefined;
|
| 820 |
+
const isMissing = row.original.isMissing === true;
|
| 821 |
+
|
| 822 |
+
// Display special text for "missing" models
|
| 823 |
+
if (isMissing) {
|
| 824 |
+
return (
|
| 825 |
+
<Box sx={commonStyles.cellContainer}>
|
| 826 |
+
<Box
|
| 827 |
+
sx={{
|
| 828 |
+
position: "relative",
|
| 829 |
+
display: "flex",
|
| 830 |
+
alignItems: "center",
|
| 831 |
+
justifyContent: "center",
|
| 832 |
+
zIndex: 1,
|
| 833 |
+
}}
|
| 834 |
+
>
|
| 835 |
+
<Typography
|
| 836 |
+
variant="body2"
|
| 837 |
+
sx={{
|
| 838 |
+
color: 'text.secondary',
|
| 839 |
+
fontStyle: 'italic',
|
| 840 |
+
}}
|
| 841 |
+
>
|
| 842 |
+
missing
|
| 843 |
+
</Typography>
|
| 844 |
+
</Box>
|
| 845 |
+
</Box>
|
| 846 |
+
);
|
| 847 |
+
}
|
| 848 |
|
| 849 |
return (
|
| 850 |
<Box sx={commonStyles.cellContainer}>
|