我如何构建一个在本地使用 WebGPU 运行 Llama、DeepSeek 和 Mistral 的 Chrome 扩展(无需 Ollama,无服务器)

发布: (2026年2月12日 GMT+8 13:15)
11 分钟阅读
原文: Dev.to

Source: Dev.to

为什么这个项目?

到目前为止,我们只在 GitHub 仓库或独立站点上看到基于 WebGPU 的 LLM 演示。这是第一个 Chrome 扩展,让喜欢在浏览器中“安装即用”的用户也能获得同样的体验——无需开发环境设置、无需 API 密钥、无需服务器。

我的动机

  • 隐私顾虑 – 云 AI 服务会把每个提示发送到远程服务器。我想要一个留在本机的方案。
  • “本地 AI” 的复杂性 – 像 Ollama 这样的工具很棒,但它们需要终端命令、模型下载,而且通常需要一台允许的工作笔记本。我需要一个我的非技术朋友(甚至是我妈妈)也能使用的方案。
  • 成本 – $20 / 月对于偶尔使用(语法修正、文档摘要、偶尔的编码帮助)来说会累积。我想要一个免费、私密的替代方案。

我构建的

一个在浏览器内部运行 LLM 推理的 Chrome 扩展——无需服务器、无需 Ollama、无需 Docker、无需繁琐。只需安装即可聊天。

三大主要优势

优势含义
隐私消息和模型权重永不离开浏览器。
成本下载一次模型后,推理免费(无需 API 调用)。
离线缓存后,模型可在飞机上、地铁里或任何没有互联网的地方使用。

权衡: 只能使用较小的量化模型(例如 Llama‑Quant、SmolLM、Phi、DeepSeek‑R1 蒸馏版)才可行。对于日常写作、摘要和代码辅助,它们已经足够。

高层架构

Next.js front‑end

   └─ useChat (Vercel AI SDK)

          └─ BrowserAIChatTransport  ← custom transport

                 ├─ selects provider & model (Zustand store)
                 ├─ obtains language model (ModelManager)
                 ├─ (optional) wraps reasoning models with extractReasoningMiddleware
                 └─ calls streamText → UIMessageStream
  • UI:相同的代码既可以作为普通网页应用运行,也可以作为 Chrome 侧边栏扩展(静态导出)运行。
  • 后端:这里的“后端”是通过 WebGPU 使用你的 GPU,而不是 Node 服务器。
  • 传输层useChat 只关心能够接收消息并返回流的传输层,因此 UI 对底层提供者保持透明。

提供者支持

提供者描述最佳使用场景
WebLLM (MLC)基于 WebGPU,支持更大的模型(Llama 3.2、Qwen、DeepSeek R1)。在性能尚可的 GPU 上实现快速推理。
Transformers.js通过 WASM 在 CPU 上运行,体积更小。适用于 SmolLM 等轻量模型。
Browser AI (Prompt API)Chrome 内置的 Gemini Nano。无需下载,开箱即用。

所有提供者都实现相同的 LanguageModelV3 接口。ModelManager

  • 实例化正确的适配器。
  • 缓存模型实例(以便切换标签页时不会重新下载)。
  • 为 UI 发出进度回调。

模型 ID 存放在单一的 models 模块中,经过低显存过滤并标记为 “supports reasoning” 或 “supports vision”。这使得传输层和 UI 都能了解每个模型的能力。

模型下载与初始化

下载权重文件可能有数千兆字节,空白页面会导致糟糕的用户体验。我创建了一个 useModelInitialization Hook,它:

  1. 检查缓存(availability() === "available")。
  2. 如果缺失,触发一次最小化的 streamText 调用以开始下载。
  3. 将进度更新通过管道传递给 UI。

进度可以来自两个来源:

  • 模型管理器的回调。
  • streamTextdata-modelDownloadProgress 事件。

这两个流会合并为一个进度条,以提供流畅的体验。

处理推理模型

DeepSeek R1 这样的模型会在最终答案之前输出一个 块。我想在 UI 中展示这种“思考过程”。

  • AI SDK 的 extractReasoningMiddleware 会解析这些标签。
  • 在 UI 端,会检查每个消息片段:
    • 如果是推理 → 渲染一个 “ 组件(可折叠)。
    • 否则 → 渲染普通文本。

因此,同一条流可以呈现两种不同的显示方式。

代码片段

传输实现(简化版)

// BrowserAIChatTransport.ts
const baseModel = modelManager.getModel(provider, modelId);

