webllm
This commit is contained in:
parent
ee66e9fdfa
commit
724bcd8572
8 changed files with 237 additions and 1 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -7,3 +7,4 @@ bribes
|
|||
site/
|
||||
.obsidian
|
||||
.task/
|
||||
webllm/node_modules/
|
||||
|
|
|
|||
|
|
@ -34,9 +34,51 @@ Use a recent Chrome/Edge (≥ 113) or Safari 18+ (chrome://flags/#enable-unsafe-
|
|||
|
||||
## install webllm
|
||||
|
||||
|
||||
[Suivre l'install](https://github.com/mlc-ai/web-llm) dans le readme.
|
||||
|
||||
```
|
||||
sudo apt install -y nodejs npm
|
||||
|
||||
npm install @mlc-ai/web-llm
|
||||
|
||||
python -m"http.server" 8000
|
||||
```
|
||||
|
||||
ou bien, lancer le serveur nodejs :
|
||||
```
|
||||
npm install -g serve
|
||||
serve
|
||||
```
|
||||
|
||||
### usage
|
||||
|
||||
La méthode principale : le System Prompt. Exemple de script:
|
||||
|
||||
```javascript
|
||||
|
||||
import { CreateMLCEngine } from "@mlc-ai/web-llm";
|
||||
|
||||
// 1. Définir la persona (comme votre instruction SYSTEM dans Ollama)
|
||||
const systemPrompt = "Tu es un assistant culinaire expert, spécialisé dans la cuisine française. Tu réponds toujours avec enthousiasme et proposes des alternatives aux ingrédients difficiles à trouver. Tu ne parles jamais de sujets hors de la cuisine.";
|
||||
|
||||
const messages = [
|
||||
// 2. Le message système définit le comportement pour toute la conversation
|
||||
{ role: "system", content: systemPrompt },
|
||||
{ role: "user", content: "Comment faire une bonne quiche lorraine ?" }
|
||||
];
|
||||
|
||||
// 3. Envoyer la requête
|
||||
const engine = await CreateMLCEngine("Llama-3.1-8B-Instruct-q4f32_1-MLC");
|
||||
const reply = await engine.chat.completions.create({ messages });
|
||||
|
||||
console.log(reply.choices[0].message.content);
|
||||
|
||||
```
|
||||
|
||||
- Aller dans le dossier `webllm` et lancer un serveur type `python -m"http.server"`
|
||||
dans ce dossier.
|
||||
- Utiliser un browser compatible (j'ai utilisé un-googled-chromium),
|
||||
le résultat du chat apparaît dans la console.
|
||||
|
||||
## install the python mlc local chat utility
|
||||
|
||||
|
|
|
|||
14
webllm/index.html
Normal file
14
webllm/index.html
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="fr">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Test WebLLM</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Test de WebLLM</h1>
|
||||
<div id="output"></div>
|
||||
|
||||
<!-- Lier votre script JavaScript -->
|
||||
<script type="module" src="./index.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
55
webllm/index.js
Normal file
55
webllm/index.js
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
// import { CreateMLCEngine } from "@mlc-ai/web-llm";
|
||||
|
||||
import { CreateMLCEngine } from "./node_modules/@mlc-ai/web-llm/lib/index.js";
|
||||
|
||||
|
||||
// Callback function to update model loading progress
|
||||
const initProgressCallback = (initProgress) => {
|
||||
console.log(initProgress);
|
||||
};
|
||||
const selectedModel = "Llama-3.1-8B-Instruct-q4f32_1-MLC";
|
||||
|
||||
const engine = await CreateMLCEngine(
|
||||
selectedModel,
|
||||
{ initProgressCallback: initProgressCallback }, // engineConfig
|
||||
);
|
||||
|
||||
// chat
|
||||
|
||||
const messages = [
|
||||
{ role: "system", content: "You are a helpful AI assistant." },
|
||||
{ role: "user", content: "Hello!" },
|
||||
];
|
||||
|
||||
// 1. Définir la persona (comme votre instruction SYSTEM dans Ollama)
|
||||
//const systemPrompt = "Tu es un assistant culinaire expert, spécialisé dans la cuisine française. Tu réponds toujours avec enthousiasme et proposes des alternatives aux ingrédients difficiles à trouver. Tu ne parles jamais de sujets hors de la cuisine.";
|
||||
|
||||
//const messages = [
|
||||
// // 2. Le message système définit le comportement pour toute la conversation
|
||||
// { role: "system", content: systemPrompt },
|
||||
// { role: "user", content: "Comment faire une bonne quiche lorraine ?" }
|
||||
//];
|
||||
|
||||
//import { loadPersona } from './personaLoader.js';
|
||||
|
||||
// ---
|
||||
|
||||
// Chunks is an AsyncGenerator object
|
||||
const chunks = await engine.chat.completions.create({
|
||||
messages,
|
||||
temperature: 0
|
||||
// stream: true, // <-- Enable streaming
|
||||
// stream_options: { include_usage: true },
|
||||
});
|
||||
|
||||
let reply = "";
|
||||
for await (const chunk of chunks) {
|
||||
reply += chunk.choices[0]?.delta.content || "";
|
||||
console.log(reply);
|
||||
if (chunk.usage) {
|
||||
console.log(chunk.usage); // only last chunk has usage
|
||||
}
|
||||
}
|
||||
|
||||
const fullReply = await engine.getMessage();
|
||||
console.log(fullReply);
|
||||
28
webllm/index.js.1
Normal file
28
webllm/index.js.1
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
// import { CreateMLCEngine } from "@mlc-ai/web-llm";
|
||||
|
||||
import { CreateMLCEngine } from "./node_modules/@mlc-ai/web-llm/lib/index.js";
|
||||
|
||||
|
||||
// Callback function to update model loading progress
|
||||
const initProgressCallback = (initProgress) => {
|
||||
console.log(initProgress);
|
||||
};
|
||||
const selectedModel = "Llama-3.1-8B-Instruct-q4f32_1-MLC";
|
||||
|
||||
const engine = await CreateMLCEngine(
|
||||
selectedModel,
|
||||
{ initProgressCallback: initProgressCallback }, // engineConfig
|
||||
);
|
||||
|
||||
// chat
|
||||
|
||||
const messages = [
|
||||
{ role: "system", content: "You are a helpful AI assistant." },
|
||||
{ role: "user", content: "Hello!" },
|
||||
];
|
||||
|
||||
const reply = await engine.chat.completions.create({
|
||||
messages,
|
||||
});
|
||||
console.log(reply.choices[0].message);
|
||||
console.log(reply.usage);
|
||||
5
webllm/package.json
Normal file
5
webllm/package.json
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"dependencies": {
|
||||
"@mlc-ai/web-llm": "^0.2.85"
|
||||
}
|
||||
}
|
||||
75
webllm/persona.txt
Normal file
75
webllm/persona.txt
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
Provided this markdown documentation:
|
||||
|
||||
```markdown
|
||||
| Variable | Description |
|
||||
|------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| **<a id="proxy_mode" name="proxy_mode">proxy_mode</a>**<br/>[`choice`](https://rougail.readthedocs.io/en/latest/variable.html#variables-types) `mandatory` | Configure Proxy Access to the Internet.<br/>**Choices**: <br/>• No proxy **← (default)**<br/>• Auto-detect proxy settings for this network<br/>• Use system proxy settings<br/>• Manual proxy configuration<br/>• Automatic proxy configuration URL |
|
||||
|
||||
# Manual proxy configuration
|
||||
|
||||
> [!NOTE]
|
||||
>
|
||||
> **Path**: manual\
|
||||
> *`disabled`*\
|
||||
> **Disabled**: when the variable "[Configure Proxy Access to the Internet](#proxy_mode)" hasn't the value "Manual proxy configuration".
|
||||
|
||||
## HTTP Proxy
|
||||
|
||||
> [!NOTE]
|
||||
>
|
||||
> **Path**: manual.http_proxy
|
||||
|
||||
| Variable | Description |
|
||||
|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| **<a id="manual.http_proxy.address" name="manual.http_proxy.address">manual.http_proxy.address</a>**<br/>[`domainname`](https://rougail.readthedocs.io/en/latest/variable.html#variables-types) `mandatory` | HTTP proxy address.<br/>**Validators**: <br/>• type domainname<br/>• the domain name can be an IP |
|
||||
| **<a id="manual.http_proxy.port" name="manual.http_proxy.port">manual.http_proxy.port</a>**<br/>[`port`](https://rougail.readthedocs.io/en/latest/variable.html#variables-types) `mandatory` | HTTP proxy port.<br/>**Validators**: <br/>• well-known ports (1 to 1023) are allowed<br/>• registred ports (1024 to 49151) are allowed<br/>• private ports (greater than 49152) are allowed<br/>**Default**: 8080 |
|
||||
|
||||
| Variable | Description |
|
||||
|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------|
|
||||
| **<a id="manual.use_for_https" name="manual.use_for_https">manual.use_for_https</a>**<br/>[`boolean`](https://rougail.readthedocs.io/en/latest/variable.html#variables-types) `mandatory` | Also use this proxy for HTTPS.<br/>**Default**: true |
|
||||
|
||||
## HTTPS Proxy
|
||||
|
||||
> [!NOTE]
|
||||
>
|
||||
> **Path**: manual.https_proxy\
|
||||
> *`hidden`*\
|
||||
> **Hidden**: when the variable "[Also use this proxy for HTTPS](#manual.use_for_https)" has the value "true".
|
||||
|
||||
| Variable | Description |
|
||||
|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| **<a id="manual.https_proxy.address" name="manual.https_proxy.address">manual.https_proxy.address</a>**<br/>[`domainname`](https://rougail.readthedocs.io/en/latest/variable.html#variables-types) `mandatory` | HTTPS proxy address.<br/>**Validators**: <br/>• type domainname<br/>• the domain name can be an IP<br/>**Default**: the value of the variable "[HTTP proxy address](#manual.http_proxy.address)". |
|
||||
| **<a id="manual.https_proxy.port" name="manual.https_proxy.port">manual.https_proxy.port</a>**<br/>[`port`](https://rougail.readthedocs.io/en/latest/variable.html#variables-types) `mandatory` | HTTPS proxy port.<br/>**Validators**: <br/>• well-known ports (1 to 1023) are allowed<br/>• registred ports (1024 to 49151) are allowed<br/>• private ports (greater than 49152) are allowed<br/>**Default**: the value of the variable "[HTTP proxy port](#manual.http_proxy.port)". |
|
||||
|
||||
## SOCKS Proxy
|
||||
|
||||
> [!NOTE]
|
||||
>
|
||||
> **Path**: manual.socks_proxy
|
||||
|
||||
| Variable | Description |
|
||||
|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| **<a id="manual.socks_proxy.address" name="manual.socks_proxy.address">manual.socks_proxy.address</a>**<br/>[`domainname`](https://rougail.readthedocs.io/en/latest/variable.html#variables-types) | SOCKS proxy address.<br/>**Validators**: <br/>• type domainname<br/>• the domain name can be an IP |
|
||||
| **<a id="manual.socks_proxy.port" name="manual.socks_proxy.port">manual.socks_proxy.port</a>**<br/>[`port`](https://rougail.readthedocs.io/en/latest/variable.html#variables-types) `mandatory` *`disabled`* | SOCKS proxy port.<br/>**Validators**: <br/>• well-known ports (1 to 1023) are allowed<br/>• registred ports (1024 to 49151) are allowed<br/>• private ports (greater than 49152) are allowed<br/>**Default**: 1080<br/>**Disabled**: when the variable "[SOCKS proxy address](#manual.socks_proxy.address)" has the value "null". |
|
||||
| **<a id="manual.socks_proxy.version" name="manual.socks_proxy.version">manual.socks_proxy.version</a>**<br/>[`choice`](https://rougail.readthedocs.io/en/latest/variable.html#variables-types) `mandatory` *`disabled`* | SOCKS host version used by proxy.<br/>**Choices**: <br/>• v4<br/>• v5 **← (default)**<br/>**Disabled**: when the variable "[SOCKS proxy address](#manual.socks_proxy.address)" has the value "null". |
|
||||
|
||||
| Variable | Description |
|
||||
|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| **<a id="auto" name="auto">auto</a>**<br/>[`web address`](https://rougail.readthedocs.io/en/latest/variable.html#variables-types) `mandatory` *`disabled`* | Automatic proxy configuration URL.<br/>**Validators**: <br/>• well-known ports (1 to 1023) are allowed<br/>• registred ports (1024 to 49151) are allowed<br/>• type domainname<br/>• the domain name can be a hostname<br/>**Disabled**: when the variable "[Configure Proxy Access to the Internet](#proxy_mode)" hasn't the value "Automatic proxy configuration URL". |
|
||||
| **<a id="no_proxy" name="no_proxy">no_proxy</a>**<br/>[`domainname`](https://rougail.readthedocs.io/en/latest/variable.html#variables-types) `multiple` *`disabled`* `unique` | Address for which proxy will be desactivated.<br/>Connections to localhost, 127.0.0.1/8 and ::1 are never proxied.<br/>**Validators**: <br/>• type domainname<br/>• the domain name can starts by a dot<br/>• the domain name can be a hostname<br/>• the domain name can be an IP<br/>• the domain name can be network in CIDR format<br/>**Examples**: <br/>• .mozilla.org<br/>• .net.nz<br/>• 192.168.1.0/24<br/>**Disabled**: when the variable "[Configure Proxy Access to the Internet](#proxy_mode)" has the value "No proxy". |
|
||||
|
||||
```
|
||||
|
||||
This markdown describes an organised data set.
|
||||
It describes some kind of a storage content with variables names.
|
||||
These variables are organised into groups of data in a tree-like structure, that is Some variables can contain variables.
|
||||
Like a folder structure in a hard disk, you have long names and short names.
|
||||
When the user talks about a variable's name, he means the long name.
|
||||
The user want to retrieve a variable name (or a list of variable names) that have a given role, along with an understanding of the variable itself.
|
||||
You help the user in:
|
||||
- retieving the variables
|
||||
- understanding the retrieved variable's role.
|
||||
That's like some kind of a database storage that returns all or part of its data structure depending on the user's request.
|
||||
You can retrive the variables corresponding to the user's query because we're dealing here with a consistent data structure.
|
||||
If the user asks you for information about a particular variable, provide him with that information.
|
||||
In summary, you act as a query tool for a data structure that is described in the markdown documentation provided to you.
|
||||
16
webllm/personaLoader.js
Normal file
16
webllm/personaLoader.js
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
// personaLoader.js
|
||||
export async function loadPersona(filepath = './persona.txt') {
|
||||
try {
|
||||
const response = await fetch(filepath);
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`Erreur ${response.status}: impossible de charger la persona`);
|
||||
}
|
||||
|
||||
const systemPrompt = await response.text();
|
||||
return systemPrompt.trim();
|
||||
} catch (error) {
|
||||
console.error("Erreur chargement persona:", error.message);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue