两种推理模式深度对比

两种推理模式深度对比

WASM 模块最有趣的设计是提供了两套推理路径,开发者可根据场景选择。

模式一:ONNX Runtime Web(混合架构)
ONNX Runtime Web
Rust WASM (G2P)
JS
ONNX Runtime Web
Rust WASM (G2P)
JS
phonemize(text)
Bopomofo 音素
tokenize + 构造 Tensor
InferenceSession.run(feeds)
PCM Float32Array
编码为 WAV
G2P 部分由 Rust WASM 完成(高效、小巧)
模型推理使用微软官方的 onnxruntime-web 库,从 CDN 加载 ort.min.js 及其 WASM 后端
发音人嵌入由 JavaScript 通过 fetch 加载后传入
适合场景:对推理稳定性和算子覆盖度要求较高的生产应用。

模式二:纯 Rust WASM + oxionnx(全栈 Rust)
Rust WASM (G2P + oxionnx)
JS
Rust WASM (G2P + oxionnx)
JS
loadModel(modelBytes)
synthesize(text, style, speed)
G2P → Tokenize → oxionnx 推理
PCM Float32Array + 音素信息
编码为 WAV
全部逻辑(G2P、推理、WAV 编码)都在 Rust WASM 内部完成
推理使用 oxionnx——一个纯 Rust 实现的 ONNX 推理库
无需加载任何外部 JavaScript 推理库,零 CDN 依赖
适合场景:离线应用、对隐私要求极高、希望最小化外部依赖的场景。

对比维度 ONNX Runtime Web oxionnx(纯 Rust)
推理库来源 微软官方 CDN 编译进 WASM
WASM 体积 ~3MB(仅 G2P) ~3MB(含推理)
额外 JS 加载 ort.min.js (~200KB) 无
算子覆盖度 广泛 核心算子(持续完善中)
优化选项 丰富(图优化、量化等) 基础
硬件加速 WebGL / WASM SIMD WASM SIMD
离线使用 需缓存 CDN 资源 完全离线可用
五、构建与 Demo:从源码到浏览器
构建 WASM 模块

安装 WASM 目标

rustup target add wasm32-unknown-unknown

安装 wasm-pack

cargo install wasm-pack

一键构建(推荐)

./scripts/build_wasm.sh

或手动构建

wasm-pack build crates/kokoros-core
–target web
–out-dir …/…/static/wasm-pkg

–features wasm
–no-default-features
构建产物位于 static/wasm-pkg/ 目录下:

static/wasm-pkg/
├── kokoros_bg.wasm # WASM 二进制 (~3MB)
├── kokoros.js # 胶水代码 (~28KB)
├── kokoros.d.ts # TypeScript 类型声明
└── package.json
Demo 页面
项目提供了三个可直接运行的演示页面,位于 static/ 目录:

wasm_demo.html — 使用 ONNX Runtime Web 后端,展示完整的 G2P + 推理流程。
browser_demo.html — 流式合成体验,更接近实时对话场景。
rust_wasm_demo.html — 纯 Rust WASM(oxionnx)后端,展示零外部依赖的全离线方案。
运行方式:

cd static
python3 -m http.server 8080

npx serve .
打开浏览器访问 http://localhost:8080/wasm_demo.html 即可体验。

六、隐私与安全:数据不出设备
这是 WASM 版本最吸引人的特性之一。对比云 TTS 方案:

传统云 TTS:
用户文本 ──(网络)──→ 云服务器 ──(网络)──→ 返回音频
文本离开用户设备,存在隐私泄露风险

kokoroi-rs WASM:
用户文本 ──(本地)──→ WASM 模块 ──(本地)──→ 播放音频
文本始终在浏览器沙箱内,永不离开用户设备
对于一些敏感场景(如医疗咨询、金融信息、个人日记等),本地 TTS 有着天然的优势。同时,由于无需网络请求,弱网环境下也能稳定工作。

七、性能与局限
性能表现
维度 数据
G2P 处理速度 < 1ms / 字符
模型加载(80MB) 首次约 1-3 秒(取决于网络)
推理实时率 约 1-2 倍实时(受 WASM 引擎限制)
内存占用 约 100-200MB
WASM 体积 ~3MB(含 G2P + oxionnx)
当前局限
单线程推理:WASM 不支持 std::thread,无法利用多核并行处理长文本分片。对于超长文本,目前的方案是整体推理,可能会造成 UI 卡顿(可通过 Web Worker 缓解)。
模型下载体积:ONNX 模型约 80MB,发音人嵌入约 150MB,首次加载需要一定时间。后续可以利用浏览器缓存或 OPFS 减少重复下载。
仅 WAV 输出:受限于 WASM 下的音频编码库支持,目前只支持 WAV 格式(PCM 16-bit)。MP3/Opus 等压缩格式暂不支持。
浏览器兼容性:需要支持 WebAssembly 和 SharedArrayBuffer(部分旧浏览器不支持)。
八、未来方向
WASM 模块的潜力远不止于此,团队已经在规划几个有意思的方向:

Web Worker 并行:利用多个 Web Worker 各加载一个 WASM 实例,实现分片并行推理,弥补单线程的不足。
OPFS 模型缓存:利用 Origin Private File System 将下载的模型持久化在本地,第二次访问时几乎秒开。
流式合成:将 Native 版本的 SSE 流式机制移植到 WASM,实现“边合成边播放”的低延迟体验。
混合模式:G2P 在本地 WASM 执行,推理通过 WebSocket 连接私有推理服务器——兼顾隐私和性能。
结语
kokoroi-rs 的 WASM 模块展示了如何将 AI 模型“搬进浏览器”——通过 Rust + WebAssembly,我们可以在不牺牲质量的前提下,让 TTS 服务脱离云端,真正属于用户自己。

对于前端开发者、隐私敏感应用以及边缘计算场景,这套方案提供了一条全新的技术路径。如果你也关注 Rust + WASM + AI 这个方向,不妨去 GitHub 仓库看一看,跑一跑 Demo,甚至参与进来一起完善。