过去想在网页里做语音转文字,通常只能调用云端API:把音频上传到服务器,跑一遍识别再返回结果。这种方案不仅带来网络延迟和服务器成本,还涉及用户语音数据的隐私问题。而OpenAI开源的Whisper模型改变了这个局面,配合WebAssembly和Transformers.js,如今可以直接在浏览器里完成语音识别,全程数据不出本机。本文将围绕这条纯前端技术路线,从环境搭建、代码实现到性能优化逐一展开。

浏览器端运行Whisper的技术原理
要在浏览器里跑一个神经网络,核心障碍是浏览器没有原生的深度学习运行时。WebAssembly(简称Wasm)解决了这个问题:它是一种可移植的字节码格式,C++、Rust等语言编译成Wasm后可以在浏览器中以接近原生的速度执行。ONNX Runtime Web正是把ONNX推理引擎编译成了Wasm模块,让浏览器具备了加载和执行ONNX格式模型的能力。
Transformers.js则是Hugging Face在ONNX Runtime Web之上封装的JS库,它复刻了Python版transformers的API设计。Whisper模型在发布时是PyTorch权重,需要先转换成ONNX格式并通过量化压缩,才能被浏览器高效加载。整个调用链可以概括为:网页中的JS代码调用Transformers.js,Transformers.js调度Wasm版的ONNX Runtime执行算子,最终在WebAssembly线性内存中完成前向推理。
值得一提的是,较新版本的Transformers.js还支持WebGPU后端。WebGPU允许网页直接访问设备的GPU算力,推理速度通常比纯Wasm快好几倍,对于Whisper这种参数量较大的模型尤其重要。浏览器不支持WebGPU时会自动回退到Wasm模式,兼容性有保障。
环境搭建与基础代码实现
Transformers.js可以通过npm安装,也可以直接用CDN引入。为了便于演示,这里采用原生HTML页面加ES Module的方式,不需要任何构建工具。npm项目中执行npm install @huggingface/transformers即可,CDN方式则在脚本标签中引入jsDelivr或unpkg上的ESM入口。
下面的代码演示了最基础的用法:加载Whisper语音识别流水线,并对一段音频文件进行转写。注意首次运行时模型会从Hugging Face Hub下载并缓存在浏览器的Cache Storage中,之后再次访问就不用重复下载了。
import { pipeline } from 'https://cdn.jsdelivr.net/npm/@huggingface/transformers';
// 创建语音识别流水线,model_id指定量化版本
const transcriber = await pipeline(
'automatic-speech-recognition',
'onnx-community/whisper-base',
{ dtype: 'q8' } // 8bit量化,体积更小
);
// audio是16kHz采样的Float32Array
const output = await transcriber(audio);
console.log(output.text);
这里有一个关键细节:Whisper要求输入音频为16kHz采样率的单声道数据。浏览器原生解码API返回的往往是44.1kHz或48kHz,因此需要用AudioContext配合重采样处理。实践中常用的做法是创建一个sampleRate为16000的AudioContext,让浏览器在解码时自动完成重采样,代码如下:
async function getAudioData(file) {
const arrayBuffer = await file.arrayBuffer();
// 指定16kHz采样率,解码时自动重采样
const audioCtx = new AudioContext({ sampleRate: 16000 });
const decoded = await audioCtx.decodeAudioData(arrayBuffer);
// 取第一个声道,转换为普通数组
return Array.from(decoded.getChannelData(0));
}
处理好音频数据后,把它传入流水线即可得到转写文本。如果要识别中文,可以在调用时传入language: 'chinese'和task: 'transcribe'参数,避免模型自动检测语言带来的额外耗时。
性能优化与实时转写方案
模型选择是性能优化的第一环。Whisper有tiny、base、small、medium等多个规格,浏览器场景下推荐tiny或base:tiny量化后只有几十MB,base大约100MB出头,而medium超过400MB,首次加载体验会很差。在准确率和加载速度之间,base通常是比较均衡的选择。
多线程是第二个优化点。Wasm默认单线程执行,而ONNX Runtime Web支持跨线程编译,需要服务器配置特定的HTTP响应头(Cross-Origin-Embedder-Policy和Cross-Origin-Opener-Policy)来启用SharedArrayBuffer。开启多线程后,CPU利用率明显提升,推理时间可以缩短一半左右。
实时转写则需要设计滑窗逻辑:通过getUserMedia获取麦克风权限,用Web Audio API的ScriptProcessorNode或AudioWorklet持续采集音频片段,每积累一定长度(比如几秒)就截取出来送入模型推理,把结果按顺序拼接。为了减少重复计算,相邻窗口可以保留一段重叠区域,配合返回的时间戳做去重合并。另外要记住Whisper对30秒以上的输入处理效率较差,控制窗口长度很有必要。
浏览器端方案的适用边界
纯前端语音识别最大的价值在于隐私和成本:语音数据全程留在本地,服务器零GPU开销,断网也能用。适合会议纪要本地化处理、语音笔记、隐私敏感的录音转写等场景。
它的局限同样明显:首次加载需要下载几十到上百MB的模型,移动端流量环境下体验不佳;推理速度受设备性能制约,低端手机上实时性难以保证;长音频的转写耗时远高于服务端GPU方案。因此在选型时,如果业务对准确率要求极高或需要批量处理大量长音频,服务端部署仍然是更好的选择;而对于注重隐私、音频片段较短的应用,浏览器端Whisper是非常值得采用的方案,两者结合使用往往能取得最佳平衡。
WhisperWebAssemblyTransformers.js修改时间:2026-09-01 05:28:39