Caleb Fahlgren
commited on
Commit
·
02eb851
1
Parent(s):
132e085
add generic table, finetune leaderboard
Browse files- app/page.tsx +20 -2
- components/simple-table.tsx +84 -0
- components/ui/skeleton.tsx +15 -0
- components/ui/table.tsx +117 -0
- lib/queries.ts +28 -6
app/page.tsx
CHANGED
@@ -5,11 +5,12 @@ import * as duckdb from "@duckdb/duckdb-wasm"
|
|
5 |
import { Loader2 } from "lucide-react"
|
6 |
import { toast } from 'sonner'
|
7 |
|
8 |
-
import { CREATE_VIEWS_QUERY, FETCH_CHART_DATA_QUERY, FETCH_DATASET_LICENSE_DATA_QUERY, FETCH_FINETUNE_MODEL_GROWTH_QUERY, FETCH_MODEL_LICENSE_DATA_QUERY, FETCH_SPACE_SDK_DATA_QUERY } from "@/lib/queries"
|
9 |
import { AreaChartStacked, ChartDataPoint } from "@/components/area-chart-stacked"
|
10 |
import { CustomPieChart } from "@/components/pie-chart"
|
11 |
import { SimpleArea } from "@/components/simple-area"
|
12 |
import { Button } from "@/components/ui/button"
|
|
|
13 |
|
14 |
export default function IndexPage() {
|
15 |
const [conn, setConn] = useState<duckdb.AsyncDuckDBConnection | null>(null)
|
@@ -20,6 +21,7 @@ export default function IndexPage() {
|
|
20 |
const [baseModel, setBaseModel] = useState("meta-llama/Meta-Llama-3-8B")
|
21 |
const [finetuneModelGrowthData, setFinetuneModelGrowthData] = useState<Array<{ date: Date; count: number }>>([])
|
22 |
const [isLoading, setIsLoading] = useState(false)
|
|
|
23 |
|
24 |
useEffect(() => {
|
25 |
initDB()
|
@@ -72,11 +74,12 @@ export default function IndexPage() {
|
|
72 |
|
73 |
setChartData(data)
|
74 |
|
75 |
-
const [modelLicenseResult, datasetLicenseResult, spaceSdkResult] =
|
76 |
await Promise.all([
|
77 |
connection.query(FETCH_MODEL_LICENSE_DATA_QUERY),
|
78 |
connection.query(FETCH_DATASET_LICENSE_DATA_QUERY),
|
79 |
connection.query(FETCH_SPACE_SDK_DATA_QUERY),
|
|
|
80 |
])
|
81 |
|
82 |
setModelLicenseData(
|
@@ -102,6 +105,11 @@ export default function IndexPage() {
|
|
102 |
fill: `hsl(${index * 30}, 70%, 50%)`,
|
103 |
}))
|
104 |
)
|
|
|
|
|
|
|
|
|
|
|
105 |
}
|
106 |
|
107 |
const handleBaseModelSubmit = async (e: React.FormEvent) => {
|
@@ -165,6 +173,15 @@ export default function IndexPage() {
|
|
165 |
</div>
|
166 |
</div>
|
167 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
168 |
<div className="flex flex-col items-center gap-4 max-w-6xl mt-10 w-full mx-auto">
|
169 |
<h2 className="text-4xl font-bold text-center">Finetuned Model Growth</h2>
|
170 |
<p className="text-center mb-4">Find how many finetuned models have been created for your favorite model</p>
|
@@ -198,6 +215,7 @@ export default function IndexPage() {
|
|
198 |
/>
|
199 |
</div>
|
200 |
)}
|
|
|
201 |
</section>
|
202 |
)
|
203 |
}
|
|
|
5 |
import { Loader2 } from "lucide-react"
|
6 |
import { toast } from 'sonner'
|
7 |
|
8 |
+
import { CREATE_VIEWS_QUERY, FETCH_CHART_DATA_QUERY, FETCH_DATASET_LICENSE_DATA_QUERY, FETCH_FINETUNE_MODEL_GROWTH_QUERY, FETCH_MODEL_LICENSE_DATA_QUERY, FETCH_SPACE_SDK_DATA_QUERY, FETCH_TOP_BASE_MODELS_TABLE_QUERY } from "@/lib/queries"
|
9 |
import { AreaChartStacked, ChartDataPoint } from "@/components/area-chart-stacked"
|
10 |
import { CustomPieChart } from "@/components/pie-chart"
|
11 |
import { SimpleArea } from "@/components/simple-area"
|
12 |
import { Button } from "@/components/ui/button"
|
13 |
+
import { GenericTable } from "@/components/simple-table"
|
14 |
|
15 |
export default function IndexPage() {
|
16 |
const [conn, setConn] = useState<duckdb.AsyncDuckDBConnection | null>(null)
|
|
|
21 |
const [baseModel, setBaseModel] = useState("meta-llama/Meta-Llama-3-8B")
|
22 |
const [finetuneModelGrowthData, setFinetuneModelGrowthData] = useState<Array<{ date: Date; count: number }>>([])
|
23 |
const [isLoading, setIsLoading] = useState(false)
|
24 |
+
const [topFinetunedModels, setTopFinetunedModels] = useState<Array<{ model: string; finetunes: number }> | undefined>(undefined)
|
25 |
|
26 |
useEffect(() => {
|
27 |
initDB()
|
|
|
74 |
|
75 |
setChartData(data)
|
76 |
|
77 |
+
const [modelLicenseResult, datasetLicenseResult, spaceSdkResult, topFinetunedModelsResult] =
|
78 |
await Promise.all([
|
79 |
connection.query(FETCH_MODEL_LICENSE_DATA_QUERY),
|
80 |
connection.query(FETCH_DATASET_LICENSE_DATA_QUERY),
|
81 |
connection.query(FETCH_SPACE_SDK_DATA_QUERY),
|
82 |
+
connection.query(FETCH_TOP_BASE_MODELS_TABLE_QUERY),
|
83 |
])
|
84 |
|
85 |
setModelLicenseData(
|
|
|
105 |
fill: `hsl(${index * 30}, 70%, 50%)`,
|
106 |
}))
|
107 |
)
|
108 |
+
|
109 |
+
setTopFinetunedModels(topFinetunedModelsResult.toArray().map(row => ({
|
110 |
+
model: row.model,
|
111 |
+
finetunes: Number(row.finetunes)
|
112 |
+
})))
|
113 |
}
|
114 |
|
115 |
const handleBaseModelSubmit = async (e: React.FormEvent) => {
|
|
|
173 |
</div>
|
174 |
</div>
|
175 |
|
176 |
+
<div className="flex flex-col gap-4 max-w-4xl mt-10 w-full mx-auto">
|
177 |
+
<h2 className="text-4xl font-bold my-10 text-center">Finetuned Model Leaderboard</h2>
|
178 |
+
<GenericTable
|
179 |
+
data={topFinetunedModels}
|
180 |
+
caption="Top 10 base models by number of finetunes"
|
181 |
+
/>
|
182 |
+
</div>
|
183 |
+
|
184 |
+
|
185 |
<div className="flex flex-col items-center gap-4 max-w-6xl mt-10 w-full mx-auto">
|
186 |
<h2 className="text-4xl font-bold text-center">Finetuned Model Growth</h2>
|
187 |
<p className="text-center mb-4">Find how many finetuned models have been created for your favorite model</p>
|
|
|
215 |
/>
|
216 |
</div>
|
217 |
)}
|
218 |
+
|
219 |
</section>
|
220 |
)
|
221 |
}
|
components/simple-table.tsx
ADDED
@@ -0,0 +1,84 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import {
|
2 |
+
Table,
|
3 |
+
TableBody,
|
4 |
+
TableCaption,
|
5 |
+
TableCell,
|
6 |
+
TableHead,
|
7 |
+
TableHeader,
|
8 |
+
TableRow,
|
9 |
+
} from "@/components/ui/table"
|
10 |
+
import { Skeleton } from "@/components/ui/skeleton"
|
11 |
+
|
12 |
+
interface TableData {
|
13 |
+
[key: string]: string | number;
|
14 |
+
}
|
15 |
+
|
16 |
+
interface TableProps {
|
17 |
+
data: TableData[] | undefined;
|
18 |
+
caption?: string;
|
19 |
+
}
|
20 |
+
|
21 |
+
export function GenericTable({ data, caption }: TableProps) {
|
22 |
+
const headers = data && data.length > 0 ? ['#', ...Object.keys(data[0])] : [];
|
23 |
+
const isLoading = !data;
|
24 |
+
const isEmpty = data && data.length === 0;
|
25 |
+
|
26 |
+
const renderSkeleton = (count: number) => (
|
27 |
+
[...Array(count)].map((_, index) => (
|
28 |
+
<TableCell key={index}>
|
29 |
+
<Skeleton className="h-4 w-full" />
|
30 |
+
</TableCell>
|
31 |
+
))
|
32 |
+
);
|
33 |
+
|
34 |
+
const renderHeaders = () => headers.map((header, index) => (
|
35 |
+
<TableHead
|
36 |
+
key={header}
|
37 |
+
className={`${index === 0 ? 'text-right' : 'text-left'} text-black font-bold`}
|
38 |
+
>
|
39 |
+
{header.toUpperCase()}
|
40 |
+
</TableHead>
|
41 |
+
));
|
42 |
+
|
43 |
+
const renderRows = () => {
|
44 |
+
if (isLoading) {
|
45 |
+
return [...Array(10)].map((_, index) => <TableRow key={index}>{renderSkeleton(5)}</TableRow>);
|
46 |
+
}
|
47 |
+
if (isEmpty) {
|
48 |
+
return (
|
49 |
+
<TableRow>
|
50 |
+
<TableCell colSpan={headers.length || 1} className="text-center py-4">
|
51 |
+
No results found
|
52 |
+
</TableCell>
|
53 |
+
</TableRow>
|
54 |
+
);
|
55 |
+
}
|
56 |
+
return data.map((row, index) => (
|
57 |
+
<TableRow key={index}>
|
58 |
+
<TableCell className="text-right font-medium">{index + 1}</TableCell>
|
59 |
+
{Object.entries(row).map(([key, value]) => (
|
60 |
+
<TableCell
|
61 |
+
key={`${index}-${key}`}
|
62 |
+
className={key.toLowerCase().includes('amount') ? 'text-right' : ''}
|
63 |
+
>
|
64 |
+
{value}
|
65 |
+
</TableCell>
|
66 |
+
))}
|
67 |
+
</TableRow>
|
68 |
+
));
|
69 |
+
};
|
70 |
+
|
71 |
+
return (
|
72 |
+
<Table>
|
73 |
+
{caption && <TableCaption>{caption}</TableCaption>}
|
74 |
+
<TableHeader>
|
75 |
+
<TableRow>
|
76 |
+
{isLoading ? renderSkeleton(5) : isEmpty ? null : renderHeaders()}
|
77 |
+
</TableRow>
|
78 |
+
</TableHeader>
|
79 |
+
<TableBody>
|
80 |
+
{renderRows()}
|
81 |
+
</TableBody>
|
82 |
+
</Table>
|
83 |
+
);
|
84 |
+
}
|
components/ui/skeleton.tsx
ADDED
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import { cn } from "@/lib/utils"
|
2 |
+
|
3 |
+
function Skeleton({
|
4 |
+
className,
|
5 |
+
...props
|
6 |
+
}: React.HTMLAttributes<HTMLDivElement>) {
|
7 |
+
return (
|
8 |
+
<div
|
9 |
+
className={cn("animate-pulse rounded-md bg-muted", className)}
|
10 |
+
{...props}
|
11 |
+
/>
|
12 |
+
)
|
13 |
+
}
|
14 |
+
|
15 |
+
export { Skeleton }
|
components/ui/table.tsx
ADDED
@@ -0,0 +1,117 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import * as React from "react"
|
2 |
+
|
3 |
+
import { cn } from "@/lib/utils"
|
4 |
+
|
5 |
+
const Table = React.forwardRef<
|
6 |
+
HTMLTableElement,
|
7 |
+
React.HTMLAttributes<HTMLTableElement>
|
8 |
+
>(({ className, ...props }, ref) => (
|
9 |
+
<div className="relative w-full overflow-auto">
|
10 |
+
<table
|
11 |
+
ref={ref}
|
12 |
+
className={cn("w-full caption-bottom text-sm", className)}
|
13 |
+
{...props}
|
14 |
+
/>
|
15 |
+
</div>
|
16 |
+
))
|
17 |
+
Table.displayName = "Table"
|
18 |
+
|
19 |
+
const TableHeader = React.forwardRef<
|
20 |
+
HTMLTableSectionElement,
|
21 |
+
React.HTMLAttributes<HTMLTableSectionElement>
|
22 |
+
>(({ className, ...props }, ref) => (
|
23 |
+
<thead ref={ref} className={cn("[&_tr]:border-b", className)} {...props} />
|
24 |
+
))
|
25 |
+
TableHeader.displayName = "TableHeader"
|
26 |
+
|
27 |
+
const TableBody = React.forwardRef<
|
28 |
+
HTMLTableSectionElement,
|
29 |
+
React.HTMLAttributes<HTMLTableSectionElement>
|
30 |
+
>(({ className, ...props }, ref) => (
|
31 |
+
<tbody
|
32 |
+
ref={ref}
|
33 |
+
className={cn("[&_tr:last-child]:border-0", className)}
|
34 |
+
{...props}
|
35 |
+
/>
|
36 |
+
))
|
37 |
+
TableBody.displayName = "TableBody"
|
38 |
+
|
39 |
+
const TableFooter = React.forwardRef<
|
40 |
+
HTMLTableSectionElement,
|
41 |
+
React.HTMLAttributes<HTMLTableSectionElement>
|
42 |
+
>(({ className, ...props }, ref) => (
|
43 |
+
<tfoot
|
44 |
+
ref={ref}
|
45 |
+
className={cn(
|
46 |
+
"border-t bg-muted/50 font-medium [&>tr]:last:border-b-0",
|
47 |
+
className
|
48 |
+
)}
|
49 |
+
{...props}
|
50 |
+
/>
|
51 |
+
))
|
52 |
+
TableFooter.displayName = "TableFooter"
|
53 |
+
|
54 |
+
const TableRow = React.forwardRef<
|
55 |
+
HTMLTableRowElement,
|
56 |
+
React.HTMLAttributes<HTMLTableRowElement>
|
57 |
+
>(({ className, ...props }, ref) => (
|
58 |
+
<tr
|
59 |
+
ref={ref}
|
60 |
+
className={cn(
|
61 |
+
"border-b transition-colors hover:bg-muted/50 data-[state=selected]:bg-muted",
|
62 |
+
className
|
63 |
+
)}
|
64 |
+
{...props}
|
65 |
+
/>
|
66 |
+
))
|
67 |
+
TableRow.displayName = "TableRow"
|
68 |
+
|
69 |
+
const TableHead = React.forwardRef<
|
70 |
+
HTMLTableCellElement,
|
71 |
+
React.ThHTMLAttributes<HTMLTableCellElement>
|
72 |
+
>(({ className, ...props }, ref) => (
|
73 |
+
<th
|
74 |
+
ref={ref}
|
75 |
+
className={cn(
|
76 |
+
"h-12 px-4 text-left align-middle font-medium text-muted-foreground [&:has([role=checkbox])]:pr-0",
|
77 |
+
className
|
78 |
+
)}
|
79 |
+
{...props}
|
80 |
+
/>
|
81 |
+
))
|
82 |
+
TableHead.displayName = "TableHead"
|
83 |
+
|
84 |
+
const TableCell = React.forwardRef<
|
85 |
+
HTMLTableCellElement,
|
86 |
+
React.TdHTMLAttributes<HTMLTableCellElement>
|
87 |
+
>(({ className, ...props }, ref) => (
|
88 |
+
<td
|
89 |
+
ref={ref}
|
90 |
+
className={cn("p-4 align-middle [&:has([role=checkbox])]:pr-0", className)}
|
91 |
+
{...props}
|
92 |
+
/>
|
93 |
+
))
|
94 |
+
TableCell.displayName = "TableCell"
|
95 |
+
|
96 |
+
const TableCaption = React.forwardRef<
|
97 |
+
HTMLTableCaptionElement,
|
98 |
+
React.HTMLAttributes<HTMLTableCaptionElement>
|
99 |
+
>(({ className, ...props }, ref) => (
|
100 |
+
<caption
|
101 |
+
ref={ref}
|
102 |
+
className={cn("mt-4 text-sm text-muted-foreground", className)}
|
103 |
+
{...props}
|
104 |
+
/>
|
105 |
+
))
|
106 |
+
TableCaption.displayName = "TableCaption"
|
107 |
+
|
108 |
+
export {
|
109 |
+
Table,
|
110 |
+
TableHeader,
|
111 |
+
TableBody,
|
112 |
+
TableFooter,
|
113 |
+
TableHead,
|
114 |
+
TableRow,
|
115 |
+
TableCell,
|
116 |
+
TableCaption,
|
117 |
+
}
|
lib/queries.ts
CHANGED
@@ -45,8 +45,11 @@ export const FETCH_SPACE_SDK_DATA_QUERY = `
|
|
45 |
export const FETCH_FINETUNE_MODEL_GROWTH_QUERY = (baseModel: string) => `
|
46 |
WITH RECURSIVE month_series AS (
|
47 |
SELECT DATE_TRUNC('month', MIN(CAST(createdAt AS TIMESTAMP))) - INTERVAL 1 MONTH AS month
|
48 |
-
FROM models
|
49 |
-
WHERE
|
|
|
|
|
|
|
50 |
|
51 |
UNION ALL
|
52 |
|
@@ -55,15 +58,34 @@ export const FETCH_FINETUNE_MODEL_GROWTH_QUERY = (baseModel: string) => `
|
|
55 |
WHERE month < DATE_TRUNC('month', CURRENT_DATE)
|
56 |
),
|
57 |
finetuned_models AS (
|
58 |
-
SELECT DATE_TRUNC('month', CAST(createdAt AS TIMESTAMP)) AS creation_month
|
59 |
-
FROM models
|
60 |
-
WHERE
|
|
|
|
|
|
|
61 |
)
|
62 |
SELECT
|
63 |
strftime(ms.month, '%Y-%m') as date,
|
64 |
-
COALESCE(SUM(COUNT(fm.
|
65 |
FROM month_series ms
|
66 |
LEFT JOIN finetuned_models fm ON ms.month = fm.creation_month
|
67 |
GROUP BY ms.month
|
68 |
ORDER BY ms.month
|
69 |
`
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
45 |
export const FETCH_FINETUNE_MODEL_GROWTH_QUERY = (baseModel: string) => `
|
46 |
WITH RECURSIVE month_series AS (
|
47 |
SELECT DATE_TRUNC('month', MIN(CAST(createdAt AS TIMESTAMP))) - INTERVAL 1 MONTH AS month
|
48 |
+
FROM models
|
49 |
+
WHERE EXISTS (
|
50 |
+
SELECT 1 FROM UNNEST(tags) AS t(tag)
|
51 |
+
WHERE tag ILIKE 'base_model:%${baseModel}'
|
52 |
+
)
|
53 |
|
54 |
UNION ALL
|
55 |
|
|
|
58 |
WHERE month < DATE_TRUNC('month', CURRENT_DATE)
|
59 |
),
|
60 |
finetuned_models AS (
|
61 |
+
SELECT DISTINCT id, DATE_TRUNC('month', CAST(createdAt AS TIMESTAMP)) AS creation_month
|
62 |
+
FROM models
|
63 |
+
WHERE EXISTS (
|
64 |
+
SELECT 1 FROM UNNEST(tags) AS t(tag)
|
65 |
+
WHERE tag ILIKE 'base_model:%${baseModel}'
|
66 |
+
)
|
67 |
)
|
68 |
SELECT
|
69 |
strftime(ms.month, '%Y-%m') as date,
|
70 |
+
COALESCE(SUM(COUNT(DISTINCT fm.id)) OVER (ORDER BY ms.month), 0) AS count
|
71 |
FROM month_series ms
|
72 |
LEFT JOIN finetuned_models fm ON ms.month = fm.creation_month
|
73 |
GROUP BY ms.month
|
74 |
ORDER BY ms.month
|
75 |
`
|
76 |
+
|
77 |
+
export const FETCH_TOP_BASE_MODELS_TABLE_QUERY = `
|
78 |
+
WITH base_models AS (
|
79 |
+
SELECT DISTINCT id,
|
80 |
+
REGEXP_REPLACE(SUBSTRING(tag, 12), '^(finetune:|adapter:)', '') AS model
|
81 |
+
FROM models, UNNEST(tags) AS t(tag)
|
82 |
+
WHERE tag ILIKE 'base_model:%'
|
83 |
+
)
|
84 |
+
SELECT
|
85 |
+
model,
|
86 |
+
COUNT(DISTINCT id) AS finetunes
|
87 |
+
FROM base_models
|
88 |
+
GROUP BY model
|
89 |
+
ORDER BY finetunes DESC
|
90 |
+
LIMIT 10
|
91 |
+
`
|