xianbao HF staff commited on
Commit
5728fdf
1 Parent(s): fb129e5

Upload folder using huggingface_hub

Browse files
Files changed (3) hide show
  1. bun.lockb +0 -0
  2. package.json +0 -1
  3. src/pages/index.tsx +104 -137
bun.lockb CHANGED
Binary files a/bun.lockb and b/bun.lockb differ
 
package.json CHANGED
@@ -9,7 +9,6 @@
9
  "lint": "next lint"
10
  },
11
  "dependencies": {
12
- "@duckdb/duckdb-wasm": "^1.28.1-dev106.0",
13
  "@emotion/react": "^11.13.0",
14
  "@emotion/styled": "^11.13.0",
15
  "@mui/material": "^5.16.6",
 
9
  "lint": "next lint"
10
  },
11
  "dependencies": {
 
12
  "@emotion/react": "^11.13.0",
13
  "@emotion/styled": "^11.13.0",
14
  "@mui/material": "^5.16.6",
src/pages/index.tsx CHANGED
@@ -2,184 +2,151 @@
2
 
3
  import { Inter } from "next/font/google";
4
  import ActivityCalendar from "react-activity-calendar";
5
- import * as duckdb from "@duckdb/duckdb-wasm"
6
  import { useState, useEffect } from "react";
7
  import { Tooltip as MuiTooltip } from '@mui/material';
8
 
9
  const inter = Inter({ subsets: ["latin"] });
10
 
11
- interface CustomActivity {
 
 
 
 
 
12
  date: string;
13
  count: number;
14
  level: number;
15
- details: Array<{ provider: string; count: number }>;
16
  }
17
 
18
- type ProviderKey = "BAAI" | "deepseek-ai" | "internlm" | "Qwen" | "THUDM" | "TencentARC" | "01-ai" | "openbmb";
19
-
20
  export default function Home() {
21
- const [calendarData, setCalendarData] = useState<Record<ProviderKey, CustomActivity[]>>({} as Record<ProviderKey, CustomActivity[]>);
22
  const [isLoading, setIsLoading] = useState(true);
23
 
24
- const PROVIDERS_MAP: Record<ProviderKey, { name: string; color: string }> = {
25
- "BAAI": { "name": "BAAI", "color": "#FF6F61" }, // Coral Red
26
- "deepseek-ai": { "name": "Deepseek", "color": "#4B8BBE" }, // Soft Blue
27
- "internlm": { "name": "Internlm", "color": "#34A853" }, // Emerald Green
28
- "Qwen": { "name": "Qwen", "color": "#FFA500" }, // Bright Orange
29
- "THUDM": { "name": "GLM", "color": "#00A6D6" }, // Cerulean Blue
30
- "TencentARC": { "name": "Tencent", "color": "#1DA1F2" }, // Twitter Blue
31
- "01-ai": { "name": "Yi/01", "color": "#FF6347" }, // Tomato Red
32
- "openbmb": { "name": "OpenBMB", "color": "#8A2BE2" }, // Blue Violet
33
  }
34
 
35
- const getModelData = async (conn: duckdb.AsyncDuckDBConnection) => {
36
- const result = await conn.query(`
37
- SELECT
38
- STRFTIME(DATE_TRUNC('day', CAST(createdAt AS DATE)), '%Y-%m-%d') AS date,
39
- CASE
40
- WHEN provider IN ('TencentARC', 'Tencent-Hunyuan') THEN 'TencentARC'
41
- ELSE provider
42
- END AS provider,
43
- COUNT(*) AS count
44
- FROM (
45
- SELECT *, SPLIT_PART(id, '/', 1) AS provider
46
- FROM models
47
- WHERE CAST(createdAt AS DATE) >= DATE_TRUNC('year', CURRENT_DATE)
48
- ) subquery
49
- WHERE provider IN (${Object.keys(PROVIDERS_MAP).map(p => `'${p}'`).join(', ')}, 'Tencent-Hunyuan')
50
- GROUP BY 1, 2
51
- ORDER BY date
52
- `);
53
- return result.toArray().map((row: any) => ({
54
- date: row.date,
55
- provider: row.provider,
56
- count: Number(row.count)
57
- }));
58
- }
59
-
60
- const generateCalendarData = (modelData: any[]) => {
61
- const data: Record<ProviderKey, CustomActivity[]> = Object.keys(PROVIDERS_MAP).reduce((acc, provider) => {
62
- acc[provider as ProviderKey] = [];
63
- return acc;
64
- }, {} as Record<ProviderKey, CustomActivity[]>);
65
 
66
  const today = new Date();
67
- const startOfYear = new Date(today.getFullYear(), 0, 1);
 
 
68
 
69
- for (let d = new Date(startOfYear); d <= today; d.setDate(d.getDate() + 1)) {
 
70
  const dateString = d.toISOString().split('T')[0];
71
 
72
- Object.keys(PROVIDERS_MAP).forEach((provider) => {
73
- const dayData = modelData.filter(item => item.date === dateString && item.provider === provider);
74
- const count = dayData.reduce((sum, item) => sum + item.count, 0);
 
 
75
 
76
- data[provider as ProviderKey].push({
77
- date: dateString,
78
- count,
79
- level: 0,
80
- details: dayData,
81
- });
82
  });
83
  }
84
 
85
- const avgCounts: Record<ProviderKey, number> = Object.fromEntries(
86
- Object.keys(PROVIDERS_MAP).map(provider => [
 
87
  provider,
88
- data[provider as ProviderKey].reduce((sum, day) => sum + day.count, 0) / data[provider as ProviderKey].length || 0
89
  ])
90
- ) as Record<ProviderKey, number>;
91
 
 
92
  Object.entries(data).forEach(([provider, days]) => {
93
- const avgCount = avgCounts[provider as ProviderKey];
94
  days.forEach(day => {
95
- day.level = day.count === 0 ? 0 :
96
- day.count <= avgCount * 0.5 ? 1 :
97
- day.count <= avgCount ? 2 :
98
- day.count <= avgCount * 1.5 ? 3 : 4;
 
99
  });
100
  });
101
 
102
  return data;
103
  }
104
 
105
- const initDB = async () => {
106
- const CDN_BASE = `https://cdn.jsdelivr.net/npm/@duckdb/duckdb-wasm@next`
107
-
108
- const JSDELIVR_BUNDLES = {
109
- mvp: {
110
- mainModule: `${CDN_BASE}/dist/duckdb-mvp.wasm`,
111
- mainWorker: `${CDN_BASE}/dist/duckdb-browser-mvp.worker.js`,
112
- },
113
- eh: {
114
- mainModule: `${CDN_BASE}/dist/duckdb-eh.wasm`,
115
- mainWorker: `${CDN_BASE}/dist/duckdb-browser-eh.worker.js`,
116
- },
 
 
 
 
 
 
 
 
 
 
 
117
  }
118
-
119
- const bundle = await duckdb.selectBundle(JSDELIVR_BUNDLES)
120
- const worker_url = URL.createObjectURL(
121
- new Blob([`importScripts("${bundle.mainWorker}");`], {
122
- type: "text/javascript",
123
- })
124
- )
125
-
126
- const worker = new Worker(worker_url)
127
- const logger = new duckdb.ConsoleLogger()
128
- const db = new duckdb.AsyncDuckDB(logger, worker)
129
- await db.instantiate(bundle.mainModule)
130
-
131
- const connection = await db.connect()
132
-
133
- await connection.query(`
134
- CREATE VIEW models AS SELECT * FROM read_parquet('https://huggingface.co/datasets/cfahlgren1/hub-stats/resolve/refs%2Fconvert%2Fparquet/models/train/0000.parquet?download=true');
135
- `);
136
-
137
- const modelData = await getModelData(connection);
138
- const calendarData = generateCalendarData(modelData);
139
- setCalendarData(calendarData);
140
- setIsLoading(false);
141
-
142
- await connection.close();
143
  }
144
 
145
  useEffect(() => {
146
- initDB();
147
  }, []);
148
 
149
- return (<main className={`grid grid-cols-1 md:grid-cols-2 gap-8 min-h-screen mx-auto p-6 ${inter.className}`}>
150
- <div className="col-span-2 text-center">
151
- <h1 className="text-5xl font-bold">Chinese AI Community: Open Source Heatmap</h1>
152
- <p className="mt-2 text-sm">A heatmap for open source model releases.</p>
153
- </div>
154
- {isLoading ? (
155
- <div className="col-span-2 text-center">
156
- <p>Loading...</p>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
157
  </div>
158
- ) : (
159
- Object.entries(PROVIDERS_MAP)
160
- .sort(([keyA], [keyB]) =>
161
- calendarData[keyB as ProviderKey].reduce((sum, day) => sum + day.count, 0) -
162
- calendarData[keyA as ProviderKey].reduce((sum, day) => sum + day.count, 0)
163
- )
164
- .map(([key, value]) => (
165
- <div key={key} className="mt-16 md:col-span-1">
166
- <h2 className="text-2xl font-bold mb-2">{value.name}</h2>
167
- <ActivityCalendar
168
- data={calendarData[key as ProviderKey]}
169
- theme={{
170
- dark: ['#161b22', value.color],
171
- }}
172
- colorScheme="dark"
173
- renderBlock={(block, activity) => (
174
- <MuiTooltip title={`${activity.count} activities on ${activity.date}`}>
175
- {block}
176
- </MuiTooltip>
177
- )}
178
- />
179
- </div>
180
- ))
181
- )}
182
- </main>
183
-
184
  );
185
  }
 
2
 
3
  import { Inter } from "next/font/google";
4
  import ActivityCalendar from "react-activity-calendar";
 
5
  import { useState, useEffect } from "react";
6
  import { Tooltip as MuiTooltip } from '@mui/material';
7
 
8
  const inter = Inter({ subsets: ["latin"] });
9
 
10
+ interface ModelData {
11
+ createdAt: string;
12
+ id: string;
13
+ }
14
+
15
+ interface Activity {
16
  date: string;
17
  count: number;
18
  level: number;
 
19
  }
20
 
 
 
21
  export default function Home() {
22
+ const [calendarData, setCalendarData] = useState<Record<string, Activity[]>>({});
23
  const [isLoading, setIsLoading] = useState(true);
24
 
25
+ const PROVIDERS_MAP: Record<string, { color: string; authors: string[] }> = {
26
+ "BAAI": { color: "#ff7000", authors: ["BAAI"] }, // Vibrant Orange
27
+ "DeepSeek": { color: "#007ACC", authors: ["deepseek-ai"] }, // Light Blue
28
+ "Shanghai AI Lab": { color: "#10A37F", authors: ["internlm", "OpenGVLab", "openmmlab"] }, // Fresh Green
29
+ "Alibaba": { color: "#D2691E", authors: ["Qwen", "Alibaba-NLP", "alibaba-pai", "DAMO-NLP-SG"] }, // Chocolate
30
+ "GLM": { color: "#4285F4", authors: ["THUDM"] }, // Classic Blue
31
+ "Tencent": { color: "#1DA1F2", authors: ["TencentARC", "Tencent-Hunyuan"] }, // Twitter Blue
32
+ "Yi/01": { color: "#FF4500", authors: ["01-ai"] }, // Orange-Red
 
33
  }
34
 
35
+ const generateCalendarData = (modelData: ModelData[]) => {
36
+ const data: Record<string, Activity[]> = Object.fromEntries(
37
+ Object.keys(PROVIDERS_MAP).map(provider => [provider, []])
38
+ );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
39
 
40
  const today = new Date();
41
+ const startDate = new Date(today);
42
+ startDate.setMonth(today.getMonth() - 11);
43
+ startDate.setDate(1); // start from the first day of the month
44
 
45
+ // generate daily data for each provider
46
+ for (let d = new Date(startDate); d <= today; d.setDate(d.getDate() + 1)) {
47
  const dateString = d.toISOString().split('T')[0];
48
 
49
+ Object.entries(PROVIDERS_MAP).forEach(([provider, { authors }]) => {
50
+ const count = modelData.filter(item =>
51
+ item.createdAt.startsWith(dateString) &&
52
+ authors.some(author => item.id.startsWith(author))
53
+ ).length;
54
 
55
+ data[provider].push({ date: dateString, count, level: 0 });
 
 
 
 
 
56
  });
57
  }
58
 
59
+ // calculate average counts for each provider
60
+ const avgCounts = Object.fromEntries(
61
+ Object.entries(data).map(([provider, days]) => [
62
  provider,
63
+ days.reduce((sum, day) => sum + day.count, 0) / days.length || 0
64
  ])
65
+ );
66
 
67
+ // assign levels based on count relative to average
68
  Object.entries(data).forEach(([provider, days]) => {
69
+ const avgCount = avgCounts[provider];
70
  days.forEach(day => {
71
+ day.level =
72
+ day.count === 0 ? 0 :
73
+ day.count <= avgCount * 0.5 ? 1 :
74
+ day.count <= avgCount ? 2 :
75
+ day.count <= avgCount * 1.5 ? 3 : 4;
76
  });
77
  });
78
 
79
  return data;
80
  }
81
 
82
+ const initData = async () => {
83
+ try {
84
+ const allAuthors = Object.values(PROVIDERS_MAP).flatMap(({ authors }) => authors);
85
+ const uniqueAuthors = Array.from(new Set(allAuthors));
86
+
87
+ const allModelData = await Promise.all(
88
+ uniqueAuthors.map(async (author) => {
89
+ const response = await fetch(`https://huggingface.co/api/models?author=${author}&sort=createdAt&direction=-1`);
90
+ const data = await response.json();
91
+ return data.map((item: any) => ({
92
+ createdAt: item.createdAt,
93
+ id: item.id,
94
+ }));
95
+ })
96
+ );
97
+
98
+ const flatModelData = allModelData.flat();
99
+ const calendarData = generateCalendarData(flatModelData);
100
+ setCalendarData(calendarData);
101
+ } catch (error) {
102
+ console.error("Error fetching data:", error);
103
+ } finally {
104
+ setIsLoading(false);
105
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
106
  }
107
 
108
  useEffect(() => {
109
+ initData();
110
  }, []);
111
 
112
+ return (
113
+ <main className={`flex flex-col items-center justify-center min-h-screen mx-auto p-24 ${inter.className}`}>
114
+ <h1 className="text-5xl font-bold text-center">Open Source Heatmap</h1>
115
+ <p className="text-center mt-2 text-sm">A heatmap for open source model releases.</p>
116
+ <div className="mt-16">
117
+ {isLoading ? (
118
+ <p>Loading...</p>
119
+ ) : (
120
+ <>
121
+ {Object.entries(PROVIDERS_MAP)
122
+ .sort(([keyA], [keyB]) =>
123
+ calendarData[keyB].reduce((sum, day) => sum + day.count, 0) -
124
+ calendarData[keyA].reduce((sum, day) => sum + day.count, 0)
125
+ )
126
+ .map(([providerName, { color }]) => (
127
+ <div key={providerName} className="mb-8">
128
+ <h2 className="text-2xl font-bold mb-2">{providerName}</h2>
129
+ <ActivityCalendar
130
+ data={calendarData[providerName]}
131
+ theme={{
132
+ dark: ['#161b22', color],
133
+ }}
134
+ hideTotalCount
135
+ colorScheme="dark"
136
+ renderBlock={(block, activity) => (
137
+ <MuiTooltip
138
+ title={`${activity.count} models created on ${activity.date}`}
139
+ >
140
+ {block}
141
+ </MuiTooltip>
142
+ )}
143
+ />
144
+ </div>
145
+ ))
146
+ }
147
+ </>
148
+ )}
149
  </div>
150
+ </main>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
151
  );
152
  }