Spaces:
Runtime error
Runtime error
Upload 16 files
Browse files- Dockerfile +33 -0
- README.md +38 -10
- package-lock.json +0 -0
- package.json +30 -0
- postcss.config.js +6 -0
- src/app.css +25 -0
- src/app.html +12 -0
- src/lib/index.js +1 -0
- src/lib/server/pipeline.js +31 -0
- src/routes/+layout.svelte +5 -0
- src/routes/+page.svelte +45 -0
- src/routes/classify/+server.js +22 -0
- static/favicon.png +0 -0
- svelte.config.js +16 -0
- tailwind.config.js +8 -0
- vite.config.js +14 -0
Dockerfile
ADDED
@@ -0,0 +1,33 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
FROM node:18 AS base
|
2 |
+
|
3 |
+
RUN apt-get update && \
|
4 |
+
apt-get install -y tini
|
5 |
+
|
6 |
+
ENTRYPOINT ["/usr/bin/tini", "--"]
|
7 |
+
|
8 |
+
# Install dependencies only when needed
|
9 |
+
FROM base AS deps
|
10 |
+
|
11 |
+
WORKDIR /app
|
12 |
+
|
13 |
+
# Install dependencies based on the preferred package manager
|
14 |
+
COPY --link package.json yarn.lock* package-lock.json* pnpm-lock.yaml* ./
|
15 |
+
RUN npm ci
|
16 |
+
|
17 |
+
FROM base AS builder
|
18 |
+
WORKDIR /app
|
19 |
+
COPY --from=deps --link /app/node_modules ./node_modules
|
20 |
+
COPY --link . .
|
21 |
+
|
22 |
+
RUN npm run build
|
23 |
+
# && npm prune --production
|
24 |
+
|
25 |
+
ENV NODE_ENV=production
|
26 |
+
|
27 |
+
EXPOSE 3000
|
28 |
+
# Allow the running process to write model files to the cache folder.
|
29 |
+
# NOTE: In practice, you would probably want to pre-download the model files to avoid having to download them on-the-fly.
|
30 |
+
RUN mkdir -p /app/node_modules/@xenova/.cache/
|
31 |
+
RUN chmod 777 -R /app/node_modules/@xenova/
|
32 |
+
|
33 |
+
CMD ["npm", "run", "preview"]
|
README.md
CHANGED
@@ -1,10 +1,38 @@
|
|
1 |
-
|
2 |
-
|
3 |
-
|
4 |
-
|
5 |
-
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# create-svelte
|
2 |
+
|
3 |
+
Everything you need to build a Svelte project, powered by [`create-svelte`](https://github.com/sveltejs/kit/tree/master/packages/create-svelte).
|
4 |
+
|
5 |
+
## Creating a project
|
6 |
+
|
7 |
+
If you're seeing this, you've probably already done this step. Congrats!
|
8 |
+
|
9 |
+
```bash
|
10 |
+
# create a new project in the current directory
|
11 |
+
npm create svelte@latest
|
12 |
+
|
13 |
+
# create a new project in my-app
|
14 |
+
npm create svelte@latest my-app
|
15 |
+
```
|
16 |
+
|
17 |
+
## Developing
|
18 |
+
|
19 |
+
Once you've created a project and installed dependencies with `npm install` (or `pnpm install` or `yarn`), start a development server:
|
20 |
+
|
21 |
+
```bash
|
22 |
+
npm run dev
|
23 |
+
|
24 |
+
# or start the server and open the app in a new browser tab
|
25 |
+
npm run dev -- --open
|
26 |
+
```
|
27 |
+
|
28 |
+
## Building
|
29 |
+
|
30 |
+
To create a production version of your app:
|
31 |
+
|
32 |
+
```bash
|
33 |
+
npm run build
|
34 |
+
```
|
35 |
+
|
36 |
+
You can preview the production build with `npm run preview`.
|
37 |
+
|
38 |
+
> To deploy your app, you may need to install an [adapter](https://kit.svelte.dev/docs/adapters) for your target environment.
|
package-lock.json
ADDED
The diff for this file is too large to render.
See raw diff
|
|
package.json
ADDED
@@ -0,0 +1,30 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"name": "sveltekit-server",
|
3 |
+
"version": "0.0.1",
|
4 |
+
"private": true,
|
5 |
+
"scripts": {
|
6 |
+
"dev": "vite dev",
|
7 |
+
"build": "vite build",
|
8 |
+
"preview": "vite preview --host 0.0.0.0 --port 3000",
|
9 |
+
"lint": "prettier --plugin-search-dir . --check . && eslint .",
|
10 |
+
"format": "prettier --plugin-search-dir . --write ."
|
11 |
+
},
|
12 |
+
"devDependencies": {
|
13 |
+
"@sveltejs/adapter-node": "^1.3.1",
|
14 |
+
"@sveltejs/kit": "^1.20.4",
|
15 |
+
"@xenova/transformers": "^2.5.2",
|
16 |
+
"autoprefixer": "^10.4.15",
|
17 |
+
"dotenv": "^16.3.1",
|
18 |
+
"eslint": "^8.28.0",
|
19 |
+
"eslint-config-prettier": "^9.0.0",
|
20 |
+
"eslint-plugin-svelte": "^2.30.0",
|
21 |
+
"postcss": "^8.4.28",
|
22 |
+
"prettier": "^3.0.2",
|
23 |
+
"prettier-plugin-svelte": "^3.0.3",
|
24 |
+
"rollup-plugin-ignore": "^1.0.10",
|
25 |
+
"svelte": "^4.0.5",
|
26 |
+
"tailwindcss": "^3.3.3",
|
27 |
+
"vite": "^4.4.2"
|
28 |
+
},
|
29 |
+
"type": "module"
|
30 |
+
}
|
postcss.config.js
ADDED
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
export default {
|
2 |
+
plugins: {
|
3 |
+
tailwindcss: {},
|
4 |
+
autoprefixer: {},
|
5 |
+
},
|
6 |
+
}
|
src/app.css
ADDED
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@100;200;300;400;500;600;700;800;900&family=Xanh+Mono&display=swap');
|
2 |
+
|
3 |
+
@tailwind base;
|
4 |
+
@tailwind components;
|
5 |
+
@tailwind utilities;
|
6 |
+
:root {
|
7 |
+
--foreground-rgb: 0, 0, 0;
|
8 |
+
--background-start-rgb: 214, 219, 220;
|
9 |
+
--background-end-rgb: 255, 255, 255;
|
10 |
+
}
|
11 |
+
|
12 |
+
@media (prefers-color-scheme: dark) {
|
13 |
+
:root {
|
14 |
+
--foreground-rgb: 255, 255, 255;
|
15 |
+
--background-start-rgb: 0, 0, 0;
|
16 |
+
--background-end-rgb: 0, 0, 0;
|
17 |
+
}
|
18 |
+
}
|
19 |
+
|
20 |
+
body {
|
21 |
+
font-family: 'Inter', sans-serif;
|
22 |
+
color: rgb(var(--foreground-rgb));
|
23 |
+
background: linear-gradient(to bottom, transparent, rgb(var(--background-end-rgb)))
|
24 |
+
rgb(var(--background-start-rgb));
|
25 |
+
}
|
src/app.html
ADDED
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<!DOCTYPE html>
|
2 |
+
<html lang="en">
|
3 |
+
<head>
|
4 |
+
<meta charset="utf-8" />
|
5 |
+
<link rel="icon" href="%sveltekit.assets%/favicon.png" />
|
6 |
+
<meta name="viewport" content="width=device-width" />
|
7 |
+
%sveltekit.head%
|
8 |
+
</head>
|
9 |
+
<body data-sveltekit-preload-data="hover">
|
10 |
+
<div style="display: contents">%sveltekit.body%</div>
|
11 |
+
</body>
|
12 |
+
</html>
|
src/lib/index.js
ADDED
@@ -0,0 +1 @@
|
|
|
|
|
1 |
+
// place files you want to import through the `$lib` alias in this folder.
|
src/lib/server/pipeline.js
ADDED
@@ -0,0 +1,31 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import { pipeline } from '@xenova/transformers';
|
2 |
+
|
3 |
+
// Use the Singleton pattern to enable lazy construction of the pipeline.
|
4 |
+
// NOTE: We wrap the class in a function to prevent code duplication (see below).
|
5 |
+
const P = () =>
|
6 |
+
class PipelineSingleton {
|
7 |
+
static task = 'text-classification';
|
8 |
+
static model = 'Xenova/distilbert-base-uncased-finetuned-sst-2-english';
|
9 |
+
static instance = null;
|
10 |
+
|
11 |
+
static async getInstance(progress_callback = null) {
|
12 |
+
if (this.instance === null) {
|
13 |
+
this.instance = pipeline(this.task, this.model, { progress_callback });
|
14 |
+
}
|
15 |
+
return this.instance;
|
16 |
+
}
|
17 |
+
};
|
18 |
+
|
19 |
+
let PipelineSingleton;
|
20 |
+
if (process.env.NODE_ENV !== 'production') {
|
21 |
+
// When running in development mode, attach the pipeline to the
|
22 |
+
// global object so that it's preserved between hot reloads.
|
23 |
+
// For more information, see https://vercel.com/guides/nextjs-prisma-postgres
|
24 |
+
if (!global.PipelineSingleton) {
|
25 |
+
global.PipelineSingleton = P();
|
26 |
+
}
|
27 |
+
PipelineSingleton = global.PipelineSingleton;
|
28 |
+
} else {
|
29 |
+
PipelineSingleton = P();
|
30 |
+
}
|
31 |
+
export default PipelineSingleton;
|
src/routes/+layout.svelte
ADDED
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<script>
|
2 |
+
import '../app.css';
|
3 |
+
</script>
|
4 |
+
|
5 |
+
<slot />
|
src/routes/+page.svelte
ADDED
@@ -0,0 +1,45 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<script>
|
2 |
+
let pipelineWorker;
|
3 |
+
let result = null;
|
4 |
+
let ready = null;
|
5 |
+
|
6 |
+
async function classify(text) {
|
7 |
+
if (!text) return;
|
8 |
+
if (ready === null) {
|
9 |
+
ready = false;
|
10 |
+
}
|
11 |
+
// Make a request to the /classify route on the server.
|
12 |
+
const response = await fetch(`/classify?text=${encodeURIComponent(text)}`);
|
13 |
+
|
14 |
+
// If this is the first time we've made a request, set the ready flag.
|
15 |
+
if (!ready) {
|
16 |
+
ready = true;
|
17 |
+
}
|
18 |
+
result = await response.json();
|
19 |
+
}
|
20 |
+
</script>
|
21 |
+
|
22 |
+
<main class="flex min-h-screen flex-col items-center justify-center p-12">
|
23 |
+
<h1 class="text-5xl font-bold mb-2 text-center">Transformers.js</h1>
|
24 |
+
<h2 class="text-2xl mb-4 text-center">SvelteKit (server-side)</h2>
|
25 |
+
<input
|
26 |
+
type="text"
|
27 |
+
class="w-full max-w-xs p-2 border border-gray-300 rounded mb-4 dark:text-black"
|
28 |
+
placeholder="Enter text here"
|
29 |
+
on:input={(e) => {
|
30 |
+
classify(e.target.value);
|
31 |
+
}}
|
32 |
+
/>
|
33 |
+
|
34 |
+
{#if ready !== null}
|
35 |
+
<pre class="bg-gray-100 dark:bg-gray-800 p-2 rounded">{!ready || !result
|
36 |
+
? 'Loading...'
|
37 |
+
: JSON.stringify(result, null, 2)}</pre>
|
38 |
+
{/if}
|
39 |
+
</main>
|
40 |
+
|
41 |
+
<style lang="postcss">
|
42 |
+
/* :global(html) {
|
43 |
+
background-color: theme(colors.gray.100);
|
44 |
+
} */
|
45 |
+
</style>
|
src/routes/classify/+server.js
ADDED
@@ -0,0 +1,22 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import { json } from '@sveltejs/kit';
|
2 |
+
import PipelineSingleton from '$lib/server/pipeline.js';
|
3 |
+
|
4 |
+
export async function GET({ url }) {
|
5 |
+
const text = url.searchParams.get('text');
|
6 |
+
if (!text) {
|
7 |
+
return json(
|
8 |
+
{
|
9 |
+
error: 'Missing text parameter'
|
10 |
+
},
|
11 |
+
{ status: 400 }
|
12 |
+
);
|
13 |
+
}
|
14 |
+
// Get the classification pipeline. When called for the first time,
|
15 |
+
// this will load the pipeline and cache it for future use.
|
16 |
+
const classifier = await PipelineSingleton.getInstance();
|
17 |
+
|
18 |
+
// Actually perform the classification
|
19 |
+
const result = await classifier(text);
|
20 |
+
|
21 |
+
return json(result);
|
22 |
+
}
|
static/favicon.png
ADDED
svelte.config.js
ADDED
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import adapter from '@sveltejs/adapter-node';
|
2 |
+
import { vitePreprocess } from '@sveltejs/kit/vite';
|
3 |
+
/** @type {import('@sveltejs/kit').Config} */
|
4 |
+
const config = {
|
5 |
+
kit: {
|
6 |
+
adapter: adapter({
|
7 |
+
// default options are shown
|
8 |
+
out: 'build',
|
9 |
+
precompress: false,
|
10 |
+
envPrefix: '',
|
11 |
+
polyfill: true
|
12 |
+
})
|
13 |
+
},
|
14 |
+
preprocess: vitePreprocess()
|
15 |
+
};
|
16 |
+
export default config;
|
tailwind.config.js
ADDED
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/** @type {import('tailwindcss').Config} */
|
2 |
+
export default {
|
3 |
+
content: ['./src/**/*.{html,js,svelte,ts}'],
|
4 |
+
theme: {
|
5 |
+
extend: {}
|
6 |
+
},
|
7 |
+
plugins: []
|
8 |
+
};
|
vite.config.js
ADDED
@@ -0,0 +1,14 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import { sveltekit } from '@sveltejs/kit/vite';
|
2 |
+
import { defineConfig } from 'vite';
|
3 |
+
|
4 |
+
export default defineConfig({
|
5 |
+
plugins: [sveltekit()]
|
6 |
+
// optimizeDeps: {
|
7 |
+
// exclude: ['sharp', 'onnxruntime-node']
|
8 |
+
// },
|
9 |
+
// build: {
|
10 |
+
// rollupOptions: {
|
11 |
+
// external: ['sharp', 'onnxruntime-node']
|
12 |
+
// }
|
13 |
+
// }
|
14 |
+
});
|