|
|
<script setup> |
|
|
import { ref, onMounted, watch, nextTick } from 'vue' |
|
|
import { useLeaderboardData } from '@/composables/useLeaderboardData.js' |
|
|
import Chart from '@/components/Chart.vue' |
|
|
import { computed } from 'vue' |
|
|
import { parsedHeaderHtml } from '@/utils/mk2html.js' |
|
|
|
|
|
|
|
|
const { |
|
|
leaderboard, |
|
|
csvHeaders, |
|
|
loading, |
|
|
error, |
|
|
selectedMode, |
|
|
visibleColumns, |
|
|
selectableColumns, |
|
|
dataGroups, |
|
|
selectedDataName, |
|
|
modelSeriesICAvg, |
|
|
selectedDataNameChart, |
|
|
autoShowSeries, |
|
|
headerDisplayMap, |
|
|
dataNameDisplayMap, |
|
|
modelTypeGroups, |
|
|
selectedModelType, |
|
|
filteredLeaderboard, |
|
|
displayedColumns, |
|
|
fetchAndLoadCsv, |
|
|
selectAll, |
|
|
clearAll, |
|
|
selectAllModelTypes, |
|
|
clearAllModelTypes, |
|
|
formatCell, |
|
|
// 排序 API |
|
|
sortKey, |
|
|
sortDesc, |
|
|
setSortKey, |
|
|
init |
|
|
} = useLeaderboardData() |
|
|
|
|
|
const isSeries = computed(() => selectedMode.value === 'ModelSeries') |
|
|
|
|
|
|
|
|
const isDark = ref(false) |
|
|
|
|
|
|
|
|
const chartSection = ref(null) |
|
|
|
|
|
|
|
|
const lastSelectedDataNameChart = ref('') |
|
|
|
|
|
|
|
|
const headerMarkdown = ref(` |
|
|
|
|
|
**Information Capacity** evaluates an LLM's **efficiency** based on text compression performance relative to computational complexity, harnessing the inherent correlation between **compression** and **intelligence**. |
|
|
Larger models can predict the next token more accurately, leading to higher compression gains but at increased computational costs. |
|
|
Consequently, a series of models with varying sizes exhibits **consistent** information capacity, which can be used to compare model capability across model series and predict model performance within a series. |
|
|
It also facilitates dynamic routing of different-sized models for efficient handling of tasks with varying difficulties, which is especially relevant to the device-edge-cloud infrastructure detailed in the **AI Flow** framework. |
|
|
With the rapid evolution of edge intelligence, we believe that this hierarchical network will replace the mainstream cloud-centric computing scheme in the near future. |
|
|
|
|
|
|
|
|
If you want to add your evaluation results to the leaderboard, please submit a discussion at [this huggingface space](https://huggingface.co/spaces/TeleAI-AI-Flow/InformationCapacityLeaderboard/discussions/new). |
|
|
|
|
|
`) |
|
|
|
|
|
const title = 'Information Capacity Leaderboard' |
|
|
|
|
|
const lastUpdatedTime = '11/12/2025 15:30' |
|
|
|
|
|
const headerInfo = parsedHeaderHtml(headerMarkdown.value) |
|
|
|
|
|
|
|
|
|
|
|
watch(selectedDataNameChart, (newVal) => { |
|
|
if (lastSelectedDataNameChart.value && lastSelectedDataNameChart.value !== newVal) { |
|
|
nextTick(() => { |
|
|
chartSection.value?.scrollIntoView({ behavior: 'smooth', block: 'end' }) |
|
|
}) |
|
|
} |
|
|
lastSelectedDataNameChart.value = newVal |
|
|
}) |
|
|
|
|
|
onMounted(() => { |
|
|
init() |
|
|
}) |
|
|
|
|
|
onMounted(() => { |
|
|
const stored = localStorage.getItem('theme') |
|
|
if (stored === 'dark') { |
|
|
isDark.value = true |
|
|
} else if (stored === 'light') { |
|
|
isDark.value = false |
|
|
} else { |
|
|
// follow system preference when no stored preference |
|
|
isDark.value = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches |
|
|
} |
|
|
}) |
|
|
|
|
|
watch(isDark, (val) => { |
|
|
try { |
|
|
if (val) document.documentElement.classList.add('dark') |
|
|
else document.documentElement.classList.remove('dark') |
|
|
localStorage.setItem('theme', val ? 'dark' : 'light') |
|
|
} catch (e) { |
|
|
// ignore if SSR or unavailable |
|
|
} |
|
|
}) |
|
|
|
|
|
function clearModelTypeSelection() { |
|
|
selectAllModelTypes() |
|
|
} |
|
|
</script> |
|
|
|
|
|
<template> |
|
|
<div |
|
|
class="min-h-screen bg-gray-50 dark:bg-gradient-to-b dark:from-gray-900 dark:via-gray-800 dark:to-gray-800 py-12 px-4 sm:px-6 lg:px-8"> |
|
|
<div class=" mx-auto"> |
|
|
<header class="mb-4 flex items-start justify-between mr-4"> |
|
|
<div> |
|
|
<h1 class="text-3xl font-extrabold text-gray-900 dark:text-gray-100">{{ title }}</h1> |
|
|
|
|
|
<div v-html="headerInfo" class="py-7"></div> |
|
|
</div> |
|
|
<div class="flex items-center"> |
|
|
|
|
|
<div class="h-40 w-40 flex items-center justify-center rounded-md overflow-hidden p-2"> |
|
|
<img src="/logo.png" alt="Logo" class="max-h-full max-w-full object-contain" /> |
|
|
</div> |
|
|
</div> |
|
|
</header> |
|
|
|
|
|
|
|
|
<div class="bg-white dark:bg-gray-900/60 shadow rounded-lg overflow-hidden"> |
|
|
<div |
|
|
class="px-6 py-4 border-b bg-gradient-to-r from-indigo-50 via-white to-white dark:bg-gradient-to-r dark:from-gray-800 dark:via-gray-900 dark:to-gray-900"> |
|
|
<div class="flex items-center justify-between"> |
|
|
<h2 class="text-lg font-medium text-gray-800 dark:text-gray-50">Leaderboard</h2> |
|
|
<div class="text-sm text-gray-500 dark:text-gray-300">Last updated on {{ lastUpdatedTime }}</div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
<div class="px-6 py-3 border-b bg-gray-50 dark:bg-gradient-to-b dark:from-gray-900 dark:to-gray-800"> |
|
|
<div class="flex items-center gap-3"> |
|
|
<span class="text-sm font-medium text-gray-700 dark:text-gray-200">Shown as</span> |
|
|
<div v-if="dataGroups.length > 0" class="flex gap-2 items-center overflow-x-auto"> |
|
|
{'bg-gray-100 dark:bg-gray-700': selectedDataName==='all'} |
|
|
|
|
|
|
|
|
<label @click="selectedMode = 'Model'" |
|
|
class="px-2 py-1 rounded-full border border-gray-200 dark:border-gray-700 text-sm cursor-pointer dark:text-slate-300" |
|
|
:class="{ 'bg-gray-100 dark:bg-gray-700 dark:text-white': selectedMode === 'Model' }"> |
|
|
Individual Models |
|
|
</label> |
|
|
<label @click="selectedMode = 'ModelSeries'" |
|
|
class="px-2 py-1 rounded-full border border-gray-200 dark:border-gray-700 text-sm cursor-pointer dark:text-slate-300" |
|
|
:class="{ 'bg-gray-100 dark:bg-gray-700 dark:text-white': selectedMode === 'ModelSeries' }"> |
|
|
Model Series |
|
|
</label> |
|
|
</div> |
|
|
<div v-else class="text-sm text-gray-500 dark:text-gray-400">(数据集中未检测到 data_name 列)</div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
|
|
|
<div class="px-6 py-3 border-b bg-gray-50 dark:bg-gradient-to-b dark:from-gray-900 dark:to-gray-800"> |
|
|
<div class="flex items-center gap-3"> |
|
|
<span class="text-sm font-medium text-gray-700 dark:text-gray-200">Dataset</span> |
|
|
<div v-if="dataGroups.length > 0" class="flex gap-2 items-center overflow-x-auto"> |
|
|
{'bg-gray-100 dark:bg-gray-700': selectedDataName==='all'} |
|
|
|
|
|
|
|
|
<label v-for="g in dataGroups" :key="g" |
|
|
class="px-2 py-1 rounded-full border border-gray-200 dark:border-gray-700 text-sm cursor-pointer dark:text-slate-300" |
|
|
:class="{ 'bg-gray-100 dark:bg-gray-700 dark:text-white': selectedDataName === g }"> |
|
|
<input type="radio" class="hidden" :value="g" v-model="selectedDataName" /> <span |
|
|
class="whitespace-nowrap">{{ dataNameDisplayMap[g] ? |
|
|
dataNameDisplayMap[g] : g }}</span> |
|
|
</label> |
|
|
</div> |
|
|
<div v-else class="text-sm text-gray-500 dark:text-gray-400">(数据集中未检测到 data_name 列)</div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
|
|
|
|
|
|
<div class="px-6 py-3 border-b bg-gray-50 dark:bg-gradient-to-b dark:from-gray-900 dark:to-gray-800"> |
|
|
<div class="flex items-center gap-3"> |
|
|
<span class="text-sm font-medium text-gray-700 dark:text-gray-200 whitespace-nowrap">Model Series</span> |
|
|
<div class="flex items-center gap-2"> |
|
|
<button @click="clearModelTypeSelection" |
|
|
class="whitespace-nowrap text-sm px-2 py-1 bg-white/90 dark:bg-gray-700/60 border border-gray-200 dark:border-gray-600 rounded text-gray-700 dark:text-gray-200 hover:bg-white dark:hover:bg-gray-600 transition"> |
|
|
全选 |
|
|
</button> |
|
|
<button @click="clearAllModelTypes" |
|
|
class="whitespace-nowrap text-sm px-2 py-1 bg-transparent border border-gray-200 dark:border-gray-700 rounded text-gray-600 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700 transition"> |
|
|
清除 |
|
|
</button> |
|
|
</div> |
|
|
<div v-if="modelTypeGroups.length > 0" class="flex flex-wrap gap-2 items-center"> |
|
|
<label v-for="g in modelTypeGroups" :key="g" |
|
|
class="flex items-center gap-2 text-sm bg-white dark:bg-gray-800 px-3 py-1 rounded-full border border-gray-200 dark:border-gray-700 hover:shadow-sm whitespace-nowrap"> |
|
|
<input type="checkbox" :value="g" v-model="selectedModelType" |
|
|
class="h-4 w-4 text-indigo-600 dark:text-indigo-400 bg-white dark:bg-gray-700 border-gray-300 dark:border-gray-600 rounded" /> |
|
|
<span class="truncate text-gray-800 dark:text-gray-50">{{ g }}</span> |
|
|
</label> |
|
|
</div> |
|
|
<div v-else class="text-sm text-gray-500 dark:text-gray-400">(未配置模型类型映射)</div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
|
|
|
<div class="px-6 py-3 border-b bg-gray-50 dark:bg-gradient-to-b dark:from-gray-900 dark:to-gray-800" v-show="!isSeries"> |
|
|
<div class="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3"> |
|
|
<div class="flex items-center gap-3"> |
|
|
<span class="text-sm font-medium text-gray-700 dark:text-gray-200">Visible Columns</span> |
|
|
<div class="flex items-center gap-2"> |
|
|
<button @click.prevent="selectAll" |
|
|
class="text-sm px-2 py-1 bg-white/90 dark:bg-gray-700/60 border border-gray-200 dark:border-gray-600 rounded text-gray-700 dark:text-gray-200 hover:bg-white dark:hover:bg-gray-600 transition">全选</button> |
|
|
<button @click.prevent="clearAll" |
|
|
class="text-sm px-2 py-1 bg-transparent border border-gray-200 dark:border-gray-700 rounded text-gray-600 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700 transition">清除</button> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
<div class="flex-1 overflow-x-auto"> |
|
|
<div class="flex gap-2 items-center px-1 py-2"> |
|
|
<label v-for="h in selectableColumns" :key="h" |
|
|
class="flex items-center gap-2 text-sm bg-white dark:bg-gray-800 px-3 py-1 rounded-full border border-gray-200 dark:border-gray-700 hover:shadow-sm whitespace-nowrap"> |
|
|
<input type="checkbox" :value="h" v-model="visibleColumns" |
|
|
class="h-4 w-4 text-indigo-600 dark:text-indigo-400 bg-white dark:bg-gray-700 border-gray-300 dark:border-gray-600 rounded" /> |
|
|
<span class="truncate text-gray-800 dark:text-gray-50">{{ headerDisplayMap[h] || h }}</span> |
|
|
</label> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
<div class="p-4 overflow-x-auto"> |
|
|
<table class="min-w-full divide-y divide-gray-200 dark:divide-gray-700"> |
|
|
<thead class="bg-gray-50 dark:bg-gradient-to-r dark:from-gray-800 dark:to-gray-900"> |
|
|
<tr> |
|
|
|
|
|
|
|
|
|
|
|
<template v-if="selectedMode === 'ModelSeries'"> |
|
|
<th v-if="visibleColumns.includes('rank')" |
|
|
class="px-4 py-2 text-left text-xs font-medium text-gray-500 dark:text-gray-300 tracking-wider"> |
|
|
<div class="flex items-center gap-2"> |
|
|
<span class="whitespace-nowrap">{{ headerDisplayMap['rank'] || 'rank' }}</span> |
|
|
</div> |
|
|
</th> |
|
|
<th v-if="visibleColumns.includes('model_series')" |
|
|
class="px-4 py-2 text-left text-xs font-medium text-gray-500 dark:text-gray-300 tracking-wider"> |
|
|
<div class="flex items-center gap-2"> |
|
|
<span class="whitespace-nowrap">{{ headerDisplayMap['model_series'] || 'ModelSeries' }}</span> |
|
|
</div> |
|
|
</th> |
|
|
<th v-if="visibleColumns.includes('constant')" |
|
|
class="px-4 py-2 text-left text-xs font-medium text-gray-500 dark:text-gray-300 tracking-wider"> |
|
|
<div class="flex items-center gap-2"> |
|
|
<span class="whitespace-nowrap">{{ headerDisplayMap['constant']}}</span> |
|
|
</div> |
|
|
</th> |
|
|
<th v-if="visibleColumns.includes('ic')" @click="setSortKey('ic')" |
|
|
class="px-4 py-2 text-left text-xs font-medium text-gray-500 dark:text-gray-300 tracking-wider"> |
|
|
<div class="flex items-center gap-2"> |
|
|
<span class="whitespace-nowrap">{{ headerDisplayMap['ic']}} (AVG)</span> |
|
|
<span v-if="sortKey === 'ic'" class="text-xs text-gray-600 dark:text-gray-300"> |
|
|
<span v-if="sortDesc">▼</span> |
|
|
<span v-else>▲</span> |
|
|
</span> |
|
|
</div> |
|
|
</th> |
|
|
<th v-if="visibleColumns.includes('model_source')" @click="setSortKey('model_source')" |
|
|
class="px-4 py-2 text-left text-xs font-medium text-gray-500 dark:text-gray-300 tracking-wider"> |
|
|
<div class="flex items-center gap-2"> |
|
|
<span class="whitespace-nowrap">{{ headerDisplayMap['model_source']}} </span> |
|
|
<span v-if="sortKey === 'model_source'" class="text-xs text-gray-600 dark:text-gray-300"> |
|
|
<span v-if="sortDesc">▼</span> |
|
|
<span v-else>▲</span> |
|
|
</span> |
|
|
</div> |
|
|
</th> |
|
|
</template> |
|
|
<template v-else> |
|
|
<th v-for="h in displayedColumns" :key="h" @click="setSortKey(h)" |
|
|
class="px-4 py-2 text-left text-xs font-medium text-gray-500 dark:text-gray-300 tracking-wider cursor-pointer select-none"> |
|
|
<div class="flex items-center gap-2"> |
|
|
<span class="whitespace-nowrap">{{ headerDisplayMap[h] || h }}</span> |
|
|
<span v-if="sortKey === h" class="text-xs text-gray-600 dark:text-gray-300"> |
|
|
<span v-if="sortDesc">▼</span> |
|
|
<span v-else>▲</span> |
|
|
</span> |
|
|
</div> |
|
|
</th> |
|
|
</template> |
|
|
</tr> |
|
|
</thead> |
|
|
<tbody class="bg-white dark:bg-transparent divide-y divide-gray-100 dark:divide-gray-700"> |
|
|
|
|
|
<template v-if="selectedMode === 'ModelSeries'"> |
|
|
<tr v-for="(row, idx) in modelSeriesICAvg" :key="row.ModelSeries" |
|
|
class="hover:bg-gray-100 dark:hover:bg-gray-700 transition-colors duration-150"> |
|
|
<td class="px-4 py-3 whitespace-nowrap font-medium text-gray-800 dark:text-gray-50">{{ idx + 1 }}</td> |
|
|
<td v-if="visibleColumns.includes('model_series')" class="px-4 py-3 whitespace-nowrap"> |
|
|
<div class="text-sm text-gray-800 dark:text-gray-50">{{ row.ModelSeries }}</div> |
|
|
</td> |
|
|
|
|
|
<td v-if="visibleColumns.includes('constant')" |
|
|
class="px-4 py-3 whitespace-nowrap"> |
|
|
<div class="text-sm text-gray-800 dark:text-gray-50">{{ row.Constant }}</div> |
|
|
</td> |
|
|
|
|
|
<td v-if="visibleColumns.includes('ic')" |
|
|
class="px-4 py-3 whitespace-nowrap"> |
|
|
<div class="text-sm text-gray-800 dark:text-gray-50">{{ row.IC }}</div> |
|
|
</td> |
|
|
|
|
|
<td v-if="visibleColumns.includes('model_source')" |
|
|
class="px-4 py-3 whitespace-nowrap"> |
|
|
<div class="text-sm text-gray-800 dark:text-gray-50">{{ row.ModelSource }}</div> |
|
|
</td> |
|
|
</tr> |
|
|
</template> |
|
|
|
|
|
|
|
|
<template v-else> |
|
|
<tr v-for="(model, index) in filteredLeaderboard" :key="model.rank" :class="{ |
|
|
// 'bg-yellow-50 dark:bg-yellow-700/25': index === 0, |
|
|
// 'bg-gray-50 dark:bg-gray-800/60': index === 1, |
|
|
// 'bg-indigo-50 dark:bg-indigo-700/25': index === 2 |
|
|
}" class="hover:bg-gray-100 dark:hover:bg-gray-700 transition-colors duration-150"> |
|
|
<td v-for="h in displayedColumns" :key="h" class="px-4 py-3 whitespace-nowrap"> |
|
|
<div class="text-sm text-gray-800 dark:text-gray-50">{{ formatCell(h, model) }}</div> |
|
|
</td> |
|
|
</tr> |
|
|
</template> |
|
|
</tbody> |
|
|
</table> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
|
|
|
<div ref="chartSection" class="mt-8 bg-white dark:bg-gray-900/60 shadow rounded-lg overflow-hidden"> |
|
|
|
|
|
<div |
|
|
class="px-6 py-4 border-b bg-gradient-to-r from-indigo-50 via-white to-white dark:bg-gradient-to-r dark:from-gray-800 dark:via-gray-900 dark:to-gray-900"> |
|
|
<h2 class="text-lg font-medium text-gray-800 dark:text-gray-50">Data visualization</h2> |
|
|
</div> |
|
|
|
|
|
|
|
|
<div class="px-6 py-3 border-b bg-gray-50 dark:bg-gradient-to-b dark:from-gray-900 dark:to-gray-800"> |
|
|
<div class="flex items-center gap-3"> |
|
|
<span class="text-sm font-medium text-gray-700 dark:text-gray-200">Dataset</span> |
|
|
<div v-if="dataGroups.length > 0" class="flex gap-2 items-center overflow-x-auto"> |
|
|
<label v-for="g in dataGroups" :key="g" |
|
|
class="px-2 py-1 rounded-full border border-gray-200 dark:border-gray-700 text-sm cursor-pointer dark:text-slate-300" |
|
|
:class="{ 'bg-gray-100 dark:bg-gray-700 dark:text-white': selectedDataNameChart === g }"> |
|
|
<input type="radio" class="hidden" :value="g" v-model="selectedDataNameChart" /> <span |
|
|
class="whitespace-nowrap">{{ dataNameDisplayMap[g] |
|
|
? dataNameDisplayMap[g] : g }}</span> |
|
|
</label> |
|
|
</div> |
|
|
<div v-else class="text-sm text-gray-500 dark:text-gray-400">(数据集中未检测到 data_name 列)</div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
|
|
|
<div class="p-6"> |
|
|
<Chart :autoShowSeries="autoShowSeries" /> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</template> |
|
|
|
|
|
<style scoped></style> |