| import { ref, computed, reactive } from 'vue' |
| import { parseCsvContent, processModelNames } from '@/utils/csvUtils.js' |
|
|
| |
| const globalState = reactive({ |
| leaderboard: [], |
| csvHeaders: [], |
| loading: true, |
| error: null, |
| |
| sortKey: '', |
| sortDesc: true, |
| visibleColumns: [], |
| dataGroups: [], |
| selectedDataName: '', |
| selectedDataNameChart: '', |
| modelTypeGroups: [], |
| selectedModelType: [], |
| DEFAULT_CSV_PATH: '/filtered.csv', |
| |
| DEFAULT_HIDDEN: new Set(['seq_len', 'uniform_entropy', 'entropy_gain', 'information_capacity', 'data_name', 'model_size (B)']) |
| }) |
|
|
| |
| const modelTypeMapping = { |
| 'Qwen3': ['Qwen3'], |
| 'Qwen2.5': ['Qwen2.5'], |
| 'Qwen2': ['Qwen2'], |
| 'Qwen1.5': ['Qwen1.5'], |
| 'Llama-3': ['Llama-3.1', 'Llama-3.2'], |
| 'InternLM2.5': ['Internlm2.5'], |
| 'GLM-4': ['GLM-4', 'GLM-4'], |
| 'Seed-OSS': ['Seed-OSS'], |
| 'Gemma-3': ['Gemma-3'], |
| 'Hunyuan': ['Hunyuan'], |
| 'Qwen2 (MoE)': ['Qwen2 (MoE)'], |
| 'Qwen1.5 (MoE)': ['Qwen1.5 (MoE)'], |
| 'DeepSeek-V3.1': ['DeepSeek-V3.1-Base'], |
| 'DeepSeek-V2': ['DeepSeek-V2'], |
| 'GLM-4.5': ['GLM-4.5-Air-Base', 'GLM-4.5-Base'], |
| 'Llama-4': ['Llama-4'] |
| } |
|
|
| const MoEModelSeries = ['Qwen2', 'Qwen1.5'] |
|
|
| const strtSymbolSeries = ['Qwen2 (MoE)', 'Qwen1.5 (MoE)', 'DeepSeek-V3.1', 'DeepSeek-V2', 'GLM-4.5', "Llama-4"] |
|
|
| |
| const autoShowSeries = ["*"] |
|
|
| |
| const headerDisplayMap = reactive({ |
| 'rank': 'Rank', |
| 'model_name': 'Model Name', |
| 'model_series': 'Model Series', |
| 'model_size (B)': 'Model Size (B)', |
| 'constant': 'Text Size', |
| 'conditional_entropy': 'Negative Log-Likelihood', |
| 'BF16_TFLOPs': 'FLOPs (G)', |
| 'ic': ' Information Capacity', |
| 'model_source': 'Tested by' |
| }) |
|
|
| |
| const dataNameDisplayMap = reactive({ |
| 'data_part_0000': 'Mixed text', |
| 'eng_Latn_000_00027_long': 'FinePDFs-en', |
| 'IndustryCorpus_batch_aa_long': 'Ch-FineWeb-Edu', |
| 'CC-MAIN-2013-20_train-00000-of-00014_long': 'FineWeb-Edu', |
| 'NextCoderDataset_v1_long': 'NextCoder', |
| }) |
|
|
|
|
| |
| const selectedMode = ref('Model') |
|
|
| |
| const selectableColumns = computed(() => { |
| if (!globalState.csvHeaders || globalState.csvHeaders.length === 0) return [] |
| return globalState.csvHeaders.filter(h => !globalState.DEFAULT_HIDDEN.has(h)) |
| }) |
|
|
| |
| const modelTypeGroups = computed(() => { |
| return Object.keys(modelTypeMapping) |
| }) |
|
|
| |
| const sortedLeaderboard = computed(() => { |
| if (!globalState.leaderboard || globalState.leaderboard.length === 0) return [] |
| const key = globalState.sortKey |
| const desc = !!globalState.sortDesc |
| const arr = [...globalState.leaderboard] |
| if (!key || key === '') return arr |
| arr.sort((a, b) => { |
| const va = a[key] |
| const vb = b[key] |
| |
| if (va == null && vb == null) return 0 |
| if (va == null) return 1 |
| if (vb == null) return -1 |
| const na = Number(va) |
| const nb = Number(vb) |
| if (Number.isFinite(na) && Number.isFinite(nb)) { |
| return desc ? (nb - na) : (na - nb) |
| } |
| try { |
| return desc ? String(vb).localeCompare(String(va)) : String(va).localeCompare(String(vb)) |
| } catch (e) { |
| return 0 |
| } |
| }) |
| return arr |
| }) |
|
|
| |
| const filteredLeaderboard = computed(() => { |
| if (!globalState.leaderboard || globalState.leaderboard.length === 0) return [] |
| |
| let filtered = sortedLeaderboard.value |
|
|
| |
| if (globalState.selectedDataName && globalState.selectedDataName !== 'all') { |
| filtered = filtered.filter(r => String(r['data_name'] ?? '') === String(globalState.selectedDataName)) |
| } |
|
|
| |
| |
| const sel = globalState.selectedModelType |
| if (Array.isArray(sel)) { |
| if (sel.includes('__none__')) return [] |
| if (sel.length > 0) { |
| filtered = filtered.filter(r => sel.includes(String(r['model_type'] ?? ''))) |
| } |
| } |
| |
| return filtered.map((item, index) => ({ ...item, rank: index + 1 })) |
| }) |
|
|
| |
| const modelSeriesICAvg = computed(() => { |
| const rows = globalState.leaderboard || [] |
| const selData = globalState.selectedDataName |
| const selModelTypes = globalState.selectedModelType |
|
|
| |
| const out = [] |
| const keys = Object.keys(modelTypeMapping) |
|
|
| |
| if (Array.isArray(selModelTypes) && selModelTypes.includes('__none__')) return [] |
|
|
| for (const key of keys) { |
| |
| if (Array.isArray(selModelTypes) && selModelTypes.length > 0) { |
| |
| if (!selModelTypes.includes(key)) continue |
| } |
|
|
| const mappedSeries = new Set(modelTypeMapping[key] || []) |
| |
| mappedSeries.add(key) |
|
|
| |
| let sum = 0 |
| let count = 0 |
| let constant = 0 |
| let modelSource = '' |
| for (const r of rows) { |
| |
| if (selData && selData !== 'all') { |
| if (String(r['data_name'] ?? '') !== String(selData)) continue |
| } |
| const seriesName = String(r['model_series'] ?? '').trim() |
| if (!seriesName) continue |
| if (!mappedSeries.has(seriesName)) continue |
| const icRaw = r['ic'] |
| const n = Number(icRaw) |
| if (!Number.isFinite(n)) continue |
| constant = Number(r['constant']) || 0 |
| sum += n |
| count += 1 |
| modelSource = r['model_source'] |
| } |
| if (count === 0) continue |
| const avg = sum / count |
| out.push({ ModelSeries: key, IC: Number(avg.toFixed(4)), Constant: constant ,ModelSource: modelSource }) |
| } |
|
|
| |
| const key = globalState.sortKey |
| const desc = !!globalState.sortDesc |
| if (key && key !== '') { |
| out.sort((a, b) => { |
| let va, vb |
| if (key === 'ic') { |
| va = a.IC |
| vb = b.IC |
| } else if (key === 'constant') { |
| va = a.Constant |
| vb = b.Constant |
| } else { |
| va = a[key] |
| vb = b[key] |
| } |
| |
| if (va == null && vb == null) return 0 |
| if (va == null) return 1 |
| if (vb == null) return -1 |
| const na = Number(va) |
| const nb = Number(vb) |
| if (Number.isFinite(na) && Number.isFinite(nb)) { |
| return desc ? (nb - na) : (na - nb) |
| } |
| try { |
| return desc ? String(vb).localeCompare(String(va)) : String(va).localeCompare(String(vb)) |
| } catch (e) { |
| return 0 |
| } |
| }) |
| } else { |
| |
| out.sort((a, b) => b.IC - a.IC) |
| } |
| return out |
| }) |
|
|
| |
| function setSortKey(h) { |
| if (!h) return |
| if (globalState.sortKey !== h) { |
| globalState.sortKey = h |
| globalState.sortDesc = true |
| return |
| } |
| |
| globalState.sortDesc = !globalState.sortDesc |
| } |
|
|
| |
| const displayedColumns = computed(() => { |
| if (!globalState.csvHeaders || globalState.csvHeaders.length === 0) return [] |
| |
| console.log('csvHeaders:', globalState.csvHeaders) |
| const all = globalState.csvHeaders |
| return all.filter(h => globalState.visibleColumns.includes(h)) |
| }) |
|
|
|
|
| |
| async function fetchAndLoadCsv(path = globalState.DEFAULT_CSV_PATH) { |
| globalState.loading = true |
| globalState.error = null |
|
|
| try { |
| const res = await fetch(path) |
| if (!res.ok) throw new Error(`Failed to fetch CSV (${res.status})`) |
| const txt = await res.text() |
| const { headers, rows } = parseCsvContent(txt) |
| processModelNames(rows) |
| if (!headers || headers.length === 0) { globalState.leaderboard = []; globalState.loading = false; return } |
|
|
| |
| const scoreKey = headers.find(h => ['information_capacity', 'ic', 'score'].includes(h)) || headers.find(h => /capacity|score|ic/i.test(h)) || headers[0] |
| |
| const defaultKey = headers.length > 0 ? headers[headers.length - 1] : scoreKey |
| globalState.sortKey = defaultKey || '' |
| globalState.sortDesc = true |
|
|
|
|
| |
| for (const r of rows) { |
| |
| |
|
|
| const seriesName = String(r['model_series'] ?? '').trim() |
| |
| if (!Object.values(modelTypeMapping).flat().includes(seriesName)) { |
| modelTypeMapping[seriesName] = [seriesName] |
| } |
|
|
| |
| const name = r['model_name'] || '' |
| const sourceMatch = name.match(/\[\[(.+?)\]\]$/) |
| if (sourceMatch) { |
| r['model_source'] = sourceMatch[1] |
| |
| r['model_name'] = name.replace(/\[\[(.+?)\]\]$/, '').trim() |
| } else { |
| r['model_source'] = 'TeleAI' |
| } |
|
|
| |
| for (const moePrefix of MoEModelSeries) { |
| if (name.startsWith(moePrefix)) { |
| |
| const moeSuffixMatch = name.match(/-A(.+)B$/) |
| if (moeSuffixMatch) { |
| |
| r['model_series'] = `${moePrefix} (MoE)` |
| |
| } |
| } |
| } |
|
|
| |
| let modelType = '' |
|
|
| for (const [type, series] of Object.entries(modelTypeMapping)) { |
| if (series.includes(r['model_series'])) { |
| modelType = type |
| break |
| } |
| } |
| r['model_type'] = modelType |
|
|
| |
| r['model_series'] = modelType |
|
|
| } |
|
|
| |
| const preferred = ['model_name', 'model_series', 'model_size (B)', 'seq_len', 'uniform_entropy', 'constant', 'conditional_entropy', 'entropy_gain', 'BF16_TFLOPs', 'information_capacity', 'ic','model_source'] |
| const ordered = [] |
| for (const p of preferred) if (headers.includes(p) && !ordered.includes(p)) ordered.push(p) |
| for (const h of headers) if (!ordered.includes(h)) ordered.push(h) |
| globalState.csvHeaders = ['rank', ...ordered, 'model_source'] |
|
|
| globalState.leaderboard = rows.map((r, idx) => { |
| |
| const modelType = r['model_type'] |
| |
| |
| const originalTFLOPs = Number(r['BF16_TFLOPs']) || 0 |
| const modifiedTFLOPs = (originalTFLOPs / 1024) * 1000 |
| return { rank: idx + 1, model_type: modelType, ...r, BF16_TFLOPs: modifiedTFLOPs } |
| }) |
|
|
| |
|
|
| |
| const seen = new Set() |
| const groups = [] |
| for (const r of rows) { |
| const dn = r['data_name'] |
| if (dn == null) continue |
| const s = String(dn) |
| if (s.trim() === '') continue |
| if (!seen.has(s)) { seen.add(s); groups.push(s) } |
| } |
| globalState.dataGroups = groups |
|
|
| |
| globalState.modelTypeGroups = Object.keys(modelTypeMapping) |
|
|
| |
| if (globalState.dataGroups.length > 0) { |
| globalState.selectedDataName = globalState.dataGroups[0] |
| globalState.selectedDataNameChart = globalState.dataGroups[0] |
| } |
|
|
| |
| if (globalState.modelTypeGroups.length > 0) { |
| globalState.selectedModelType = [...globalState.modelTypeGroups] |
| } |
|
|
| |
| globalState.visibleColumns = ['rank', ...ordered.filter(h => !globalState.DEFAULT_HIDDEN.has(h)), 'model_source'] |
|
|
| |
| const numericFloatCols = new Set(['uniform_entropy', 'conditional_entropy', 'entropy_gain', 'information_capacity', 'ic', 'constant', 'BF16_TFLOPs']) |
| const numericIntCols = new Set(['seq_len']) |
| |
| for (const row of globalState.leaderboard) { |
| row._formatted = {} |
| for (const h of ordered) { |
| const raw = row[h] |
| if (raw == null || raw === '') { row._formatted[h] = ''; continue } |
| if (numericIntCols.has(h)) { |
| const n = Number(raw) |
| row._formatted[h] = Number.isFinite(n) ? String(Math.round(n)) : raw |
| } else if (numericFloatCols.has(h)) { |
| const n = Number(raw) |
| if (h === 'ic') { |
| row._formatted[h] = Number.isFinite(n) ? n.toFixed(4) : raw |
| } |
| else if (h === 'constant') { |
| row._formatted[h] = Number.isFinite(n) ? n.toFixed(2) : raw |
| } |
| else { |
| row._formatted[h] = Number.isFinite(n) ? n.toFixed(3) : raw |
| } |
| } else { |
| row._formatted[h] = raw |
| } |
| } |
| } |
| } catch (e) { |
| console.error(e) |
| globalState.error = e && e.message ? e.message : String(e) |
| } finally { |
| globalState.loading = false |
| } |
| } |
|
|
| function selectAll() { |
| |
| globalState.visibleColumns = [...selectableColumns.value] |
| } |
|
|
| function clearAll() { |
| globalState.visibleColumns = [] |
| } |
|
|
| function selectAllModelTypes() { |
| globalState.selectedModelType = [...modelTypeGroups.value] |
| } |
|
|
| function clearAllModelTypes() { |
| |
| globalState.selectedModelType = ['__none__'] |
| } |
|
|
| function formatCell(h, model) { |
| if (!model) return '' |
| if (model._formatted && model._formatted[h] !== undefined) return model._formatted[h] |
| return model[h] |
| } |
|
|
| |
| function init() { |
| fetchAndLoadCsv() |
| } |
|
|
| export function useLeaderboardData() { |
| return { |
| |
| leaderboard: computed(() => globalState.leaderboard), |
| csvHeaders: computed(() => globalState.csvHeaders), |
| loading: computed(() => globalState.loading), |
| error: computed(() => globalState.error), |
| visibleColumns: computed({ |
| get: () => globalState.visibleColumns, |
| set: (v) => globalState.visibleColumns = v |
| }), |
| selectedMode: computed({ |
| get: () => selectedMode.value, |
| set: (v) => selectedMode.value = v |
| }), |
| selectableColumns, |
| autoShowSeries, |
| strtSymbolSeries, |
| headerDisplayMap: computed(() => headerDisplayMap), |
| dataNameDisplayMap: computed(() => dataNameDisplayMap), |
| dataGroups: computed(() => globalState.dataGroups), |
| selectedDataName: computed({ |
| get: () => globalState.selectedDataName, |
| set: (v) => globalState.selectedDataName = v |
| }), |
| selectedDataNameChart: computed({ |
| get: () => globalState.selectedDataNameChart, |
| set: (v) => globalState.selectedDataNameChart = v |
| }), |
| modelTypeGroups: computed(() => globalState.modelTypeGroups), |
| selectedModelType: computed({ |
| get: () => globalState.selectedModelType, |
| set: (v) => { |
| |
| if (Array.isArray(v) && v.some(x => x !== '__none__')) { |
| globalState.selectedModelType = v.filter(x => x !== '__none__') |
| } else { |
| globalState.selectedModelType = v |
| } |
| } |
| }), |
| filteredLeaderboard, |
| displayedColumns, |
| modelSeriesICAvg, |
| |
| fetchAndLoadCsv, |
| selectAll, |
| clearAll, |
| selectAllModelTypes, |
| clearAllModelTypes, |
| |
| sortKey: computed(() => globalState.sortKey), |
| sortDesc: computed(() => globalState.sortDesc), |
| setSortKey, |
| formatCell, |
| init |
| } |
| } |