Download mobile/test/webllm-test.html from Devseis/Arx: direct link, hf CLI and curl.
- Browser
- Download file 2.66 kB
-
https://huggingface.co/spaces/Devseis/Arx/resolve/main/mobile/test/webllm-test.html
- Command line
-
hf download hf://spaces/Devseis/Arx/mobile/test/webllm-test.html
-
curl -L -o webllm-test.html https://huggingface.co/spaces/Devseis/Arx/resolve/main/mobile/test/webllm-test.html
2.66 kB
| <meta charset="utf-8"><title>WebLLM model test</title> | |
| <script type="module"> | |
| // Loads a Devseis auditor model build in WebLLM and answers prompts given by mobile/test/webllm-test.cjs. | |
| import * as webllm from '../../app/node_modules/@mlc-ai/web-llm/lib/index.js'; | |
| import { SYSTEM_PROMPT, groundingProblems, ANSWER_SCHEMAS } from '../../app/renderer/auditor-core.js'; | |
| import { chatProblems } from '../../app/renderer/knowledge.js'; | |
| window.loadModel = async (modelUrl) => { | |
| const adapter = await navigator.gpu.requestAdapter(); | |
| const f16 = adapter.features.has('shader-f16'); | |
| const named = (modelUrl.match(/q0f16|q4f16_1|q4f32_1/) || [])[0]; | |
| const quant = named || (f16 ? 'q4f16_1' : 'q4f32_1'); | |
| const size = /1\.5b/i.test(modelUrl) ? '1.5B' : '0.5B'; | |
| const base = webllm.prebuiltAppConfig.model_list.find(m => m.model_id === `Qwen2.5-${size}-Instruct-${quant}-MLC`); | |
| const url = modelUrl.replace('{quant}', quant); | |
| const custom = { ...base, model: url, model_id: 'devseis-test-' + quant }; | |
| // ?ctx=N caps the KV cache (context window); the 1.5B default (32768) breaks after the first answer on some GPUs. | |
| const ctx = +new URLSearchParams(location.search).get('ctx') || 0; | |
| window.engine = await webllm.CreateMLCEngine(custom.model_id, { appConfig: { ...webllm.prebuiltAppConfig, model_list: [custom] } }, | |
| ctx ? { context_window_size: ctx } : undefined); | |
| return { quant, url }; | |
| }; | |
| // task 'chat': messages = the full chat messages (system + user); otherwise prompt = report prompt. | |
| window.ask = async (task, prompt, useSchema) => { | |
| if (new URLSearchParams(location.search).get('reset')) await window.engine.resetChat(); | |
| if (task === 'chat') { | |
| const t0 = performance.now(); | |
| const r = await window.engine.chat.completions.create({ messages: prompt, temperature: 0, max_tokens: 700 }); | |
| const reply = r.choices[0].message.content; | |
| return { seconds: Math.round((performance.now() - t0) / 1000), problems: chatProblems(prompt[prompt.length - 1].content, reply), reply }; | |
| } | |
| const t = performance.now(); | |
| const r = await window.engine.chat.completions.create({ messages: [{ role: 'system', content: SYSTEM_PROMPT }, { role: 'user', content: prompt }], | |
| temperature: 0, max_tokens: 900, ...(useSchema ? { response_format: { type: 'json_object', schema: JSON.stringify(ANSWER_SCHEMAS[task]) } } : {}) }); | |
| const reply = r.choices[0].message.content; | |
| let problems; | |
| try { problems = groundingProblems(task, prompt, JSON.parse(reply)); } catch (e) { problems = ['invalid JSON']; } | |
| return { seconds: Math.round((performance.now() - t) / 1000), problems, reply }; | |
| }; | |
| window.ready = true; | |
| </script> | |