很多人看到 “Show HN: Glaux” 这样的标题,第一反应是:又一个浏览器里跑 AI 的玩具?但如果你做过前端 AI 应用,或者负责过小型模型的服务端部署,你的反应可能会更深一层:无论是什么新项目,只要它能让“模型部署”这件事不再那么沉重,就值得认真看一下。
我的判断是:Glaux 这种“Browser-Only AI”项目,真正解决的不是“浏览器能不能跑 AI”,而是“跑一个社区模型到底要经过多少非技术环节”。换句话说,它把 AI 从“需要运维的推理服务”变成了“可以分发的前端资源”。这个变化,对独立开发者、前端团队和中小型项目的影响,可能比模型本身的能力提升更实际。
这篇文章会从四个层面展开:先讲为什么浏览器端 AI 值得关注,再拆解 Glaux、Hugging Face ONNX 模型和浏览器推理链路的核心概念,然后给出一个可以复制的最小示例,最后补充常见问题和工程建议。全程以 ONNX Runtime Web 为主要技术底座,因为 Glaux 这类工具无论封装得再好,底层也离不开这条链路。
1. 为什么浏览器端 AI 最近越来越值得关注
过去几年,一个前端开发如果想要在页面里加入“AI 能力”,几乎只有一个标准路径:找一台 GPU 服务器,部署一个推理服务,写一层 REST API,然后让前端去请求它。这个路径本身没有错,但它隐含了几笔很大的成本:
- 服务器成本:GPU 实例的价格远高于普通 Web 服务器,即使只有少量用户使用,也需要为高峰预留资源。
- 运维成本:模型更新、容器重启、并发扩容、异常监控,这些对于一个以页面开发为主的团队来说,是一个完全陌生的领域。
- 延迟成本:每一次推理都要经过一次完整的网络往返。如果用户和服务器不在同一个区域,体感会非常明显。
- 隐私成本:用户输入的数据必须上传到服务器。很多工具类场景,用户本身并不希望数据离开自己的设备。
浏览器端 AI 走的是另一条路径:把模型文件下载到本地,在浏览器里完成推理。用户不离开页面,数据不出本机,模型由开发者以静态资源的形式分发。你付出的成本从“GPU 服务器租金”变成了“模型文件的一次性下载”。
那为什么这条路直到最近才变得可行?三个技术条件逐步成熟:
- WebAssembly 提供了接近原生的 CPU 计算能力,浏览器不再只是解释执行 JavaScript 的脚本环境。
- WebGPU 让浏览器可以直接访问 GPU 做矩阵计算,为深度学习推理提供了硬件加速的可能。
- ONNX Runtime Web 这类运行时把复杂的算子适配、内存管理、设备调度封装成了几个 API,前端工程师不需要理解底层实现也能上手。
所以,我们看到越来越多面向浏览器的 AI 项目出现在 Hacker News、GitHub 和 CSDN 的热门列表里。Glaux 是其中一个典型代表。它的标题很直接:Browser-Only AI for Hugging Face ONNX Community Models。翻译过来,就是“专门跑 Hugging Face ONNX 社区模型的纯浏览器 AI 工具”。这句话包含了三个关键信息:模型来源是 Hugging Face、模型格式是 ONNX、运行环境是浏览器。
2. Glaux 是什么:不只是“又一个在线 Demo”
很多浏览器端 AI 项目,本质上是一个预置了某个模型的演示页面。你打开页面,点一下按钮,看到预测结果,然后关闭。做得再好一点,也只是内部封装了一个模型,用户无法替换。
Glaux 的定位不太一样。从它的标题看,它试图成为一个通用的运行层,让来自 Hugging Face 社区的大量 ONNX 模型能够直接在浏览器中加载和运行。这意味着它关注的不是某一个模型的效果,而是“模型接入链路”的通用性。
你当然可以说,ONNX Runtime Web 本身已经能把模型跑在浏览器里,为什么还需要 Glaux 这类工具?这里有一个很现实的问题:ONNX Runtime Web 给出的是一套库,你需要自己处理模型从哪里来、用什么版本、怎么管理缓存、模型加载失败怎么办、WebGPU 和 WebAssembly 后端怎么选、如何避免卡死主线程等一堆工程问题。Glaux 这类项目把这些环节整理成一条更顺滑的链路,让开发者不用每次从零开始。
我们可以用播放器的概念来类比:
- Hugging Face 像一个唱片库,里面躺着各种风格的模型。
- ONNX 是一种统一的 CD 格式,不管模型原本是用 PyTorch、TensorFlow 还是其他框架训练的,都可以转换成这种格式在多个平台上播放。
- 浏览器是一个不带厂商锁定的播放器。
- Glaux 就是那个“把 CD 塞进播放器,按一下播放”的自动唱机。它不生产音乐,但它让你拿到 CD 后不需要研究播放器内部结构。
对开发者来说,最实际的收益是:想尝试一个社区模型时,不再需要先准备一个 Python 环境、下载依赖、启动 Flask/FastAPI 服务,然后再写前端代码。你只需要拿到 ONNX 模型文件,把它放进前端工程,可能十几行代码就能完成一次推理调用。
当然,这里也要诚实地指出边界。Glaux 这类工具面向的是中小型模型,比如文本分类、指令问答的小型版本、图像分类、目标检测、语音识别等。如果你要的是动辄几十 GB 参数的顶级大模型,浏览器端方案短期内并不现实。理解这个边界,才不会对这个项目产生不合理的预期。
3. ONNX 与 Hugging Face 社区模型:为什么偏偏是这两个
要理解 Glaux,必须先理解它的两个基石:ONNX 和 Hugging Face 社区模型。
3.1 ONNX 是 AI 模型的“通用转接头”
ONNX(Open Neural Network Exchange)是一种开放的模型表示格式。它解决的问题非常具体:PyTorch 训练的模型不能直接给 TensorFlow Serving 用,TensorFlow 的 SavedModel 也不能直接变成 Core ML 模型。每个深度学习框架都有自己的产物格式,部署到不同平台时,要么重新训练、要么做复杂的格式转换。
ONNX 的思路是:把训练好的模型导成一张标准化的计算图,里面包含了算子的类型、张量的形状、权重数据等信息。只要支持 ONNX 的运行时能理解这张计算图,就能执行推理。你可以把它理解成一个通用转接头:只要两端都支持这个标准,就能互通。
ONNX 能够在浏览器里跑,靠的是 ONNX Runtime Web 这个运行时。它有两种执行后端:
- WebAssembly 后端:兼容性最好,几乎所有现代浏览器都能运行,不需要 GPU 也能做推理,但速度相对慢。
- WebGPU 后端:利用浏览器对 GPU 的访问能力,适合计算量较大的模型,但需要较新的浏览器版本和可用 GPU。
ONNX Runtime Web 负责把计算图映射到这些后端上,尽可能把中间过程对开发者隐藏。这就是“浏览器端 AI”的技术基础。
3.2 Hugging Face 社区提供了“模型货源”
Hugging Face 之所以能成为 AI 开发者绕不开的平台,并不是因为它只是存模型文件,而是它建立了一个完整的生态:模型库、数据集、推理 API、模型卡说明、社区评分,以及最重要的,海量的预训练模型。
在 Hugging Face 的模型库中,有一类组织名为onnx-community的仓库,专门提供转换好的 ONNX 格式模型。也有大量开发者把自己训练的模型导出为 ONNX 后上传到个人仓库。这些模型涵盖了:
- 文本分类、情感分析、信息抽取
- 小型指令问答模型
- 图像分类、目标检测(包括 YOLOv8、YOLOv11 等社区的 ONNX 导出版本)
- 语音识别和音频处理
- 多模态嵌入模型
过去,这些模型主要面向服务端部署。如果你要在前端使用,通常要先下载 PyTorch 权重,再做转换,再放进自己搭的推理服务里。Glaux 这类工具的出现,让这些社区模型有了一个直接面向浏览器的出口。对于做网页应用、浏览器插件、互动类小游戏的开发者来说,这意味着可以用非常小的成本,在页面里接上 AI 能力。
不过,并不是 Hugging Face 上的所有模型都能直接跑在浏览器里。模型过大、依赖特殊算子、需要动态形状支持的模型,可能无法运行或性能很差。这也是后面“常见问题与排查思路”里会重点讲的内容。
4. 浏览器运行 AI 的核心原理
很多读者可能没有接触过 ONNX Runtime Web。我建议不要把它当成一个黑盒,至少要知道一条推理请求从发起到出结果,经过了哪些环节。这对排查问题帮助非常大。
一次完整的浏览器端 ONNX 推理过程大致是这样的:
- 前端代码发起加载模型的请求,模型文件被下载到浏览器。
- ONNX Runtime Web 创建会话(InferenceSession),把模型计算图解析到内存中。
- 运行时自动选择一个可用的执行后端,优先 WebGPU,如果没有则退回到 WebAssembly。
- 前端把输入数据整理成张量(Tensor),传给会话。
- 会话按照计算图逐层执行算子,得到输出张量。
- 前端把输出张量转换成 JavaScript 可读的数据,再转换成业务结果。
这里有几个容易被误解的地方:
- 模型加载不等于一次推理。模型文件下载、解析、初始化是很耗时的步骤,所以生产环境必须做缓存和预热。
- 后端选择是自动的,但默认行为未必最优。你需要明确指定
executionProviders: ['webgpu', 'wasm']这样的配置,否则不同浏览器表现可能不同。 - ONNX Runtime Web 支持 GPU 加速,但不等于它一定会用 GPU。WebGPU 需要浏览器开启支持、操作系统提供对应图形驱动,如果条件不满足,它会回退到 CPU 上的 WASM 执行。
- 动态形状的模型在浏览器里更容易出现性能问题。因为张量形状不确定,运行时无法提前做好内存规划和算子融合优化。社区里常见的做法是固定输入尺寸,例如把文本序列长度限制为 128 或 256,把图像分辨率固定。
用一句话概括:浏览器端 AI 的本质,是把“模型部署”这个原本属于服务端的工程问题,压缩成了一个“前端资源管理与运行时适配”的问题。Glaux 这类工具做的,就是让这个压缩过程看起来更自然。
5. 环境准备与前置条件
如果你要跟着后面的示例操作,先确认环境是否满足以下条件。这里不写死具体版本号,因为浏览器和工具链更新很快,重点看能力项。
5.1 浏览器
推荐使用最新版的 Chrome、Edge 或 Firefox。如果需要 WebGPU 加速,最好使用 Chrome/Edge 的较新版本,并在chrome://gpu页面确认 WebGPU 状态为可用。Safari 对新特性的支持节奏比较特殊,如果你的主要测试对象是 Safari,建议先跑通 WebAssembly 后端,再考虑 WebGPU。
5.2 网络条件
模型文件需要从 Hugging Face 下载。开发时需要保证网络可以正常访问 Hugging Face,生产环境建议把模型文件放到自己的 CDN、对象存储或静态资源服务器上。这样既提升了加载速度,也避免依赖第三方站点。
5.3 前端工程
后面的示例使用 Vite 构建,因为它配置简单,适合快速验证。如果你更习惯 Webpack,原理也一样。Node.js 环境建议使用现网 LTS 版本。
5.4 核心依赖
本文示例会用到:
onnxruntime-web:ONNX Runtime 的浏览器端版本,提供InferenceSession等核心 API。@huggingface/transformers(可选):如果你想用更高层的 Pipeline 方式跑模型,可以引入它。本文重点演示底层链路,所以以onnxruntime-web为主。
这里要特别说明:本文的示例演示的是“浏览器端加载 ONNX 模型并做推理”的完整链路。Glaux 这类工具本质上是把这套链路封装成了更友好的接口,所以直接理解底层代码,对你使用任何上层工具都有帮助。
5.5 模型准备
你需要一个可用的 ONNX 模型文件。可以到 Hugging Face 搜索onnx-community组织下的仓库,或者搜索某个具体任务名称加onnx关键词。下载后,把.onnx文件放到项目的public/models目录。为了控制篇幅,示例假设你使用一个文本分类模型,输入为 token 序列,这类模型在浏览器中的运行效果比较清晰,便于验证。
如果你暂时找不到合适的模型,也可以先用一个结构简单的示例模型跑通流程,后续再换正式模型。
6. 完整示例:在浏览器里跑通一个 ONNX 模型
下面我们用一个最小 Vite 工程,走通“加载 ONNX 模型 → 构造输入 → 执行推理 → 显示结果”的完整链路。
6.1 初始化项目并安装依赖
npm create vite@latest onnx-browser-demo -- --template vanilla cd onnx-browser-demo npm install npm install onnxruntime-web这里使用 Vite 的 vanilla 模板,是为了让示例保持最简。如果你是 React/Vue 项目,原理是一样的,只是把调用封装到组件里。
6.2 把模型文件放到静态目录
在public目录下创建models文件夹,放入你的.onnx模型文件。
onnx-browser-demo/ ├─ public/ │ └─ models/ │ └─ model.onnx ├─ src/ │ ├─ main.js │ └─ style.css ├─ index.html └─ package.jsonVite 会把public目录里的内容原样复制到最终构建产物中。后续代码通过/models/model.onnx这样的路径访问。
6.3 编写推理代码
打开src/main.js,写入以下内容。
import * as ort from 'onnxruntime-web'; const MODEL_URL = '/models/model.onnx'; async function runInference() { const session = await ort.InferenceSession.create(MODEL_URL, { executionProviders: ['webgpu', 'wasm'], }); // 这里的输入 name 和维度根据你的模型确定 const inputName = session.inputNames[0]; const inputTensor = new ort.Tensor('int64', new BigInt64Array(128).fill(0n), [1, 128]); const outputs = await session.run({ [inputName]: inputTensor }); const outputName = session.outputNames[0]; const data = outputs[outputName].data; console.log('推理结果:', data); } runInference().catch((err) => { console.error('推理失败:', err); });这段代码做了三件事:
- 创建 InferenceSession,传入模型 URL 和 executionProviders 配置。
- 构造一个形状为
[1, 128]的 int64 张量作为输入。实际项目中,你需要根据模型的 tokenizer 和预处理逻辑来生成输入。 - 调用
session.run()执行推理,然后从输出张量中读取数据。
需要特别提醒:不同模型的输入名、输入类型、输入维度完全不同。上面的代码只是一个模板,你必须根据自己模型的实际定义改写。一个常见的错误是照搬模板,却遇到“输入名找不到”或“形状不匹配”的报错。所以拿到一个新模型时,第一件事是看它在 Hugging Face 上的模型卡,确认输入要求。
6.4 把推理放到 Web Worker 中
上面的示例已经能跑通,但如果模型较大,session.run会阻塞主线程,导致页面卡顿。生产环境应该把推理放到 Web Worker 里。
创建src/worker.js:
import * as ort from 'onnxruntime-web'; let session = null; async function predict(inputData) { if (!session) { session = await ort.InferenceSession.create('/models/model.onnx', { executionProviders: ['webgpu', 'wasm'], }); } const inputName = session.inputNames[0]; const tensor = new ort.Tensor('int64', BigInt64Array.from(inputData), [1, inputData.length]); const outputs = await session.run({ [inputName]: tensor }); return Array.from(outputs[session.outputNames[0]].data); } self.onmessage = async (e) => { const { id, data } = e.data; try { const result = await predict(data); self.postMessage({ id, result, ok: true }); } catch (err) { self.postMessage({ id, error: String(err), ok: false }); } };在主线程中创建 Worker:
const worker = new Worker(new URL('./worker.js', import.meta.url), { type: 'module' }); function requestInference(data) { return new Promise((resolve, reject) => { const id = Date.now() + Math.random(); const handler = (e) => { if (e.data.id !== id) return; worker.removeEventListener('message', handler); if (e.data.ok) { resolve(e.data.result); } else { reject(new Error(e.data.error)); } }; worker.addEventListener('message', handler); worker.postMessage({ id, data }); }); }Worker 的好处是:模型加载、张量构造、推理计算全部不占用主线程,用户界面不会出现“假死”状态。这也是浏览器端 AI 项目里最重要的工程优化之一。Glaux 这类工具如果封装得好,大概率内部也使用了类似的模式。
6.5 模型缓存与二次加载优化
每次刷新页面都重新下载大模型,会严重拉低体验。常见做法是使用浏览器的 Cache API,把模型文件缓存起来,下次加载时优先从缓存读取。这里给出一个最小的封装思路:
async function loadModelWithCache(url) { const cache = await caches.open('onnx-models'); let response = await cache.match(url); if (!response) { response = await fetch(url); if (!response.ok) { throw new Error(`模型加载失败:${response.status}`); } await cache.put(url, response.clone()); } const blob = await response.blob(); return URL.createObjectURL(blob); }然后在创建会话时,把模型的 URL 换成这个缓存逻辑生成的对象 URL:
const modelUrl = await loadModelWithCache(MODEL_URL); const session = await ort.InferenceSession.create(modelUrl, { executionProviders: ['webgpu', 'wasm'], });这个方式有一个坑需要注意:InferenceSession.create需要能拿到完整的模型文件,直接传blob:URL 在某些浏览器版本上可能有问题。如果你在测试中遇到加载失败,可以退回直接使用 HTTP URL,或者在本地环境下提前完成模型文件的预下载。
7. 运行结果与效果验证
完成上面的步骤后,运行开发服务器:
npm run dev浏览器打开 Vite 输出的本地地址。如果代码正确,你会在控制台看到类似这样的输出:
推理结果:Float32Array(2) [0.82, 0.18]这表示模型对输入的预测置信度。具体数值没有绝对意义,你需要结合模型的类别标签做解读。
从三个层面判断是否成功:
- 页面正常打开,控制台没有报错。如果出现
Failed to fetch或404,优先检查public/models路径是否写对,以及模型文件是否真的存在于该目录。 - 网络面板能看到模型文件的加载记录。打开 DevTools 的 Network 面板,刷新页面,搜索
.onnx,应该能看到一个体积较大的请求。如果模型文件没有出现在请求列表中,说明代码里模型 URL 不对。 - 第一次推理完成后,再次触发推理时响应明显变快,说明会话已经被复用,模型解析和初始化只发生了一次。
如果首次推理耗时过长,先不要急着怀疑代码。浏览器首次下载模型、解析计算图、初始化 WASM 模块都需要时间。这在本地开发时尤其明显。你需要做的是把“模型加载”和“推理”两个阶段分开计时,才能准确定位瓶颈。
一个常见的测试误区是:只在本地预览时看到模型能出结果,就认为可以上线了。实际上生产环境和本地有显著差异,主要区别在于:生产环境模型文件体积大,CDN 和缓存策略直接影响首次加载时间;低端安卓设备的内存和 CPU 差异明显,同样的模型可能在高配电脑上流畅、在手机上直接崩溃。因此,发布前一定要至少在低端真机和 Safari 上各做一轮验证。
8. 常见问题与排查思路
浏览器端 ONNX 推理涉及浏览器、Runtime、模型文件三个层面,问题定位比纯前端更复杂。下面是真实项目中最常遇到的几类问题。
| 问题现象 | 可能原因 | 排查方式 | 解决方案 |
|---|---|---|---|
| 模型文件请求返回 404 | 模型路径写错,或文件没有放在 public 目录 | 检查 Network 面板请求 URL | 修正路径,确认文件位于 public 目录下 |
| CORS 错误导致模型加载失败 | 模型存储在跨域存储服务上,且未配置 CORS 头 | 查看浏览器控制台 CORS 报错 | 将模型放到同源目录,或在存储服务配置 CORS |
| 控制台提示 WebAssembly 不支持 | 浏览器版本过旧,或测试环境禁用了 WASM | 检查浏览器版本和设置 | 升级浏览器,或启用 WASM 支持 |
| 创建会话时报“模型格式无效” | 模型不是标准 ONNX 格式,或文件损坏 | 用 Python 加载模型验证完整性 | 重新导出模型,或重新下载文件 |
| 运行时报“输入名不存在” | 代码里写死的输入名和模型实际输入不一致 | 打印session.inputNames对比 | 按模型卡修改输入名 |
| 推理速度很慢 | 未使用 WebGPU,或模型没有量化 | 查看运行日志中的执行后端信息 | 配置executionProviders: ['webgpu', 'wasm'],或使用 INT8/INT4 量化模型 |
| 页面卡死无响应 | 推理直接主线程执行 | 检查代码是否在主线程调用run | 把推理迁移到 Web Worker |
| 刷新后每次都要重新下载大模型 | 没有做模型缓存 | 观察 Network 面板是否每次都有模型请求 | 使用 Cache API 或 IndexedDB 缓存模型 |
| WebGPU 后端报错 | 浏览器 GPU 加速不可用,或驱动问题 | 检查 GPU 状态面板 | 回退到 WASM 先保证功能可用 |
这里重点说两个问题。
第一个是 CORS。浏览器端的模型文件加载本质上是一个 HTTP 请求,任何跨域请求都必须符合 CORS 规则。如果你把模型放在阿里云 OSS、腾讯云 COS、AWS S3 或者任意 CDN 上,一定要在存储服务控制台配置允许的来源和安全方法。否则,本地开发可能因为同源不报错,一旦部署到线上域名,模型就加载失败。
第二个是模型量化和剪枝。现在很多社区模型已经提供了量化版本,比如.onnx量化成 INT8 或 INT4。量化后的模型体积可以缩小到原来的四分之一甚至更低,推理速度也有明显提升。代价是模型精度会有小幅下降,具体损失要看任务类型。如果你打算把一个 PyTorch 模型导出后直接用,经常会出现模型文件过大、浏览器加载几秒甚至十几秒的情况。所以我建议:在浏览器端项目里,优先选择量化后的 ONNX 模型,或者自己用onnxruntime的 Python 工具链做量化。
9. 最佳实践与工程建议
在浏览器端 AI 项目里,“能跑通 demo”和“能上生产”之间,隔着一整条工程链。这里把核心经验总结成可执行的建议。
9.1 优先选择量化模型
浏览器端的资源和算力都是有限的。一个 FP32 的 BERT 模型文件可能达到 400MB 以上,这在移动端几乎不可用。量化为 INT8 后,体积可能降到 100MB 左右,更接近可接受范围。更激进的做法是 INT4 量化,但要注意部分算子对低比特量化支持不完整,导出前需要验证。
9.2 把模型文件放在可靠的 CDN 上
千万不要直接让生产环境的前端工程从 Hugging Face 拉取模型。Hugging Face 本身是一个模型研发平台,并不是面向终端用户的海量静态资源服务。从它的域名加载模型,你无法控制缓存、无法做自定义回源、也缺少对线上用户的访问质量保障。正确做法是把模型文件下载到自己的对象存储或 CDN,再交给前端配置。
9.3 管理模型版本
前端工程里,模型也和 npm 依赖一样需要版本管理。建议把模型文件的版本号写到文件名里,例如model-int8-v2.onnx。好处是:当模型更新时,你可以通过改文件名触发新的缓存,而不是让用户因旧缓存继续使用旧版本逻辑。同时,最好在页面里展示模型版本信息,否则用户反馈问题时,你很难判断他跑的是哪个模型。
9.4 拆分模型加载和业务渲染
大模型文件的加载时间可能长达数秒。好的产品设计会把加载过程变成一种可见的状态:显示加载进度、预加载必要模型、在模型未就绪时先展示可交互的页面骨架。不要等模型加载完才渲染整个页面,这样用户看到的就是一个白屏。
9.5 明确安全边界
浏览器端 AI 有一个必须提醒的安全问题:模型和代码都暴露在用户设备上。如果你的模型包含私有数据,或者你的业务逻辑依赖“用户不能直接调用模型”,那么浏览端方案并不合适。在浏览器里,一切可下载的资源都无法防止被爬取。你只能在“离线可运行”和“服务端保护模型”之间做选择。对于真正需要保护模型权重或请求密钥的场景,还是应该部署后端代理。
9.6 考虑向后端降级
我不建议把一个浏览器端 AI 方案设计成不可回退的独家方案。更稳妥的做法是抽象出推理接口,浏览器端可用时走本地推理,不可用时降级到远程 API。这样至少能保证核心功能永远可用,同时为低端设备用户保留一条可用的路径。
9.7 额外提醒:模型授权与登记
Hugging Face 上的模型不一定都是宽松许可证。有些模型只允许研究用途,有些对商用有严格限制。在项目上线前,记得检查模型卡中的 License。如果模型禁止商用,或者要求保留版权声明,请严格遵守。这不是一个技术问题,但它比任何技术问题都可能带来更严重的后果。
10. 总结与后续学习方向
Glaux 这类浏览器端 AI 项目,真正的意义不是让浏览器多了一个“可以运行 AI”的能力标签,而是让模型分发的模式发生了一次值得关注的转变:从“部署服务”转向“分发资源”。它降低了小团队尝试 AI 的工程门槛,也让隐私敏感、低延迟、离线优先的应用有了更顺滑的落地方式。
如果你看完这篇文章想动手实践,我建议按这个顺序走一遍:
- 先挑一个 Hugging Face 上的小型 ONNX 模型,下载到本地,用 ONNX Runtime Web 跑通加载和推理。
- 把推理迁到 Web Worker,确认 UI 不再卡顿。
- 给模型文件加上 Cache API 缓存,刷新页面观察二次加载速度。
- 再尝试模型量化,对比量化前后的大小、速度和精度损失。
- 最后,在手机浏览器和低配置电脑上各做一轮验证。
后续值得继续深入的学习方向是:ONNX Runtime Web 的算子优化、WebGPU 计算管线和 shader 行为、模型量化的精度评估、以及在 Worker 里使用 OffscreenCanvas 做实时视频流检测。浏览器端 AI 并不是把 Python 的推理搬到浏览器这么简单,它的性能瓶颈、内存模型和工程实践都值得单独研究。
如果你之前习惯把 AI 能力都放在后端,现在可以带着一个新视角看前端:很多小模型推理,已经完全可以交给浏览器了。这个方向未必适合所有业务,但它至少值得你认真测试一遍,因为一旦跑通,你省下的不只是服务器租金,还有一整条服务端链路。建议收藏本文,作为你开始尝试浏览器端 ONNX 推理的第一份参考。