ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

WebLLM 文本补全(Text Completion)示例实战:基于 OpenAI Completion API 的浏览器端无模板文本生成

WebLLM 文本补全(Text Completion)示例实战:基于 OpenAI Completion API 的浏览器端无模板文本生成 WebLLM 文本补全Text Completion示例实战基于 OpenAI Completion API 的浏览器端无模板文本生成【免费下载链接】web-llmHigh-performance In-browser LLM Inference Engine项目地址: https://gitcode.com/GitHub_Trending/we/web-llm导读examples/text-completion是 WebLLMHigh-performance In-browser LLM Inference Engine仓库中一个刻意保持最小化的示例目录它以最少的代码量演示了如何在普通 Web 页面中加载一个纯基座模型Base Model并通过 OpenAI 风格的engine.completions.create()接口完成不经过任何聊天模板的原始文本补全。读完本文你将掌握如何搭建并运行该示例、如何理解AppConfig模型清单与overrides配置、CompletionCreateParams每个核心参数的真实含义与取值范围以及如何将mlc-ai/web-llm依赖替换为本地源码包file:../..来调试 WebLLM 核心逻辑。示例定位一个最小化的 WebLLM API 演示该目录的 README.md 开门见山地说明其定位This folder provides a minimum demo to show WebLLM API in a webapp setting.—— 它不是一个功能完备的聊天应用而是为了展示 WebLLM 核心 API 在 Web 应用环境下的最小可用形态重点突出 WebLLM 对 OpenAICompletions文本补全协议的兼容实现。整个示例仅包含三个源文件文件作用text_completion.html页面骨架展示初始化进度标签、提示词与响应占位并加载 TypeScript 入口text_completion.ts核心逻辑加载模型并调用completions.create()发起补全请求package.json依赖声明与 Parcel 启动/构建脚本值得注意的细节示例依赖声明为mlc-ai/web-llm: ^0.2.84并通过 Parcel 提供本地开发服务器start脚本固定使用--port 8888见 package.json。mlc-ai/web-llm的 npm 版本与仓库内modelVersion当前为v0_2_84/base定义于 src/config.ts共同决定了预构建模型库wasm的兼容范围。三步启动示例在 examples/text-completion 目录下依次执行npm install npm startnpm install安装示例自身的依赖包括mlc-ai/web-llm与parcel等开发依赖npm start等价于parcel src/text_completion.html --port 8888启动本地开发服务器浏览器打开 Parcel 提示的地址默认http://localhost:8888页面会显示初始化进度完整补全结果则输出在浏览器 DevTools 控制台中——这也是 text_completion.html 中Open console to see output的含义。由于推理在浏览器内完成运行环境需满足 WebLLM 对 WebGPU 的支持要求建议使用最新版 Chrome/Edge 等启用 WebGPU 的浏览器。核心代码逐段拆解1. 初始化进度回调const initProgressCallback (report: webllm.InitProgressReport) { setLabel(init-label, report.text); };InitProgressReport携带模型下载与编译过程中的进度文本示例将其写入页面上init-label标签对应 text_completion.html让用户直观看到下载权重 → 编译 WebGPU 着色器 → 加载 KV Cache等阶段。2. 选择基座模型而非 Instruct 模型// Unlike Llama-3.1-8B-Instruct-q4f32_1-MLC, this is a base model const selectedModel Llama-3.1-8B-Instruct-q4f32_1-MLC.replace(...); // 实际代码中直接使用 Llama-3.1-8B-q4f32_1-MLC源码注释明确提醒与聊天场景常用的Llama-3.1-8B-Instruct-q4f32_1-MLC不同这里选择的是纯基座模型Llama-3.1-8B-q4f32_1-MLC。文本补全不做对话模板包装因此使用基座模型更符合给定前缀、续写文本的原始语义具体声明见 text_completion.ts。3. 通过 AppConfig 自定义模型清单const appConfig: webllm.AppConfig { model_list: [ { model: https://huggingface.co/mlc-ai/Llama-3.1-8B-q4f32_1-MLC, // a base model model_id: selectedModel, model_lib: webllm.modelLibURLPrefix webllm.modelVersion /Llama-3_1-8B-Instruct-q4f32_1-ctx4k_cs1k-webgpu.wasm, overrides: { context_window_size: 2048, }, }, ], };对照 src/config.ts 中的ModelRecord接口可逐一对应每个字段的作用modelHugging Face 上的权重仓库链接WebLLM 据此下载模型参数model_id模型在本应用中的唯一标识后续CreateMLCEngine、engine.reload()均使用该 IDmodel_lib该模型对应的预编译 WebGPU 模型库.wasm 文件地址由modelLibURLPrefix modelVersion 文件名拼接而成。注意此处 wasm 复用 Instruct 变体的编译产物后缀-ctx4k_cs1k但权重来自基座模型仓库overrides对模型自带mlc-chat-config.json的局部覆盖示例将context_window_size下调为 2048用于控制 KV Cache 占用显存的规模详见 src/config.ts 对overrides的注释。AppConfig还支持cacheBackendcache | indexeddb | cross-origin | opfs等字段用于指定权重与工件的浏览器缓存后端缺省时使用 Cache API见 src/config.ts。4. 创建引擎const engine: webllm.MLCEngineInterface await webllm.CreateMLCEngine( selectedModel, { appConfig: appConfig, initProgressCallback: initProgressCallback, logLevel: INFO, }, );CreateMLCEngine(modelId, config)的第二个参数即MLCEngineConfigsrc/config.ts字段均为可选appConfig提供模型清单initProgressCallback上报加载进度logLevel控制日志输出级别默认WARN示例显式设为INFO便于观察加载细节。5. 发起文本补全请求const reply0 await engine.completions.create({ prompt: List 3 US states: , // below configurations are all optional echo: true, n: 2, max_tokens: 64, logprobs: true, top_logprobs: 2, }); console.log(reply0); console.log(reply0.usage);这是示例的主角engine.completions.create()即 OpenAICompletionsAPI 的浏览器端实现入口类Completions定义于 src/openai_api_protocols/completion.ts其create()直接委托给引擎的engine.completion(request)。注释明确说明其余参数均为可选示例启用的四个参数含义如下参数示例值作用echotrue在返回文本前回显原始 promptn2对同一 prompt 生成 2 个独立补全候选choicemax_tokens64生成 token 数上限logprobstrue返回每个输出 token 的对数概率top_logprobs2每个 token 位置返回概率最高的前 2 个候选 token 的对数概率源码注释text_completion.ts还提示了换模型的两条路径重新调用CreateMLCEngine()或调用engine.reload(modelId)。从源码看 Completion API 的完整参数面示例只用了上述参数而 completion.ts 中CompletionCreateParamsBase完整定义了该接口的全部可用字段按类别展开如下采样控制temperature02越高越随机、top_p核采样与 temperature 建议二选一、repetition_penalty0抑制 token 重复、frequency_penalty与presence_penalty-2.02.0输出控制max_tokens、stop最多 4 个停止序列字符串或数组、ignore_eos为 true 时忽略 EOS直到max_tokens耗尽、suffix当前不支持多样性/确定性n每 prompt 的候选数、seed整数使相同参数下的请求尽量确定性地复现、echo、logprobs、top_logprobs05需先开启logprobs高级操纵logit_bias以 token ID 为键、-100100 为值的映射直接加在采样前的 logits 上-100 近似禁用该 token流式stream为 true 时返回AsyncIterableCompletion且会以空 chunk 终止、stream_options仅流式时可用模型选择model可选——若引擎只加载了一个模型可省略多模型时必须显式指定且取值需在prebuiltAppConfig或appConfig.model_list的model_id中见 completion.ts不支持的字段suffix、user、best_of会触发UnsupportedFieldsError见 completion.ts。请求参数的后置校验postInitAndCheckFields()completion.ts在引擎处理前对请求做四类校验出现suffix/user/best_of任一字段即抛UnsupportedFieldsError流式模式下n 1抛StreamingCountError引擎无法同时管理多条序列的流seed必须为整数否则抛SeedTypeError仅在stream: true时允许设置stream_options。这些规则都有对应测试用例佐证见 tests/openai_completion.test.ts例如非整数 seed 抛错、流式且 n2 抛错等。引擎内部的执行链路MLCEngineInterface.completion()的实际实现在 src/engine.ts 及其后约 80 行代码中其执行流程为预处理通过getLLMStates()解析请求所属模型request.model或当前已加载模型调用API.postInitAndCheckFieldsCompletion()完成上文所述的字段校验并将请求字段映射为GenerationConfigfrequency_penalty、max_tokens、logit_bias、logprobs等一一对应见 src/engine.ts并发控制对同一modelId的请求通过 per-model 锁串行执行loadedModelIdToLocklock.acquire()保证同一模型上一次只处理一个补全请求流式分支若request.stream为真返回asyncGenerate(...)产出的AsyncIterable非流式分支按n次循环调用_generate()生成每个 choice并收集finish_reason自然结束为stop达到max_tokens为lengthlogprobs.content来自getTokenLogprobArray()仅在logprobs: true时填充text当echo: true时拼接为prompt outputMessage否则仅返回生成文本usage统计累加各 choice 的 prefill/decode token 数与耗时构成prompt_tokens、completion_tokens与total_tokens见 src/engine.tsseed 复位请求处理完毕后调用selectedPipeline.setSeed(Date.now())复位种子避免影响后续请求的确定性见 src/engine.ts。此外从 src/types.ts 的接口注释可以确认文本补全走的是无聊天模板路径且同一模型下的多个请求会按到达顺序阻塞排队执行。文本补全与聊天的本质区别无模板生成为什么这个示例不使用engine.chatCompletion而是engine.completions关键在于completion 不做任何对话模板包装prompt 原样送入模型模型输出续写文本。这一差异在对话管理层的测试中也有体现tests/openai_completion.test.ts以isTextCompletion true构造对话对象时getPromptArray()聊天模板路径会抛TextCompletionConversationError未设置prompt就调用getPromptArrayTextCompletion()会抛TextCompletionConversationExpectsPrompt设置conv.prompt Hi后getPromptArrayTextCompletion()返回[Hi]。也就是说文本补全直接复用 prompt 字符串本身作为输入天然适合前缀续写“代码生成”“填词”等不需要角色对话包装的场景而聊天补全则需要维护多轮消息历史并应用模板。这也解释了示例为何选择基座模型没有对话模板介入时基座模型行为更可预期。进阶把依赖替换为本地 WebLLM 源码包README 特别说明了一种面向二次开发者的用法原文见 examples/text-completion/README.md如果你希望修改 WebLLM 核心包本身而非仅仅调用其 API可以做两件事将示例的package.json中mlc-ai/web-llm依赖改写为本地路径dependencies: { mlc-ai/web-llm: file:../.. }按仓库的从源码构建说明在项目根目录构建本地webllm产物参见 docs/developer/building_from_source.rst。完成后npm install npm start即可让示例直接运行你本地编译的 WebLLM 核心包从而在最小示例环境中调试引擎层逻辑。README 也明确提示该选项仅推荐给确实需要修改 WebLLM 核心包的开发者普通使用场景直接依赖 npm 发布包即可。小结examples/text-completion虽小却完整覆盖了 WebLLM 文本补全能力的全部关键环节通过AppConfig自定义模型清单与overrides、以CreateMLCEngine加载基座模型、用 OpenAI 风格的engine.completions.create()完成无模板补全并提供了echo、n、max_tokens、logprobs等参数的现场示范。配合 src/openai_api_protocols/completion.ts、src/engine.ts 的实现与 tests/openai_completion.test.ts 的测试用例开发者既可以照抄最小示例快速跑通也可以顺藤摸瓜深入引擎源码理解 WebLLM 在浏览器端对 OpenAI Completion 协议的完整实现。【免费下载链接】web-llmHigh-performance In-browser LLM Inference Engine项目地址: https://gitcode.com/GitHub_Trending/we/web-llm创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表