const model = isReasoningModel(modelId)
  ? wrapLanguageModel({
      model: baseModel,
      middleware: extractReasoningMiddleware({
        tagName: "think",
        startWithReasoning: true,
      }),
    })
  : baseModel;

const result = streamText({
  model,
  messages: modelMessages,
  ...streamOptions, // only pass options the provider actually supports
});

return result.toUIMessageStream();

选项处理

一个坑点: 并非所有模型都支持每个选项(例如 topPpresencePenalty)。传输层只会转发 (a) 当前提供者支持的 并且 (b) 已显式设置的选项。我是吃了大亏才明白的。

要点

  1. WebGPU 使得在浏览器中进行 LLM 推理变得实用,适用于中等规模的模型。
  2. 单一传输抽象 让相同的 UI 能够与多个后端通信,而无需重复代码。
  3. 进度处理 对于在下载大型模型文件时提供良好的用户体验至关重要。
  4. 推理中间件 提供了一种简洁的方式来展示模型的内部思考过程。
  5. Chrome 扩展 可以作为私有离线 AI 工具的便捷分发渠道。

接下来是什么?

  • 添加对视觉模型的支持(例如 OCR、图像字幕)。
  • 尝试量化技巧,以将更大的模型压缩到低显存设备上。
  • 完善移动 Chrome 的 UI/UX(侧边面板 vs. 全屏)。

欢迎在 noaibills.app 试用此扩展,如遇到任何问题请提交 issue!

概览

  • 静态导出 – Next.js 使用 output: "export" 构建,并将所有内容放入 extension/ui/。侧边面板加载 ui/index.html
  • CSP 问题 – Chrome 扩展不允许内联脚本。构建后脚本会提取 HTML 中的所有内联 “,将其保存为独立文件,并重写 HTML 以引用这些文件。
  • WASM 加载 – transformers.js 需要 ONNX Runtime 的 WASM 文件,这些文件无法在扩展中从 CDN 获取。构建脚本会将它们复制到 extension/transformers/,并在 web_accessible_resources 中声明。

结果: 一个代码库,一个构建流程。

  • 开发在 localhost:3000 运行。
  • 生产环境构建为 Chrome 扩展。

持久化对话

我希望聊天能够在关闭标签页和浏览器重启后仍然保留,于是我使用了 Dexie(一个轻量级的 IndexedDB 包装器)并定义了一个简单的模式:

字段类型
idstring(对话 ID)
titlestring
modelstring
providerstring
createdAtDate
messagesarray of message objects

当用户从历史记录中选择一个对话时,应用会 rehydrates(重新加载)所有内容——包括所使用的模型——从而让用户能够准确地从上次离开的地方继续。

从旧存储迁移

旧版本将数据存储在 localStorage 中。首次加载时,应用会:

  1. 检测到旧版数据。
  2. 批量插入到 IndexedDB 中。
  3. 删除旧的 localStorage 条目。

聊天记录不会丢失。

架构要点

  • 单传输模式 – 添加新提供者只需“接线适配器,添加模型 ID”。用户界面保持不变。
  • 浏览器限制 – CSP、WASM 加载和存储配额都可以通过合适的构建脚本解决;只需为它们分配时间。
  • 进度反馈 – 如果用户看到进度条,他们会等待 2 GB 的下载。空白屏幕会导致放弃。

用例定位

  • 本地 AI 足以应对大多数日常任务(草稿、摘要、快速编码问题)。
  • 不是 替代像 GPT‑4 这样的 大型云模型,但本地运行的 3 B 参数模型可以处理约 80 % 的常规文本工作。

目标受众

  • 拥有严格数据隐私政策、阻止使用云 AI 且无法安装 Ollama 或 LMStudio 等桌面工具的组织。
  • 需要快速草稿、语法检查或基本推理、且 不需要 API 费用或互联网依赖的团队。

对于需要实时知识或深度推理的任务,云模型仍是更好的选择。

建设者要点

如果你正在构建类似的东西,下面的模式应该可以推广到任何浏览器内运行时:

  1. 静态导出,并在构建后修复 CSP 和 WASM。
  2. 模型管理器 + 单传输 抽象,用于提供者。
  3. IndexedDB(通过 Dexie)用于持久化对话存储以及从旧格式迁移。

试试看吧:noaibills.app

如有疑问或反馈,欢迎随时联系——我很期待收到你的来信!

0 浏览
Back to Blog

相关文章

阅读更多 »

KAIzen — AI 时代对敏捷的需求

一家游戏公司的小团队如何将流效率从 32% 提升到 85%——通过改变我们提供给 AI 的内容。我们的团队严格遵循 Scrum:两周的 s...