Android 端实时语音转文字实战:基于 Whisper 的落地实践
为什么要在端侧做?
移动端实时语音识别(STT)在实际落地中往往面临三个核心痛点。首先是延迟敏感,用户期望语音输入后 200ms 内得到反馈,传统云端方案受网络抖动影响很难稳定达标;其次是资源受限,移动设备内存通常不足 4GB,而语音模型参数量常超过 100MB;最后是环境复杂,背景噪音、方言口音及设备麦克风差异都会导致识别率波动。
技术选型对比
相比传统 ASR 方案,Whisper 在离线支持和多语言处理上优势明显。虽然 Google Speech-to-Text 在中文准确率上略高(89.2% vs 86.5% WER),但 Whisper 支持完全离线运行,且 tiny 版仅 39MB,更适合端侧部署。在延迟表现上,端侧处理约 300ms,不依赖网络波动。
| 维度 | Whisper | Google Speech-to-Text |
|---|---|---|
| 离线支持 | 完全离线 | 需联网 |
| 中文准确率 | 86.5%(WER) | 89.2%(WER) |
| 模型大小 | tiny 版 39MB | 不提供离线模型 |
| 延迟表现 | 端侧处理约 300ms | 依赖网络延迟 |
| 多语言支持 | 支持 97 种语言 | 需单独配置 |
实现细节
音频流预处理
为了高效处理音频流,我们使用 MediaCodec 构建管道。首先配置 AudioRecord 参数时,采用双缓冲策略来避免数据丢失:
val bufferSize = AudioRecord.getMinBufferSize(
SAMPLE_RATE,
AudioFormat.CHANNEL_IN_MONO,
AudioFormat.ENCODING_PCM_16BIT
) * 2
接着建立环形缓冲区,确保线程安全地写入和读取数据:
class CircularBuffer(size: Int) {
private val data = ShortArray(size)
private var head = 0
private var tail = 0
fun write(samples: ShortArray) {
// 实现线程安全的环形写入逻辑
}
}
模型优化
Whisper-tiny 量化是提升性能的关键。我们采用了 TensorFlow Lite 的 int8 量化方案,移除了非必要输出头(仅保留中文相关部分),并进行了层融合以减少算子调用次数。

