BrowserAI:把 MLC、Transformers、Flare、Demucs 四套引擎塞进一个浏览器 SDK
Run local LLMs like llama, deepseek-distill, kokoro and more inside your browser
秒懂
- 它是什么?
- BrowserAI 是一个 TypeScript 库,用统一 API 在浏览器里跑本地模型,覆盖文本生成、语音识别、语音合成和音源分离。它的价值在于把 WebGPU 与 WASM 两条技术路线的差异封装掉,代价是模型清单、量化档位和引擎能力都被提前限定。
- 适合谁用?
- 如果你要在网页里做本地推理,且需求落在 BrowserAI 已预置的模型清单内,比如 llama-3.2-1b-instruct、whisper-tiny-en、kokoro-tts 或 htdemucs,这个库能省掉引擎适配层的重复工作,MIT 许可也允许直接嵌入闭源产品。如果你的目标模型不在清单里,或者你需要自选量化档位、需要控制权重下载源,那么应该先把 loadModel 的模型解析逻辑读一遍,确认它能否指向你自己的模型文件;不能的话,直接基于 MLC 或 transformers.js 自建反而更短。
- 能商用吗?
- 可以。MIT 是宽松许可证:你可以使用、修改并销售基于它的软件,只需保留版权和许可证声明。
- 还在维护吗?
- 在维护。仓库最近一次提交在 57 天前。
- 用什么语言写的?
- 主要是 TypeScript(依据 GitHub 的语言统计)。
以上回答依据项目的 GitHub 数据(最近同步于 2026年9月15日)和我们的分析,不构成法律意见。
开源项目深度解析
它替谁挡掉了引擎适配这层脏活
浏览器里跑模型从来不是单一技术栈的问题。WebGPU 适合矩阵运算密集的推理,WASM 适合把已有的 GGUF 运行时搬进来,而语音和音频任务又各自有更合适的实现路径。README 列出 BrowserAI 同时支持 MLC、Transformers、Flare 和 Demucs 四个引擎,并强调可以在它们之间切换。这意味着调用方不需要为文本生成写一套 WebGPU 初始化,为 GGUF 再写一套 WASM 内存管理,为语音识别再接一套音频管线。
目标读者因此比较明确:做 AI 功能的 Web 开发者,以及需要把推理留在用户设备上的产品团队。README 把 100% Private 和 Zero Server Costs 放在功能列表最前面,这两个说法指向同一件事,权重和输入都不离开浏览器,服务端只负责托管静态资源。对于处理敏感文本、又不愿意承担 GPU 服务器账单的场景,这个取舍是成立的。
但要注意,隐私承诺的边界由模型下载决定。README 的离线能力描述是 initial download 之后可用,也就是说首次仍要从某个地址拉取权重。权重从哪来、是否经过第三方 CDN,README 没有展开,这一点需要在代码里确认。
四套引擎各管一段,API 表面是统一的
BrowserAI 的核心设计是把引擎差异收在 loadModel 后面。README 的基础示例展示了这条路径:先 new BrowserAI(),再 loadModel('llama-3.2-1b-instruct', { quantization: 'q4f16_1', onProgress }),然后 generateText。onProgress 回调里拿到 progress.progress 百分比,用于加载进度条。这个回调的存在本身说明模型加载是异步且耗时的,否则不需要暴露进度。
引擎分工可以从模型清单反推。MLC 那一组是文本生成的主力,从 SmolLM2-135M 一直到 Qwen3-8B,还包括 DeepSeek-R1-Distill 系列和 Snowflake-Arctic-Embed 系列嵌入模型。Transformers 那一组覆盖了 Whisper 语音识别和 Kokoro 语音合成,同时也有 llama-3.2-1b-instruct,说明同一个模型名可能对应不同引擎实现。Flare 走的是另一条路,README 明确写着 GGUF Models via WASM,模型名带 -flare 后缀,例如 llama-3.2-1b-flare,并且支持通过 loadAdapter 加载 safetensors 格式的 LoRA 适配器。Demucs 单独从 @browserai/browserai/demucs 导入,用 DemucsEngine 类,输出 drums、bass、other、vocals 四路 AudioBuffer。
数据流因此是分叉的。文本生成走的是 token 输入、token 输出,结果包在 choices[0].message.content 里。语音识别走的是音频 Blob 输入、文本输出。语音合成走的是文本输入、AudioBuffer 输出,需要调用方自己用 AudioContext 解码播放。音源分离走的是 AudioBuffer 进、多路 AudioBuffer 出。四者共享的只有 BrowserAI 这个入口对象和加载进度的表达方式,输出形态完全不同。
从安装到出声,README 给出的最短路径
安装命令是 npm install @browserai/browserai,yarn 对应 yarn add @browserai/browserai。包名带 scope,导入方式是 import { BrowserAI } from '@browserai/browserai'。
文本生成的最小闭环是三步。构造实例,加载模型,调用 generateText。加载时可以传 quantization,示例用的是 q4f16_1。生成时可以传 temperature、max_tokens 和 system_prompt,也可以直接把消息数组交给 generateText,数组元素形如 { role: 'system', content: '...' } 和 { role: 'user', content: '...' }。结构化输出通过 json_schema 加 response_format: { type: 'json_object' } 触发,README 给的例子是让模型返回一组颜色及其 hex 值。
语音识别的流程是 loadModel('whisper-tiny-en'),然后 startRecording、stopRecording 拿到 audioBlob,再调用 transcribeAudio,参数里可以带 return_timestamps: true 和 language: 'en'。语音合成是 loadModel('kokoro-tts') 之后调用 textToSpeech,参数含 voice 和 speed,示例用的音色是 af_bella,速度 1.0,返回 AudioBuffer,后续播放代码由调用方自己写。
音源分离需要单独导入 DemucsEngine,loadModel 时传入 htdemucs 配置,然后调用 separate,参数有 shifts 和 overlap。README 对这两个参数的解释是 shifts 表示时间偏移增强的遍数,越高音质越好但越慢,overlap 是分段重叠比例。这是全文少见的明确性能权衡说明。
预置模型清单是便利,也是硬边界
BrowserAI 的模型清单是写死的枚举。MLC 一组约二十个,Transformers 一组五个,Flare 一组四个,Demucs 只有一个 htdemucs。README 在清单开头写着 More models will be added soon,并建议通过创建 issue 请求模型。这句话的含义是,清单之外的东西现在用不了。
这个限制在实践中的后果比看上去严重。如果你手上已经有一份微调过的 GGUF,或者想用清单里没有的量化档位,比如某个只发布了 Q5_K_M 的模型,你无法通过传参绕过。Flare 引擎的模型名后缀、MLC 引擎的量化标识,都是库内部解析的一部分,README 没有提供指向自定义模型 URL 的接口。loadAdapter 加载 LoRA 是唯一的自定义入口,但它要求基础模型本身已在清单内。
另一个需要留意的是同一模型跨引擎的重复。llama-3.2-1b-instruct 同时出现在 MLC 和 Transformers 两组里,Flare 组里则有 llama-3.2-1b-flare。调用 loadModel 时传哪个名字,决定走哪条推理路径,而这两条路径的性能特征并不相同。README 没有说明这种重名如何解析,也没有给出选择建议,这是文档偏薄的地方。
WebGPU 是加速项,也是前置条件
README 把 WebGPU 列为关键特性之一,描述是 Near-native performance。这个说法没有附带任何数字,也没有说明在缺少 WebGPU 的浏览器上会怎样降级。从引擎划分看,MLC 和 Transformers 路径依赖 WebGPU,Flare 路径明确走 WASM,理论上后者不依赖 WebGPU。但 README 没有确认 Flare 是否能在无 WebGPU 环境下独立工作,也没有给出回退策略。
这构成一个真实的失败模式。用户浏览器不支持 WebGPU 时,loadModel 会失败还是静默走慢速路径,文档没有交代。对于面向公众的网站,这意味着要么做能力检测并给出降级提示,要么接受一部分用户完全用不了。
内存是第二个约束。清单里最大的模型是 Qwen3-8B 和 DeepSeek-R1-Distill-Llama-8B,即便按较低位宽量化,权重也要占用可观的显存或内存,而浏览器标签页的资源上限由浏览器决定,不受开发者控制。移动端尤其如此。README 提到 Web Worker 支持,用于避免阻塞 UI,但 Web Worker 解决的是主线程卡顿,不解决内存上限。把 8B 模型放进浏览器标签页是否可行,取决于设备,这一点文档没有给出指导。
和直接使用 transformers.js 的差别在哪
浏览器内推理最常见的替代方案是 transformers.js。两者的差别不在模型能力,而在封装层次。transformers.js 提供的是管道抽象,pipeline('text-generation', model) 之后拿到生成器,模型标识通常指向 Hugging Face 上的仓库,加载、分词、解码由库处理,模型选择面基本等于 Hub 上可转换的模型集合。
BrowserAI 走的是另一条路。它不追求模型覆盖面,而是预先挑选并优化一批模型,用引擎标签把它们组织起来,再用统一的 loadModel 和 generateText 暴露出去。代价是灵活性,收益是一致性:同一个 generateText 调用在 MLC、Transformers 和 Flare 三条路径上写法相同,切换引擎只需要改模型名。如果你的应用需要在不同设备上尝试不同引擎以找到最优解,这个抽象是有用的。
Demucs 和 Kokoro 的存在也说明定位差异。transformers.js 主要面向文本和视觉模型,BrowserAI 把语音识别、语音合成和音源分离一并纳入同一个 SDK,这对做音频类 Web 应用的人省事。反过来说,如果你的需求纯粹是文本生成,而且你想用 Hub 上任意一个已转换模型,transformers.js 的模型自由度更高,BrowserAI 的清单会成为阻碍。
版本节奏、许可与维护成本
从发布记录看,v2.0.2 在 2025 年 4 月,v2.0.4 在 2025 年 5 月,v2.2.0 在 2026 年 4 月。中间隔了将近一年才出一个次版本,这个节奏说明项目不是高频迭代型。仓库最后推送时间在 2026 年 7 月,未归档,说明仍在维护,但主要版本之间跨度较大。
对使用方来说,这意味着两件事。一是升级时可能面对较大的跨度,v2.0.x 到 v2.2.0 之间是否有破坏性变更,需要查 release notes,本文无法从给定材料确认。二是依赖的引擎本身在演进,MLC 和 transformers.js 的上游更新不跟随 BrowserAI 的版本节奏,锁版本时要留意间接依赖。
许可方面,仓库标注 MIT。这个许可允许商用、修改和再分发,通常只需保留版权声明。但模型权重有各自的许可,BrowserAI 的 MIT 只覆盖库代码,不覆盖它下载的 llama、gemma、qwen 等模型。Llama 系列和 Gemma 系列都有独立的使用条款,商用前需要逐个核对对应模型的许可,这一点与库本身的开源许可无关。
编辑结论
如果你要在网页里做本地推理,且需求落在 BrowserAI 已预置的模型清单内,比如 llama-3.2-1b-instruct、whisper-tiny-en、kokoro-tts 或 htdemucs,这个库能省掉引擎适配层的重复工作,MIT 许可也允许直接嵌入闭源产品。如果你的目标模型不在清单里,或者你需要自选量化档位、需要控制权重下载源,那么应该先把 loadModel 的模型解析逻辑读一遍,确认它能否指向你自己的模型文件;不能的话,直接基于 MLC 或 transformers.js 自建反而更短。上线前必须验证的第一件事是目标浏览器是否提供 WebGPU,第二件事是首次加载的权重体积是否落在你能接受的范围,因为 README 只给了离线可用的说法,没有给出体积数字。
社区笔记