Spaces:
Running
on
CPU Upgrade
Running
on
CPU Upgrade
add uid to context
Browse files- backend/app/services/leaderboard.py +5 -2
- frontend/src/pages/LeaderboardPage/components/Leaderboard/components/Filters/Filters.js +5 -2
- frontend/src/pages/LeaderboardPage/components/Leaderboard/components/Filters/hooks/useOfficialProvidersMode.js +2 -4
- frontend/src/pages/LeaderboardPage/components/Leaderboard/components/Table/Table.js +2 -2
- frontend/src/pages/LeaderboardPage/components/Leaderboard/components/Table/hooks/useDataProcessing.js +2 -2
- frontend/src/pages/LeaderboardPage/components/Leaderboard/context/LeaderboardContext.js +10 -31
- frontend/src/pages/LeaderboardPage/components/Leaderboard/hooks/useDataUtils.js +40 -24
- frontend/src/pages/LeaderboardPage/components/Leaderboard/utils/columnUtils.js +1 -1
backend/app/services/leaderboard.py
CHANGED
@@ -102,6 +102,9 @@ class LeaderboardService:
|
|
102 |
model_name = data.get("fullname", "Unknown")
|
103 |
logger.debug(LogFormatter.info(f"Transforming data for model: {model_name}"))
|
104 |
|
|
|
|
|
|
|
105 |
evaluations = {
|
106 |
"ifeval": {
|
107 |
"name": "IFEval",
|
@@ -174,14 +177,14 @@ class LeaderboardService:
|
|
174 |
"fine tuning": "fined-tuned-on-domain-specific-dataset",
|
175 |
"fine-tuning": "fined-tuned-on-domain-specific-dataset"
|
176 |
}
|
177 |
-
|
178 |
mapped_type = model_type_mapping.get(model_type.lower().strip(), model_type)
|
179 |
|
180 |
if mapped_type != model_type:
|
181 |
logger.debug(LogFormatter.info(f"Model type mapped: {original_type} -> {mapped_type}"))
|
182 |
|
183 |
transformed_data = {
|
184 |
-
"id":
|
185 |
"model": {
|
186 |
"name": data.get("fullname"),
|
187 |
"sha": data.get("Model sha"),
|
|
|
102 |
model_name = data.get("fullname", "Unknown")
|
103 |
logger.debug(LogFormatter.info(f"Transforming data for model: {model_name}"))
|
104 |
|
105 |
+
# Create unique ID combining model name, precision, sha and chat template status
|
106 |
+
unique_id = f"{data.get('fullname', 'Unknown')}_{data.get('Precision', 'Unknown')}_{data.get('Model sha', 'Unknown')}_{str(data.get('Chat Template', False))}"
|
107 |
+
|
108 |
evaluations = {
|
109 |
"ifeval": {
|
110 |
"name": "IFEval",
|
|
|
177 |
"fine tuning": "fined-tuned-on-domain-specific-dataset",
|
178 |
"fine-tuning": "fined-tuned-on-domain-specific-dataset"
|
179 |
}
|
180 |
+
|
181 |
mapped_type = model_type_mapping.get(model_type.lower().strip(), model_type)
|
182 |
|
183 |
if mapped_type != model_type:
|
184 |
logger.debug(LogFormatter.info(f"Model type mapped: {original_type} -> {mapped_type}"))
|
185 |
|
186 |
transformed_data = {
|
187 |
+
"id": unique_id,
|
188 |
"model": {
|
189 |
"name": data.get("fullname"),
|
190 |
"sha": data.get("Model sha"),
|
frontend/src/pages/LeaderboardPage/components/Leaderboard/components/Filters/Filters.js
CHANGED
@@ -379,9 +379,12 @@ const LeaderboardFilters = ({
|
|
379 |
clearTimeout(stableTimerRef.current);
|
380 |
}
|
381 |
|
382 |
-
//
|
|
|
|
|
|
|
383 |
stableTimerRef.current = setTimeout(() => {
|
384 |
-
|
385 |
}, TABLE_DEFAULTS.DEBOUNCE.SEARCH);
|
386 |
};
|
387 |
|
|
|
379 |
clearTimeout(stableTimerRef.current);
|
380 |
}
|
381 |
|
382 |
+
// Update URL immediately
|
383 |
+
onParamsRangeChange(newValue);
|
384 |
+
|
385 |
+
// Trigger data update after debounce
|
386 |
stableTimerRef.current = setTimeout(() => {
|
387 |
+
actions.updateFilteredData();
|
388 |
}, TABLE_DEFAULTS.DEBOUNCE.SEARCH);
|
389 |
};
|
390 |
|
frontend/src/pages/LeaderboardPage/components/Leaderboard/components/Filters/hooks/useOfficialProvidersMode.js
CHANGED
@@ -117,10 +117,8 @@ export const useOfficialProvidersMode = () => {
|
|
117 |
timestamp: now,
|
118 |
};
|
119 |
|
120 |
-
// Update
|
121 |
-
|
122 |
-
setSearchParams(newSearchParams, { replace: true });
|
123 |
-
}, 0);
|
124 |
},
|
125 |
[searchParams, setSearchParams]
|
126 |
);
|
|
|
117 |
timestamp: now,
|
118 |
};
|
119 |
|
120 |
+
// Update search params and let HashRouter handle the URL
|
121 |
+
setSearchParams(newSearchParams);
|
|
|
|
|
122 |
},
|
123 |
[searchParams, setSearchParams]
|
124 |
);
|
frontend/src/pages/LeaderboardPage/components/Leaderboard/components/Table/Table.js
CHANGED
@@ -259,8 +259,8 @@ const LeaderboardTable = ({
|
|
259 |
const pinnedModelRows = rows.filter((row) => row.original.isPinned);
|
260 |
// Sort pinned models according to their original order in pinnedModels
|
261 |
return pinnedModelRows.sort((a, b) => {
|
262 |
-
const aIndex = pinnedModels.indexOf(a.original.
|
263 |
-
const bIndex = pinnedModels.indexOf(b.original.
|
264 |
return aIndex - bIndex;
|
265 |
});
|
266 |
}, [rows, pinnedModels]);
|
|
|
259 |
const pinnedModelRows = rows.filter((row) => row.original.isPinned);
|
260 |
// Sort pinned models according to their original order in pinnedModels
|
261 |
return pinnedModelRows.sort((a, b) => {
|
262 |
+
const aIndex = pinnedModels.indexOf(a.original.id);
|
263 |
+
const bIndex = pinnedModels.indexOf(b.original.id);
|
264 |
return aIndex - bIndex;
|
265 |
});
|
266 |
}, [rows, pinnedModels]);
|
frontend/src/pages/LeaderboardPage/components/Leaderboard/components/Table/hooks/useDataProcessing.js
CHANGED
@@ -119,8 +119,8 @@ export const useDataProcessing = (
|
|
119 |
|
120 |
if (rowA.original.isPinned && rowB.original.isPinned) {
|
121 |
return (
|
122 |
-
pinnedModels.indexOf(rowA.original.
|
123 |
-
pinnedModels.indexOf(rowB.original.
|
124 |
);
|
125 |
}
|
126 |
|
|
|
119 |
|
120 |
if (rowA.original.isPinned && rowB.original.isPinned) {
|
121 |
return (
|
122 |
+
pinnedModels.indexOf(rowA.original.id) -
|
123 |
+
pinnedModels.indexOf(rowB.original.id)
|
124 |
);
|
125 |
}
|
126 |
|
frontend/src/pages/LeaderboardPage/components/Leaderboard/context/LeaderboardContext.js
CHANGED
@@ -297,12 +297,12 @@ const reducer = (state, action) => {
|
|
297 |
};
|
298 |
|
299 |
case "TOGGLE_PINNED_MODEL":
|
300 |
-
const
|
301 |
const pinnedModels = [...state.pinnedModels];
|
302 |
-
const modelIndex = pinnedModels.indexOf(
|
303 |
|
304 |
if (modelIndex === -1) {
|
305 |
-
pinnedModels.push(
|
306 |
} else {
|
307 |
pinnedModels.splice(modelIndex, 1);
|
308 |
}
|
@@ -659,25 +659,10 @@ const LeaderboardProvider = ({ children }) => {
|
|
659 |
precisionsChanged ||
|
660 |
typesChanged
|
661 |
) {
|
662 |
-
|
|
|
663 |
}
|
664 |
-
}, [
|
665 |
-
state.filters.paramsRange,
|
666 |
-
state.filters.booleanFilters,
|
667 |
-
state.filters.search,
|
668 |
-
state.filters.isOfficialProviderActive,
|
669 |
-
state.filters.precisions,
|
670 |
-
state.filters.types,
|
671 |
-
state.pinnedModels,
|
672 |
-
state.display.visibleColumns,
|
673 |
-
state.display.rowSize,
|
674 |
-
state.display.scoreDisplay,
|
675 |
-
state.display.averageMode,
|
676 |
-
state.display.rankingMode,
|
677 |
-
searchParams,
|
678 |
-
setSearchParams,
|
679 |
-
location.state,
|
680 |
-
]);
|
681 |
|
682 |
const actions = useMemo(
|
683 |
() => ({
|
@@ -688,8 +673,8 @@ const LeaderboardProvider = ({ children }) => {
|
|
688 |
setFilter: (key, value) => dispatch({ type: "SET_FILTER", key, value }),
|
689 |
setDisplayOption: (key, value) =>
|
690 |
dispatch({ type: "SET_DISPLAY_OPTION", key, value }),
|
691 |
-
togglePinnedModel: (
|
692 |
-
dispatch({ type: "TOGGLE_PINNED_MODEL", payload:
|
693 |
toggleOfficialProvider: () =>
|
694 |
dispatch({ type: "TOGGLE_OFFICIAL_PROVIDER" }),
|
695 |
toggleFiltersExpanded: () =>
|
@@ -707,19 +692,13 @@ const LeaderboardProvider = ({ children }) => {
|
|
707 |
].forEach((param) => {
|
708 |
newParams.delete(param);
|
709 |
});
|
710 |
-
setSearchParams(newParams
|
711 |
},
|
712 |
resetAll: () => {
|
713 |
// Reset all state
|
714 |
dispatch({ type: "RESET_ALL" });
|
715 |
// Clear all URL params with skipUrlSync flag
|
716 |
-
setSearchParams(
|
717 |
-
{},
|
718 |
-
{
|
719 |
-
replace: true,
|
720 |
-
state: { skipUrlSync: true },
|
721 |
-
}
|
722 |
-
);
|
723 |
},
|
724 |
}),
|
725 |
[searchParams, setSearchParams]
|
|
|
297 |
};
|
298 |
|
299 |
case "TOGGLE_PINNED_MODEL":
|
300 |
+
const modelKey = action.payload;
|
301 |
const pinnedModels = [...state.pinnedModels];
|
302 |
+
const modelIndex = pinnedModels.indexOf(modelKey);
|
303 |
|
304 |
if (modelIndex === -1) {
|
305 |
+
pinnedModels.push(modelKey);
|
306 |
} else {
|
307 |
pinnedModels.splice(modelIndex, 1);
|
308 |
}
|
|
|
659 |
precisionsChanged ||
|
660 |
typesChanged
|
661 |
) {
|
662 |
+
// Update search params and let HashRouter handle the URL
|
663 |
+
setSearchParams(newSearchParams);
|
664 |
}
|
665 |
+
}, [state, searchParams, location.state]);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
666 |
|
667 |
const actions = useMemo(
|
668 |
() => ({
|
|
|
673 |
setFilter: (key, value) => dispatch({ type: "SET_FILTER", key, value }),
|
674 |
setDisplayOption: (key, value) =>
|
675 |
dispatch({ type: "SET_DISPLAY_OPTION", key, value }),
|
676 |
+
togglePinnedModel: (modelKey) =>
|
677 |
+
dispatch({ type: "TOGGLE_PINNED_MODEL", payload: modelKey }),
|
678 |
toggleOfficialProvider: () =>
|
679 |
dispatch({ type: "TOGGLE_OFFICIAL_PROVIDER" }),
|
680 |
toggleFiltersExpanded: () =>
|
|
|
692 |
].forEach((param) => {
|
693 |
newParams.delete(param);
|
694 |
});
|
695 |
+
setSearchParams(newParams);
|
696 |
},
|
697 |
resetAll: () => {
|
698 |
// Reset all state
|
699 |
dispatch({ type: "RESET_ALL" });
|
700 |
// Clear all URL params with skipUrlSync flag
|
701 |
+
setSearchParams({}, { state: { skipUrlSync: true } });
|
|
|
|
|
|
|
|
|
|
|
|
|
702 |
},
|
703 |
}),
|
704 |
[searchParams, setSearchParams]
|
frontend/src/pages/LeaderboardPage/components/Leaderboard/hooks/useDataUtils.js
CHANGED
@@ -104,12 +104,12 @@ export const useFilteredData = (
|
|
104 |
isOfficialProviderActive = false
|
105 |
) => {
|
106 |
return useMemo(() => {
|
107 |
-
const pinnedData = processedData.filter((row) =>
|
108 |
-
pinnedModels.includes(row.
|
109 |
-
);
|
110 |
-
const unpinnedData = processedData.filter(
|
111 |
-
|
112 |
-
);
|
113 |
|
114 |
let filteredUnpinned = unpinnedData;
|
115 |
|
@@ -213,8 +213,8 @@ export const useFilteredData = (
|
|
213 |
|
214 |
// Create ordered array of pinned models respecting pinnedModels order
|
215 |
const orderedPinnedData = pinnedModels
|
216 |
-
.map((
|
217 |
-
pinnedData.find((item) => item.
|
218 |
)
|
219 |
.filter(Boolean);
|
220 |
|
@@ -223,31 +223,47 @@ export const useFilteredData = (
|
|
223 |
|
224 |
// Sort all data by average_score for dynamic_rank
|
225 |
const sortedByScore = [...allFilteredData].sort((a, b) => {
|
226 |
-
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
231 |
});
|
232 |
|
233 |
// Create Map to store dynamic_ranks
|
234 |
const dynamicRankMap = new Map();
|
235 |
sortedByScore.forEach((item, index) => {
|
236 |
-
dynamicRankMap.set(item.
|
237 |
});
|
238 |
|
239 |
// Add ranks to final data
|
240 |
const finalData = [...orderedPinnedData, ...filteredUnpinned].map(
|
241 |
-
(item) =>
|
242 |
-
|
243 |
-
|
244 |
-
|
245 |
-
|
246 |
-
|
247 |
-
|
248 |
-
|
249 |
-
|
250 |
-
|
|
|
|
|
251 |
);
|
252 |
|
253 |
return finalData;
|
|
|
104 |
isOfficialProviderActive = false
|
105 |
) => {
|
106 |
return useMemo(() => {
|
107 |
+
const pinnedData = processedData.filter((row) => {
|
108 |
+
return pinnedModels.includes(row.id);
|
109 |
+
});
|
110 |
+
const unpinnedData = processedData.filter((row) => {
|
111 |
+
return !pinnedModels.includes(row.id);
|
112 |
+
});
|
113 |
|
114 |
let filteredUnpinned = unpinnedData;
|
115 |
|
|
|
213 |
|
214 |
// Create ordered array of pinned models respecting pinnedModels order
|
215 |
const orderedPinnedData = pinnedModels
|
216 |
+
.map((pinnedModelId) =>
|
217 |
+
pinnedData.find((item) => item.id === pinnedModelId)
|
218 |
)
|
219 |
.filter(Boolean);
|
220 |
|
|
|
223 |
|
224 |
// Sort all data by average_score for dynamic_rank
|
225 |
const sortedByScore = [...allFilteredData].sort((a, b) => {
|
226 |
+
// Si les scores moyens sont différents, trier par score
|
227 |
+
if (a.model.average_score !== b.model.average_score) {
|
228 |
+
if (a.model.average_score === null && b.model.average_score === null)
|
229 |
+
return 0;
|
230 |
+
if (a.model.average_score === null) return 1;
|
231 |
+
if (b.model.average_score === null) return -1;
|
232 |
+
return b.model.average_score - a.model.average_score;
|
233 |
+
}
|
234 |
+
|
235 |
+
// Si les scores sont égaux, comparer le nom du modèle et la date de soumission
|
236 |
+
if (a.model.name === b.model.name) {
|
237 |
+
// Si même nom, trier par date de soumission (la plus récente d'abord)
|
238 |
+
const dateA = new Date(a.metadata?.submission_date || 0);
|
239 |
+
const dateB = new Date(b.metadata?.submission_date || 0);
|
240 |
+
return dateB - dateA;
|
241 |
+
}
|
242 |
+
|
243 |
+
// Si noms différents, trier par nom
|
244 |
+
return a.model.name.localeCompare(b.model.name);
|
245 |
});
|
246 |
|
247 |
// Create Map to store dynamic_ranks
|
248 |
const dynamicRankMap = new Map();
|
249 |
sortedByScore.forEach((item, index) => {
|
250 |
+
dynamicRankMap.set(item.id, index + 1);
|
251 |
});
|
252 |
|
253 |
// Add ranks to final data
|
254 |
const finalData = [...orderedPinnedData, ...filteredUnpinned].map(
|
255 |
+
(item) => {
|
256 |
+
return {
|
257 |
+
...item,
|
258 |
+
dynamic_rank: dynamicRankMap.get(item.id),
|
259 |
+
rank: item.isPinned
|
260 |
+
? pinnedModels.indexOf(item.id) + 1
|
261 |
+
: rankingMode === "static"
|
262 |
+
? item.static_rank
|
263 |
+
: dynamicRankMap.get(item.id),
|
264 |
+
isPinned: pinnedModels.includes(item.id),
|
265 |
+
};
|
266 |
+
}
|
267 |
);
|
268 |
|
269 |
return finalData;
|
frontend/src/pages/LeaderboardPage/components/Leaderboard/utils/columnUtils.js
CHANGED
@@ -473,7 +473,7 @@ export const createColumns = (
|
|
473 |
onClick={(e) => {
|
474 |
e.stopPropagation();
|
475 |
e.preventDefault();
|
476 |
-
onTogglePin(row.original.
|
477 |
}}
|
478 |
sx={{
|
479 |
padding: 0.5,
|
|
|
473 |
onClick={(e) => {
|
474 |
e.stopPropagation();
|
475 |
e.preventDefault();
|
476 |
+
onTogglePin(row.original.id);
|
477 |
}}
|
478 |
sx={{
|
479 |
padding: 0.5,
|