Spaces:
Running
on
CPU Upgrade
Running
on
CPU Upgrade
Fix theme and fouc (#58)
Browse files- .env.example +1 -0
- .github/workflows/lint-and-test.yml +20 -8
- .prettierignore +14 -0
- Dockerfile +9 -6
- README.md +6 -4
- package-lock.json +0 -0
- package.json +4 -3
- pnpm-lock.yaml +0 -0
- src/app.html +32 -0
- src/lib/components/InferencePlayground/InferencePlayground.svelte +13 -14
- src/lib/components/InferencePlayground/InferencePlaygroundCodeSnippets.svelte +13 -12
- src/lib/components/InferencePlayground/InferencePlaygroundMessage.svelte +2 -2
- src/lib/components/InferencePlayground/inferencePlaygroundUtils.ts +8 -11
- src/lib/components/InferencePlayground/types.ts +4 -2
- src/routes/+layout.svelte +1 -39
- src/routes/+page.server.ts +2 -1
.env.example
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
HF_TOKEN=
|
.github/workflows/lint-and-test.yml
CHANGED
|
@@ -4,24 +4,36 @@ on:
|
|
| 4 |
push:
|
| 5 |
branches:
|
| 6 |
- main
|
| 7 |
-
|
| 8 |
jobs:
|
| 9 |
lint:
|
| 10 |
runs-on: ubuntu-latest
|
| 11 |
timeout-minutes: 10
|
| 12 |
-
|
| 13 |
steps:
|
| 14 |
- uses: actions/checkout@v3
|
| 15 |
-
|
| 16 |
- uses: actions/setup-node@v3
|
| 17 |
with:
|
| 18 |
node-version: "20"
|
| 19 |
-
|
| 20 |
-
|
| 21 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 22 |
- name: "Checking lint/format errors"
|
| 23 |
run: |
|
| 24 |
-
|
| 25 |
- name: "Checking type errors"
|
| 26 |
run: |
|
| 27 |
-
|
|
|
|
| 4 |
push:
|
| 5 |
branches:
|
| 6 |
- main
|
|
|
|
| 7 |
jobs:
|
| 8 |
lint:
|
| 9 |
runs-on: ubuntu-latest
|
| 10 |
timeout-minutes: 10
|
|
|
|
| 11 |
steps:
|
| 12 |
- uses: actions/checkout@v3
|
|
|
|
| 13 |
- uses: actions/setup-node@v3
|
| 14 |
with:
|
| 15 |
node-version: "20"
|
| 16 |
+
- name: Install pnpm
|
| 17 |
+
uses: pnpm/action-setup@v2
|
| 18 |
+
with:
|
| 19 |
+
version: latest
|
| 20 |
+
run_install: false
|
| 21 |
+
- name: Get pnpm store directory
|
| 22 |
+
id: pnpm-cache
|
| 23 |
+
shell: bash
|
| 24 |
+
run: |
|
| 25 |
+
echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT
|
| 26 |
+
- uses: actions/cache@v3
|
| 27 |
+
with:
|
| 28 |
+
path: ${{ steps.pnpm-cache.outputs.STORE_PATH }}
|
| 29 |
+
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
|
| 30 |
+
restore-keys: |
|
| 31 |
+
${{ runner.os }}-pnpm-store-
|
| 32 |
+
- name: Install dependencies
|
| 33 |
+
run: pnpm install --frozen-lockfile
|
| 34 |
- name: "Checking lint/format errors"
|
| 35 |
run: |
|
| 36 |
+
pnpm run lint
|
| 37 |
- name: "Checking type errors"
|
| 38 |
run: |
|
| 39 |
+
pnpm run check
|
.prettierignore
CHANGED
|
@@ -2,3 +2,17 @@
|
|
| 2 |
package-lock.json
|
| 3 |
pnpm-lock.yaml
|
| 4 |
yarn.lock
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2 |
package-lock.json
|
| 3 |
pnpm-lock.yaml
|
| 4 |
yarn.lock
|
| 5 |
+
.pnpm-store
|
| 6 |
+
|
| 7 |
+
.DS_Store
|
| 8 |
+
node_modules
|
| 9 |
+
/build
|
| 10 |
+
/.svelte-kit
|
| 11 |
+
/package
|
| 12 |
+
.env
|
| 13 |
+
.env.*
|
| 14 |
+
!.env.example
|
| 15 |
+
|
| 16 |
+
# Ignore files for PNPM, NPM and YARN
|
| 17 |
+
pnpm-lock.yaml
|
| 18 |
+
yarn.lock
|
Dockerfile
CHANGED
|
@@ -1,22 +1,25 @@
|
|
| 1 |
FROM node:alpine
|
| 2 |
|
|
|
|
|
|
|
|
|
|
| 3 |
# Set the working directory
|
| 4 |
WORKDIR /app
|
| 5 |
|
| 6 |
-
# Copy package.json and pnpm-lock.yaml
|
| 7 |
-
COPY package.json
|
| 8 |
|
| 9 |
# Install all dependencies, including dev dependencies
|
| 10 |
-
RUN
|
| 11 |
|
| 12 |
# Copy the rest of the application code
|
| 13 |
COPY . .
|
| 14 |
|
| 15 |
# Build the application
|
| 16 |
-
RUN
|
| 17 |
|
| 18 |
# Prune dev dependencies
|
| 19 |
-
RUN
|
| 20 |
|
| 21 |
# Set correct permissions
|
| 22 |
RUN chown -R node:node /app
|
|
@@ -28,4 +31,4 @@ USER node
|
|
| 28 |
EXPOSE 3000
|
| 29 |
|
| 30 |
# Start the application
|
| 31 |
-
CMD ["node", "build"]
|
|
|
|
| 1 |
FROM node:alpine
|
| 2 |
|
| 3 |
+
# Install pnpm
|
| 4 |
+
RUN npm install -g pnpm
|
| 5 |
+
|
| 6 |
# Set the working directory
|
| 7 |
WORKDIR /app
|
| 8 |
|
| 9 |
+
# Copy package.json and pnpm-lock.yaml
|
| 10 |
+
COPY package.json pnpm-lock.yaml* ./
|
| 11 |
|
| 12 |
# Install all dependencies, including dev dependencies
|
| 13 |
+
RUN pnpm install --frozen-lockfile
|
| 14 |
|
| 15 |
# Copy the rest of the application code
|
| 16 |
COPY . .
|
| 17 |
|
| 18 |
# Build the application
|
| 19 |
+
RUN pnpm run build
|
| 20 |
|
| 21 |
# Prune dev dependencies
|
| 22 |
+
RUN pnpm prune --prod
|
| 23 |
|
| 24 |
# Set correct permissions
|
| 25 |
RUN chown -R node:node /app
|
|
|
|
| 31 |
EXPOSE 3000
|
| 32 |
|
| 33 |
# Start the application
|
| 34 |
+
CMD ["node", "build"]
|
README.md
CHANGED
|
@@ -12,11 +12,13 @@ Check out the configuration reference at https://huggingface.co/docs/hub/spaces-
|
|
| 12 |
|
| 13 |
Demo: https://huggingface.co/spaces/huggingface-projects/inference-playground
|
| 14 |
|
| 15 |
-
|
| 16 |
|
| 17 |
-
```
|
| 18 |
-
|
| 19 |
-
HF_TOKEN=your_hf_token
|
| 20 |
```
|
| 21 |
|
| 22 |
get your READ token from http://hf.co/settings/token
|
|
|
|
|
|
|
|
|
| 12 |
|
| 13 |
Demo: https://huggingface.co/spaces/huggingface-projects/inference-playground
|
| 14 |
|
| 15 |
+
## Local development
|
| 16 |
|
| 17 |
+
```sh
|
| 18 |
+
pnpm i
|
| 19 |
+
HF_TOKEN=your_hf_token pnpm run dev
|
| 20 |
```
|
| 21 |
|
| 22 |
get your READ token from http://hf.co/settings/token
|
| 23 |
+
|
| 24 |
+
Hint: Use antfu's [ni](https://github.com/antfu-collective/ni) and never memorize a package manager again
|
package-lock.json
DELETED
|
The diff for this file is too large to render.
See raw diff
|
|
|
package.json
CHANGED
|
@@ -6,6 +6,7 @@
|
|
| 6 |
"dev": "vite dev",
|
| 7 |
"build": "vite build",
|
| 8 |
"preview": "vite preview",
|
|
|
|
| 9 |
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
|
| 10 |
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
|
| 11 |
"lint": "prettier . --check . && eslint --ext .js,.ts,.svelte src/",
|
|
@@ -36,9 +37,9 @@
|
|
| 36 |
},
|
| 37 |
"type": "module",
|
| 38 |
"dependencies": {
|
| 39 |
-
"@huggingface/hub": "^0.
|
| 40 |
-
"@huggingface/inference": "^
|
| 41 |
-
"@huggingface/tasks": "^0.
|
| 42 |
"@tailwindcss/container-queries": "^0.1.1"
|
| 43 |
}
|
| 44 |
}
|
|
|
|
| 6 |
"dev": "vite dev",
|
| 7 |
"build": "vite build",
|
| 8 |
"preview": "vite preview",
|
| 9 |
+
"prepare": "svelte-kit sync || echo ''",
|
| 10 |
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
|
| 11 |
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
|
| 12 |
"lint": "prettier . --check . && eslint --ext .js,.ts,.svelte src/",
|
|
|
|
| 37 |
},
|
| 38 |
"type": "module",
|
| 39 |
"dependencies": {
|
| 40 |
+
"@huggingface/hub": "^1.0.1",
|
| 41 |
+
"@huggingface/inference": "^3.5.1",
|
| 42 |
+
"@huggingface/tasks": "^0.17.1",
|
| 43 |
"@tailwindcss/container-queries": "^0.1.1"
|
| 44 |
}
|
| 45 |
}
|
pnpm-lock.yaml
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
src/app.html
CHANGED
|
@@ -6,7 +6,39 @@
|
|
| 6 |
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
| 7 |
%sveltekit.head%
|
| 8 |
</head>
|
|
|
|
| 9 |
<body data-sveltekit-preload-data="hover" class="dark:bg-gray-900">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 10 |
<div style="display: contents">%sveltekit.body%</div>
|
| 11 |
</body>
|
| 12 |
</html>
|
|
|
|
| 6 |
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
| 7 |
%sveltekit.head%
|
| 8 |
</head>
|
| 9 |
+
|
| 10 |
<body data-sveltekit-preload-data="hover" class="dark:bg-gray-900">
|
| 11 |
+
<script>
|
| 12 |
+
(function () {
|
| 13 |
+
const urlParams = new URLSearchParams(window.location.search);
|
| 14 |
+
const theme = urlParams.get("__theme");
|
| 15 |
+
|
| 16 |
+
let systemPrefersDark = window.matchMedia("(prefers-color-scheme: dark)").matches;
|
| 17 |
+
|
| 18 |
+
function updateTheme() {
|
| 19 |
+
if (theme === "dark") {
|
| 20 |
+
document.body.classList.add("dark");
|
| 21 |
+
} else if (theme === "light") {
|
| 22 |
+
document.body.classList.remove("dark");
|
| 23 |
+
} else if (theme === "system" || theme === null || theme === undefined) {
|
| 24 |
+
if (systemPrefersDark) {
|
| 25 |
+
document.body.classList.add("dark");
|
| 26 |
+
} else {
|
| 27 |
+
document.body.classList.remove("dark");
|
| 28 |
+
}
|
| 29 |
+
}
|
| 30 |
+
}
|
| 31 |
+
|
| 32 |
+
// Initial theme update
|
| 33 |
+
updateTheme();
|
| 34 |
+
|
| 35 |
+
// Listen for system preference changes
|
| 36 |
+
window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change", event => {
|
| 37 |
+
systemPrefersDark = event.matches;
|
| 38 |
+
updateTheme();
|
| 39 |
+
});
|
| 40 |
+
})();
|
| 41 |
+
</script>
|
| 42 |
<div style="display: contents">%sveltekit.body%</div>
|
| 43 |
</body>
|
| 44 |
</html>
|
src/lib/components/InferencePlayground/InferencePlayground.svelte
CHANGED
|
@@ -1,37 +1,36 @@
|
|
| 1 |
<script lang="ts">
|
| 2 |
-
import type { Conversation, ModelEntryWithTokenizer, Session } from "./types";
|
| 3 |
-
import type { ChatCompletionInputMessage } from "@huggingface/tasks";
|
| 4 |
|
| 5 |
import { page } from "$app/stores";
|
| 6 |
import { defaultGenerationConfig } from "./generationConfigSettings";
|
| 7 |
import {
|
| 8 |
createHfInference,
|
| 9 |
-
|
| 10 |
handleNonStreamingResponse,
|
|
|
|
| 11 |
isSystemPromptSupported,
|
| 12 |
-
FEATURED_MODELS_IDS,
|
| 13 |
} from "./inferencePlaygroundUtils";
|
| 14 |
|
|
|
|
| 15 |
import { onDestroy, onMount } from "svelte";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 16 |
import GenerationConfig, { defaultSystemMessage } from "./InferencePlaygroundGenerationConfig.svelte";
|
| 17 |
import HFTokenModal from "./InferencePlaygroundHFTokenModal.svelte";
|
| 18 |
import ModelSelector from "./InferencePlaygroundModelSelector.svelte";
|
| 19 |
-
import PlaygroundConversation from "./InferencePlaygroundConversation.svelte";
|
| 20 |
-
import PlaygroundConversationHeader from "./InferencePlaygroundConversationHeader.svelte";
|
| 21 |
-
import IconDelete from "../Icons/IconDelete.svelte";
|
| 22 |
-
import IconCode from "../Icons/IconCode.svelte";
|
| 23 |
-
import IconInfo from "../Icons/IconInfo.svelte";
|
| 24 |
-
import IconCompare from "../Icons/IconCompare.svelte";
|
| 25 |
import ModelSelectorModal from "./InferencePlaygroundModelSelectorModal.svelte";
|
| 26 |
-
import IconThrashcan from "../Icons/IconThrashcan.svelte";
|
| 27 |
-
import { goto } from "$app/navigation";
|
| 28 |
|
| 29 |
export let models: ModelEntryWithTokenizer[];
|
| 30 |
|
| 31 |
-
const startMessageUser:
|
| 32 |
const modelIdsFromQueryParam = $page.url.searchParams.get("modelId")?.split(",");
|
| 33 |
const modelsFromQueryParam = modelIdsFromQueryParam?.map(id => models.find(model => model.id === id));
|
| 34 |
-
const systemMessage:
|
| 35 |
role: "system",
|
| 36 |
content: modelIdsFromQueryParam ? (defaultSystemMessage?.[modelIdsFromQueryParam[0]] ?? "") : "",
|
| 37 |
};
|
|
|
|
| 1 |
<script lang="ts">
|
| 2 |
+
import type { Conversation, ConversationMessage, ModelEntryWithTokenizer, Session } from "./types";
|
|
|
|
| 3 |
|
| 4 |
import { page } from "$app/stores";
|
| 5 |
import { defaultGenerationConfig } from "./generationConfigSettings";
|
| 6 |
import {
|
| 7 |
createHfInference,
|
| 8 |
+
FEATURED_MODELS_IDS,
|
| 9 |
handleNonStreamingResponse,
|
| 10 |
+
handleStreamingResponse,
|
| 11 |
isSystemPromptSupported,
|
|
|
|
| 12 |
} from "./inferencePlaygroundUtils";
|
| 13 |
|
| 14 |
+
import { goto } from "$app/navigation";
|
| 15 |
import { onDestroy, onMount } from "svelte";
|
| 16 |
+
import IconCode from "../Icons/IconCode.svelte";
|
| 17 |
+
import IconCompare from "../Icons/IconCompare.svelte";
|
| 18 |
+
import IconDelete from "../Icons/IconDelete.svelte";
|
| 19 |
+
import IconInfo from "../Icons/IconInfo.svelte";
|
| 20 |
+
import IconThrashcan from "../Icons/IconThrashcan.svelte";
|
| 21 |
+
import PlaygroundConversation from "./InferencePlaygroundConversation.svelte";
|
| 22 |
+
import PlaygroundConversationHeader from "./InferencePlaygroundConversationHeader.svelte";
|
| 23 |
import GenerationConfig, { defaultSystemMessage } from "./InferencePlaygroundGenerationConfig.svelte";
|
| 24 |
import HFTokenModal from "./InferencePlaygroundHFTokenModal.svelte";
|
| 25 |
import ModelSelector from "./InferencePlaygroundModelSelector.svelte";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 26 |
import ModelSelectorModal from "./InferencePlaygroundModelSelectorModal.svelte";
|
|
|
|
|
|
|
| 27 |
|
| 28 |
export let models: ModelEntryWithTokenizer[];
|
| 29 |
|
| 30 |
+
const startMessageUser: ConversationMessage = { role: "user", content: "" };
|
| 31 |
const modelIdsFromQueryParam = $page.url.searchParams.get("modelId")?.split(",");
|
| 32 |
const modelsFromQueryParam = modelIdsFromQueryParam?.map(id => models.find(model => model.id === id));
|
| 33 |
+
const systemMessage: ConversationMessage = {
|
| 34 |
role: "system",
|
| 35 |
content: modelIdsFromQueryParam ? (defaultSystemMessage?.[modelIdsFromQueryParam[0]] ?? "") : "",
|
| 36 |
};
|
src/lib/components/InferencePlayground/InferencePlaygroundCodeSnippets.svelte
CHANGED
|
@@ -85,12 +85,13 @@
|
|
| 85 |
messages.unshift(systemMessage);
|
| 86 |
}
|
| 87 |
|
| 88 |
-
|
| 89 |
role,
|
| 90 |
content: JSON.stringify(content).slice(1, -1),
|
| 91 |
}));
|
|
|
|
| 92 |
|
| 93 |
-
return
|
| 94 |
}
|
| 95 |
|
| 96 |
function highlight(code: string, language: Language) {
|
|
@@ -139,7 +140,7 @@ for await (const chunk of stream) {
|
|
| 139 |
const newContent = chunk.choices[0].delta.content;
|
| 140 |
out += newContent;
|
| 141 |
console.log(newContent);
|
| 142 |
-
}
|
| 143 |
}`,
|
| 144 |
});
|
| 145 |
} else {
|
|
@@ -210,7 +211,7 @@ for await (const chunk of stream) {
|
|
| 210 |
const newContent = chunk.choices[0].delta.content;
|
| 211 |
out += newContent;
|
| 212 |
console.log(newContent);
|
| 213 |
-
}
|
| 214 |
}`,
|
| 215 |
});
|
| 216 |
} else {
|
|
@@ -270,8 +271,8 @@ client = InferenceClient(api_key="${tokenStr}")
|
|
| 270 |
messages = ${formattedMessages({ sep: ",\n\t", start: `[\n\t`, end: `\n]` })}
|
| 271 |
|
| 272 |
stream = client.chat.completions.create(
|
| 273 |
-
model="${conversation.model.id}",
|
| 274 |
-
messages=messages,
|
| 275 |
${formattedConfig({ sep: ",\n\t", start: "", end: "", connector: "=" })},
|
| 276 |
stream=True
|
| 277 |
)
|
|
@@ -291,8 +292,8 @@ client = InferenceClient(api_key="${tokenStr}")
|
|
| 291 |
messages = ${formattedMessages({ sep: ",\n\t", start: `[\n\t`, end: `\n]` })}
|
| 292 |
|
| 293 |
completion = client.chat.completions.create(
|
| 294 |
-
model="${conversation.model.id}",
|
| 295 |
-
messages=messages,
|
| 296 |
${formattedConfig({ sep: ",\n\t", start: "", end: "", connector: "=" })}
|
| 297 |
)
|
| 298 |
|
|
@@ -338,8 +339,8 @@ client = OpenAI(
|
|
| 338 |
messages = ${formattedMessages({ sep: ",\n\t", start: `[\n\t`, end: `\n]` })}
|
| 339 |
|
| 340 |
stream = client.chat.completions.create(
|
| 341 |
-
model="${conversation.model.id}",
|
| 342 |
-
messages=messages,
|
| 343 |
${formattedConfig({ sep: ",\n\t", start: "", end: "", connector: "=" })},
|
| 344 |
stream=True
|
| 345 |
)
|
|
@@ -362,8 +363,8 @@ client = OpenAI(
|
|
| 362 |
messages = ${formattedMessages({ sep: ",\n\t", start: `[\n\t`, end: `\n]` })}
|
| 363 |
|
| 364 |
completion = client.chat.completions.create(
|
| 365 |
-
model="${conversation.model.id}",
|
| 366 |
-
messages=messages,
|
| 367 |
${formattedConfig({ sep: ",\n\t", start: "", end: "", connector: "=" })}
|
| 368 |
)
|
| 369 |
|
|
|
|
| 85 |
messages.unshift(systemMessage);
|
| 86 |
}
|
| 87 |
|
| 88 |
+
const res = messages.map(({ role, content }) => ({
|
| 89 |
role,
|
| 90 |
content: JSON.stringify(content).slice(1, -1),
|
| 91 |
}));
|
| 92 |
+
messages = res;
|
| 93 |
|
| 94 |
+
return res;
|
| 95 |
}
|
| 96 |
|
| 97 |
function highlight(code: string, language: Language) {
|
|
|
|
| 140 |
const newContent = chunk.choices[0].delta.content;
|
| 141 |
out += newContent;
|
| 142 |
console.log(newContent);
|
| 143 |
+
}
|
| 144 |
}`,
|
| 145 |
});
|
| 146 |
} else {
|
|
|
|
| 211 |
const newContent = chunk.choices[0].delta.content;
|
| 212 |
out += newContent;
|
| 213 |
console.log(newContent);
|
| 214 |
+
}
|
| 215 |
}`,
|
| 216 |
});
|
| 217 |
} else {
|
|
|
|
| 271 |
messages = ${formattedMessages({ sep: ",\n\t", start: `[\n\t`, end: `\n]` })}
|
| 272 |
|
| 273 |
stream = client.chat.completions.create(
|
| 274 |
+
model="${conversation.model.id}",
|
| 275 |
+
messages=messages,
|
| 276 |
${formattedConfig({ sep: ",\n\t", start: "", end: "", connector: "=" })},
|
| 277 |
stream=True
|
| 278 |
)
|
|
|
|
| 292 |
messages = ${formattedMessages({ sep: ",\n\t", start: `[\n\t`, end: `\n]` })}
|
| 293 |
|
| 294 |
completion = client.chat.completions.create(
|
| 295 |
+
model="${conversation.model.id}",
|
| 296 |
+
messages=messages,
|
| 297 |
${formattedConfig({ sep: ",\n\t", start: "", end: "", connector: "=" })}
|
| 298 |
)
|
| 299 |
|
|
|
|
| 339 |
messages = ${formattedMessages({ sep: ",\n\t", start: `[\n\t`, end: `\n]` })}
|
| 340 |
|
| 341 |
stream = client.chat.completions.create(
|
| 342 |
+
model="${conversation.model.id}",
|
| 343 |
+
messages=messages,
|
| 344 |
${formattedConfig({ sep: ",\n\t", start: "", end: "", connector: "=" })},
|
| 345 |
stream=True
|
| 346 |
)
|
|
|
|
| 363 |
messages = ${formattedMessages({ sep: ",\n\t", start: `[\n\t`, end: `\n]` })}
|
| 364 |
|
| 365 |
completion = client.chat.completions.create(
|
| 366 |
+
model="${conversation.model.id}",
|
| 367 |
+
messages=messages,
|
| 368 |
${formattedConfig({ sep: ",\n\t", start: "", end: "", connector: "=" })}
|
| 369 |
)
|
| 370 |
|
src/lib/components/InferencePlayground/InferencePlaygroundMessage.svelte
CHANGED
|
@@ -1,8 +1,8 @@
|
|
| 1 |
<script lang="ts">
|
| 2 |
-
import { type ChatCompletionInputMessage } from "@huggingface/tasks";
|
| 3 |
import { createEventDispatcher } from "svelte";
|
|
|
|
| 4 |
|
| 5 |
-
export let message:
|
| 6 |
export let loading: boolean = false;
|
| 7 |
export let autofocus: boolean = false;
|
| 8 |
|
|
|
|
| 1 |
<script lang="ts">
|
|
|
|
| 2 |
import { createEventDispatcher } from "svelte";
|
| 3 |
+
import type { ConversationMessage } from "./types";
|
| 4 |
|
| 5 |
+
export let message: ConversationMessage;
|
| 6 |
export let loading: boolean = false;
|
| 7 |
export let autofocus: boolean = false;
|
| 8 |
|
src/lib/components/InferencePlayground/inferencePlaygroundUtils.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
| 1 |
-
import { type
|
| 2 |
import type { Conversation, ModelEntryWithTokenizer } from "./types";
|
| 3 |
|
| 4 |
import { HfInference } from "@huggingface/inference";
|
|
@@ -25,7 +25,7 @@ export async function handleStreamingResponse(
|
|
| 25 |
messages,
|
| 26 |
...conversation.config,
|
| 27 |
},
|
| 28 |
-
{ signal: abortController.signal
|
| 29 |
)) {
|
| 30 |
if (chunk.choices && chunk.choices.length > 0 && chunk.choices[0]?.delta?.content) {
|
| 31 |
out += chunk.choices[0].delta.content;
|
|
@@ -37,21 +37,18 @@ export async function handleStreamingResponse(
|
|
| 37 |
export async function handleNonStreamingResponse(
|
| 38 |
hf: HfInference,
|
| 39 |
conversation: Conversation
|
| 40 |
-
): Promise<{ message:
|
| 41 |
const { model, systemMessage } = conversation;
|
| 42 |
const messages = [
|
| 43 |
...(isSystemPromptSupported(model) && systemMessage.content?.length ? [systemMessage] : []),
|
| 44 |
...conversation.messages,
|
| 45 |
];
|
| 46 |
|
| 47 |
-
const response = await hf.chatCompletion(
|
| 48 |
-
|
| 49 |
-
|
| 50 |
-
|
| 51 |
-
|
| 52 |
-
},
|
| 53 |
-
{ use_cache: false }
|
| 54 |
-
);
|
| 55 |
|
| 56 |
if (response.choices && response.choices.length > 0) {
|
| 57 |
const { message } = response.choices[0];
|
|
|
|
| 1 |
+
import { type ChatCompletionOutputMessage } from "@huggingface/tasks";
|
| 2 |
import type { Conversation, ModelEntryWithTokenizer } from "./types";
|
| 3 |
|
| 4 |
import { HfInference } from "@huggingface/inference";
|
|
|
|
| 25 |
messages,
|
| 26 |
...conversation.config,
|
| 27 |
},
|
| 28 |
+
{ signal: abortController.signal }
|
| 29 |
)) {
|
| 30 |
if (chunk.choices && chunk.choices.length > 0 && chunk.choices[0]?.delta?.content) {
|
| 31 |
out += chunk.choices[0].delta.content;
|
|
|
|
| 37 |
export async function handleNonStreamingResponse(
|
| 38 |
hf: HfInference,
|
| 39 |
conversation: Conversation
|
| 40 |
+
): Promise<{ message: ChatCompletionOutputMessage; completion_tokens: number }> {
|
| 41 |
const { model, systemMessage } = conversation;
|
| 42 |
const messages = [
|
| 43 |
...(isSystemPromptSupported(model) && systemMessage.content?.length ? [systemMessage] : []),
|
| 44 |
...conversation.messages,
|
| 45 |
];
|
| 46 |
|
| 47 |
+
const response = await hf.chatCompletion({
|
| 48 |
+
model: model.id,
|
| 49 |
+
messages,
|
| 50 |
+
...conversation.config,
|
| 51 |
+
});
|
|
|
|
|
|
|
|
|
|
| 52 |
|
| 53 |
if (response.choices && response.choices.length > 0) {
|
| 54 |
const { message } = response.choices[0];
|
src/lib/components/InferencePlayground/types.ts
CHANGED
|
@@ -2,11 +2,13 @@ import type { GenerationConfig } from "$lib/components/InferencePlayground/gener
|
|
| 2 |
import type { ModelEntry } from "@huggingface/hub";
|
| 3 |
import type { ChatCompletionInputMessage } from "@huggingface/tasks";
|
| 4 |
|
|
|
|
|
|
|
| 5 |
export type Conversation = {
|
| 6 |
model: ModelEntryWithTokenizer;
|
| 7 |
config: GenerationConfig;
|
| 8 |
-
messages:
|
| 9 |
-
systemMessage:
|
| 10 |
streaming: boolean;
|
| 11 |
};
|
| 12 |
|
|
|
|
| 2 |
import type { ModelEntry } from "@huggingface/hub";
|
| 3 |
import type { ChatCompletionInputMessage } from "@huggingface/tasks";
|
| 4 |
|
| 5 |
+
export type ConversationMessage = Omit<ChatCompletionInputMessage, "content"> & { content?: string };
|
| 6 |
+
|
| 7 |
export type Conversation = {
|
| 8 |
model: ModelEntryWithTokenizer;
|
| 9 |
config: GenerationConfig;
|
| 10 |
+
messages: ConversationMessage[];
|
| 11 |
+
systemMessage: ConversationMessage;
|
| 12 |
streaming: boolean;
|
| 13 |
};
|
| 14 |
|
src/routes/+layout.svelte
CHANGED
|
@@ -1,43 +1,5 @@
|
|
| 1 |
<script lang="ts">
|
| 2 |
import "../app.css";
|
| 3 |
-
import { onMount } from "svelte";
|
| 4 |
-
import { browser } from "$app/environment";
|
| 5 |
-
import { page } from "$app/stores";
|
| 6 |
-
|
| 7 |
-
type Theme = "light" | "dark" | "system" | null | undefined;
|
| 8 |
-
|
| 9 |
-
let systemPrefersDark = false;
|
| 10 |
-
|
| 11 |
-
function updateTheme(theme: Theme, systemPrefersDark: boolean) {
|
| 12 |
-
if (theme === "dark" || (theme === "system" && systemPrefersDark)) {
|
| 13 |
-
document.documentElement.classList.add("dark");
|
| 14 |
-
} else {
|
| 15 |
-
document.documentElement.classList.remove("dark");
|
| 16 |
-
}
|
| 17 |
-
}
|
| 18 |
-
|
| 19 |
-
$: if (browser) {
|
| 20 |
-
const theme = $page.url.searchParams.get("__theme") as Theme;
|
| 21 |
-
updateTheme(theme, systemPrefersDark);
|
| 22 |
-
}
|
| 23 |
-
|
| 24 |
-
onMount(() => {
|
| 25 |
-
if (browser) {
|
| 26 |
-
const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
|
| 27 |
-
systemPrefersDark = mediaQuery.matches;
|
| 28 |
-
|
| 29 |
-
const handleChange = (event: MediaQueryListEvent) => {
|
| 30 |
-
systemPrefersDark = event.matches;
|
| 31 |
-
updateTheme($page.url.searchParams.get("__theme") as Theme, systemPrefersDark);
|
| 32 |
-
};
|
| 33 |
-
|
| 34 |
-
mediaQuery.addEventListener("change", handleChange);
|
| 35 |
-
|
| 36 |
-
return () => mediaQuery.removeEventListener("change", handleChange);
|
| 37 |
-
}
|
| 38 |
-
});
|
| 39 |
</script>
|
| 40 |
|
| 41 |
-
<slot
|
| 42 |
-
|
| 43 |
-
<style></style>
|
|
|
|
| 1 |
<script lang="ts">
|
| 2 |
import "../app.css";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3 |
</script>
|
| 4 |
|
| 5 |
+
<slot />
|
|
|
|
|
|
src/routes/+page.server.ts
CHANGED
|
@@ -4,7 +4,8 @@ import type { PageServerLoad } from "./$types";
|
|
| 4 |
import { env } from "$env/dynamic/private";
|
| 5 |
|
| 6 |
export const load: PageServerLoad = async ({ fetch }) => {
|
| 7 |
-
const apiUrl =
|
|
|
|
| 8 |
const HF_TOKEN = env.HF_TOKEN;
|
| 9 |
|
| 10 |
const res = await fetch(apiUrl, {
|
|
|
|
| 4 |
import { env } from "$env/dynamic/private";
|
| 5 |
|
| 6 |
export const load: PageServerLoad = async ({ fetch }) => {
|
| 7 |
+
const apiUrl =
|
| 8 |
+
"https://huggingface.co/api/models?pipeline_tag=text-generation&inference_provider=hf-inference&filter=conversational";
|
| 9 |
const HF_TOKEN = env.HF_TOKEN;
|
| 10 |
|
| 11 |
const res = await fetch(apiUrl, {
|