多模态语音合成与识别:从 Whisper + TTS 到实时语音交互的 LLM 实践

系统拆解 LLM 语音技术栈:语音识别(ASR / Whisper)、语音合成(TTS / ElevenLabs / Coqui TTS)、语音活动检测(VAD)。 覆盖实时语音交互架构(流式识别 + 流式合成 + 打断机制)、多语言语音克隆、以及语音 Agent 的安全与隐私考量。 附完整的 Whisper API 集成、本地 TTS 部署、WebRTC 实时语音管道代码。

前置:了解基础 LLM API 调用(LLM API 基础指南)。


1. 语音技术栈全景

用户语音输入
    │
    ▼
┌─────────────────┐
│  VAD 检测       │  ← 检测说话开始/结束
└─────────────────┘
    │
    ▼
┌─────────────────┐
│  ASR (Whisper)  │  ← 语音 → 文本
└─────────────────┘
    │
    ▼
┌─────────────────┐
│  LLM 文本推理   │  ← 文本 → 文本回答
└─────────────────┘
    │
    ▼
┌─────────────────┐
│  TTS 合成       │  ← 文本 → 语音
└─────────────────┘
    │
    ▼
  语音输出

2. 语音信号处理基础

理解语音 AI 之前,先掌握数字音频的基本概念。音频是连续的模拟声波,需要经过采样和量化才能被计算机处理。

音频特征参数:

参数典型值说明
采样率16kHz / 22.05kHz / 44.1kHz每秒采样次数。人语音主要频率在 8kHz 内,16kHz 满足奈奎斯特定理
位深度16-bit / 24-bit / 32-bit float量化精度。16-bit 是 ASR/TTS 的标准
声道单声道 (mono) / 立体声 (stereo)ASR 通常使用单声道,减少计算量
格式WAV / MP3 / FLAC / WebMWAV 无损原始格式,MP3 有损压缩省空间

特征提取:梅尔频谱(Mel Spectrogram):

人类对不同频率的感知是非线性的——对低频更敏感,对高频相对不敏感。**梅尔尺度(Mel Scale)**模拟人耳感知,将线性频率映射到感知尺度。

import librosa
import numpy as np

# 加载音频
audio, sr = librosa.load("speech.wav", sr=16000)  # 16kHz

# 计算梅尔频谱
mel_spec = librosa.feature.melspectrogram(
    y=audio,
    sr=sr,
    n_mels=80,           # 梅尔滤波器数量
    n_fft=400,           # FFT 窗口大小(25ms @ 16kHz)
    hop_length=160,      # 帧移(10ms)
    f_min=0, f_max=8000  # 频率范围
)

# 转换为对数尺度(更符合人耳感知)
log_mel_spec = librosa.power_to_db(mel_spec, ref=np.max)

# 输出 shape: (80, T)
# 80 个梅尔频段,T 个时间帧
原始波形 → 预加重 → 分帧 → 加窗 → FFT → 梅尔滤波器组 → 对数 → 梅尔频谱

┌──────────┐    ┌──────────┐    ┌──────────┐
│ 原始波形  │──→│ 25ms 窗口 │──→│ FFT(512) │──→ 梅尔滤波(80) ──→ 对数压缩
│  16kHz   │    │ 10ms 帧移 │    └──────────┘          ↓
└──────────┘    └──────────┘                    Mel Spectrogram (80×T)

Mel Spectrogram 是连接原始音频和深度学习模型的桥梁。Whisper 等 ASR 模型直接输入 Mel Spectrogram,而非原始 PCM 波形。

语音活动检测(VAD)前置处理:

VAD 用于区分音频中的语音段和静音段,是实时语音交互的第一步:

import webrtcvad

# WebRTC VAD(Google 开源,轻量 CPU 实现)
vad = webrtcvad.Vad(3)  # 灵敏度 0-3(3 最严格)

# 将音频分帧检测
frame_duration = 30  # 支持 10/20/30ms
is_speech = vad.is_speech(frame_bytes, sample_rate=16000)

# 更现代的 Silero VAD(基于 PyTorch,精度更高)
import torch
model, utils = torch.hub.load(repo_or_dir='snakers4/silero-vad',
                              model='silero_vad',
                              force_reload=True)
(get_speech_timestamps,
 save_audio,
 read_audio,
 VADIterator,
 collect_chunks) = utils

wav = read_audio('long_audio.wav', sampling_rate=16000)
speech_timestamps = get_speech_timestamps(wav, model, sampling_rate=16000)
# 输出: [{'start': 0.52, 'end': 3.41}, {'start': 5.12, 'end': 8.90}, ...]
VAD 方案延迟精度CPU 开销适用场景
WebRTC VAD10-30ms中等极低移动端、实时通话
Silero VAD30-100ms高低服务器端 ASR 预处理
能量阈值实时低无实验室环境、非噪声场景

3. 语音识别(ASR):Whisper 体系

3.1 模型架构:Encoder-Decoder Transformer

OpenAI Whisper(2022 年发布)采用经典的 Sequence-to-Sequence Transformer 架构:

音频输入 (Mel Spectrogram)     文本输出 (Token 序列)
        │                               ▲
        ▼                               │
┌───────────────┐              ┌───────────────┐
│ Audio Encoder │              │ Text Decoder  │
│  (卷积+Transformer│  ────────→│  (Masked    │
│   自注意力)     │   交叉注意力  │   Transformer)│
└───────────────┘              └───────────────┘
        │                               │
        ▼                               ▼
    80 × 3000                     "<|startoftranscript|>"
     (频谱维度)                     "<|zh|>"
                                    "你好世界"
                                    "<|endoftext|>"

关键设计:
  1. Encoder 将 30 秒音频 → 1500 个 audio token
  2. Decoder 自回归生成文本 token
  3. 支持多语言(99 种语言的多任务训练)
  4. 训练数据:68 万小时标注音频(迄今最大 ASR 训练集)

Whisper 的优越性来自大规模多语言多任务预训练:

  • 多语言:同一模型可识别 99 种语言,通过特殊 token |<lang>| 指定目标语言
  • 多任务:支持语音识别(transcribe)、语音翻译(translate to English)、语言识别(detect)
  • 鲁棒性:在噪声、口音、填充词(嗯、啊)等场景下表现稳定
  • 零样本能力:未在特定领域训练,也能识别专业术语

3.2 OpenAI Whisper API

from openai import OpenAI
client = OpenAI()

audio_file = open("speech.mp3", "rb")
transcript = client.audio.transcriptions.create(
    model="whisper-1",
    file=audio_file,
    language="zh",  # 指定语言提升准确率
    response_format="verbose_json",  # 含时间戳
    timestamp_granularities=["word"],  # 词级时间戳
)
print(transcript.text)

3.3 本地 Whisper( faster-whisper )

pip install faster-whisper
from faster_whisper import WhisperModel

model = WhisperModel("large-v3", device="cuda", compute_type="float16")

segments, info = model.transcribe("audio.mp3", beam_size=5, language="zh")

print(f"检测到语言: {info.language}, 概率: {info.language_probability:.2f}")

for segment in segments:
    print(f"[{segment.start:.2f} → {segment.end:.2f}] {segment.text}")
模型大小实时因子 (RTF)中文准确率适用场景
tiny39MB0.0570%低功耗设备
base74MB0.180%实时移动端
small244MB0.385%边缘计算
medium769MB0.890%服务器
large-v31550MB2.095%高精度离线

4. 语音合成(TTS)技术演进

4.1 OpenAI TTS API

response = client.audio.speech.create(
    model="tts-1",
    voice="alloy",  # alloy, echo, fable, onyx, nova, shimmer
    input="欢迎来到 Birdor,您的 AI 助手已准备就绪。",
    speed=1.0,
)

response.stream_to_file("output.mp3")

4.2 ElevenLabs(最佳质量)

from elevenlabs import generate, play, set_api_key

set_api_key("YOUR_KEY")

audio = generate(
    text="这是一段高质量的语音合成演示。",
    voice="Bella",  # 或自定义克隆声音
    model="eleven_multilingual_v2",
)

play(audio)

4.3 Coqui TTS(开源本地运行)

pip install TTS
from TTS.api import TTS

# 加载多语言模型
tts = TTS("tts_models/multilingual/multi-dataset/xtts_v2")

# 克隆声音(用 6 秒参考音频)
tts.tts_to_file(
    text="你好,这是用你的声音合成的中文语音。",
    speaker_wav="reference_voice.wav",
    language="zh",
    file_path="cloned_output.wav",
)

5. 实时语音交互架构

5.1 核心组件

import asyncio
import numpy as np
import torch

class RealtimeVoiceAgent:
    def __init__(self):
        self.vad = VADModel()          # 语音活动检测
        self.asr = WhisperModel("base")  # 语音识别
        self.llm = OpenAIClient()      # 大语言模型
        self.tts = TTSClient()         # 语音合成
        self.is_speaking = False       # Agent 是否在说话
        self.user_interrupt = False    # 用户是否打断

    async def audio_stream_loop(self):
        """持续监听音频输入"""
        audio_buffer = []

        async for chunk in microphone_stream():
            # VAD 检测
            speech_prob = self.vad(chunk)

            if speech_prob > 0.5:
                audio_buffer.append(chunk)
            elif audio_buffer:
                # 用户说完一句,开始处理
                await self.process_utterance(audio_buffer)
                audio_buffer = []

    async def process_utterance(self, audio_chunks):
        # 1. ASR
        text = self.asr.transcribe(np.concatenate(audio_chunks))

        # 2. 如果 Agent 正在说话,先中断
        if self.is_speaking:
            self.user_interrupt = True
            await self.tts.stop()

        # 3. LLM 推理
        response_text = await self.llm.chat(text)

        # 4. TTS 合成(流式)
        self.is_speaking = True
        await self.tts.speak_streaming(response_text)
        self.is_speaking = False

4.2 WebRTC 实时音频管道

# 使用 aiortc 实现浏览器 ↔ 服务器的实时音频通信
from aiortc import RTCPeerConnection, MediaStreamTrack
from aiortc.contrib.media import MediaPlayer, MediaRecorder

class AudioTrack(MediaStreamTrack):
    kind = "audio"

    async def recv(self):
        frame = await self.track.recv()
        # 将音频帧送入 VAD/ASR 管道
        audio_data = frame.to_ndarray()
        await process_audio_chunk(audio_data)
        return frame

# 前端使用 Web Audio API + getUserMedia
# 音频通过 WebRTC 传输到 Python 服务端

5. 语音克隆(Voice Cloning)

5.1 XTTS v2 本地克隆

from TTS.api import TTS

tts = TTS("tts_models/multilingual/multi-dataset/xtts_v2")

# 只需 6 秒参考音频即可克隆
tts.tts_to_file(
    text="这是用克隆声音说出的中文句子。",
    speaker_wav="my_voice_6s.wav",
    language="zh",
    file_path="cloned.wav",
)

5.2 语音克隆的伦理边界

⚠️ 安全红线
├── 绝不克隆未授权人员的声音
├── 明确标注 AI 合成语音
├── 金融场景禁用语音克隆(防诈骗)
├── 提供声音水印 / 检测接口
└── 保留合成日志用于追溯

6. 成本估算

组件API 成本本地成本实时延迟
ASR (Whisper API)$0.006/分钟GPU $0.02/小时1-3s
TTS (OpenAI)$0.015/1K字符CPU 免费<1s
TTS (ElevenLabs)$0.18/1K字符不支持<1s
VAD免费(silero)CPU 免费50ms

实时语音会话成本(10 分钟):

  • ASR: $0.06
  • LLM: ~$0.10(假设 2K token 往返)
  • TTS: ~$0.03
  • 总计: ~$0.19 / 10 分钟

7. 总结与选型

场景ASRTTS架构建议
客服机器人Whisper APIOpenAI TTS流式 ASR → LLM → 流式 TTS
播客生成Whisper + 校对ElevenLabs批量处理,人工校对
语音助手(设备端)Whisper tinyPicoTTS本地运行,低延迟
多语言翻译Whisper largeXTTS v2ASR → LLM翻译 → TTS 目标语言
有声读物WhisperCoqui TTS批量,低成本

📂 继续阅读:


8. 语音质量评估与调优

8.1 客观评估指标

语音合成质量的客观评估帮助开发者在迭代中量化改进:

指标全称计算方法目标
MCDMel Cepstral Distortion比较合成与参考音频的梅尔倒谱距离< 6 dB
F0 RMSE基频均方根误差合成与参考音高曲线的差异< 10 Hz
UTMOS基于深度学习的 MOS用神经网络预测人类听感评分> 3.5
WER词错误率ASR 转写合成音频与原文本比对< 5%

UTMOS 快速评估:

# 使用 Hugging Face 上的 UTMOS 模型
from transformers import pipeline

utmos = pipeline("audio-classification", model="speechbrain/UTMOS-strong-563M")
score = utmos("synthetic_audio.wav")
print(f"Predicted MOS: {score[0]['score']}")  # 0-5 分

8.2 主观听感调优技巧

客观指标与主观听感有时不一致。实际调优中需要关注:

中文 TTS 的特殊挑战:

  • 多音字:如 “银行” vs “行走”,“重庆” vs “重复” —— 需要文本前端正确的 G2P(Grapheme-to-Phoneme)
  • 数字读法:“2024年” → “二〇二四年” vs “两千零二十四年”,“13800138000” → 电话号码读法
  • 停顿:逗号、句号、分号的停顿长度应有所区别
  • 语气词:“啊”、“呢”、“吧” 在不同语境下的语调变化

解决方案:

  • 使用支持中文 SSML(语音合成标记语言)的引擎
  • 对 G2P 进行领域定制(金融、医疗、地理名词)
  • 人工标注高频场景的韵律数据,微调模型

9. 生产部署与运维

9.1 语音服务架构模式

单体部署模式:
  ┌──────────────┐
  │  GPU 服务器   │
  │  ├─ Whisper   │
  │  ├─ XTTS v2   │
  │  └─ VAD       │
  └──────────────┘
  适合:初期验证、用户量小

微服务拆分模式(推荐):
  ┌──────────┐    ┌──────────┐    ┌──────────┐
  │ ASR 服务  │    │ LLM 服务  │    │ TTS 服务  │
  │ (GPU×2)  │←──→│ (GPU×4)  │←──→│ (GPU×2)  │
  └──────────┘    └──────────┘    └──────────┘
       ↑              ↑              ↑
       └──────────────┼──────────────┘
                      ↓
               ┌──────────┐
               │ API 网关  │
               │ 负载均衡  │
               └──────────┘
  优势:独立扩缩容、故障隔离、多模型 A/B 测试

性能参考(单 A100 GPU):
  - ASR (Whisper Large-v3): ~10x 实时(10 秒音频/秒)
  - TTS (XTTS v2): ~50x 实时
  - VAD (Silero): ~500x 实时

9.2 部署注意事项

  • GPU 显存:Whisper Large-v3 FP16 约需 6GB;TTS 模型如 VITS 约需 2GB。单卡 24GB(RTX 4090/A100 40GB)可并行运行多个模型。
  • 模型预热:首次推理需要加载模型到显存,延迟较高。生产环境应在服务启动时预热,并设置 readiness probe。
  • 批处理 vs 流式:ASR 批处理吞吐量更高,流式延迟更低(适合实时通话)。TTS 流式(chunk-based)可以边合成边播放。
  • 缓存策略:相同文本的 TTS 结果可缓存(Redis),避免重复合成。开播客、通知类场景缓存命中率极高。

10. 安全与合规

除了语音克隆的伦理问题,语音 AI 还面临以下安全挑战:

风险描述防护
音频注入攻击者通过麦克风注入恶意指令声纹认证 + 唤醒词 + 意图校验
音频 deepfake 检测合成语音冒充真人部署 AI 检测模型(如 AudioShield)
数据隐私语音数据包含生物特征信息端到端加密存储、本地处理优先
内容过滤TTS 合成有害内容输入文本敏感词过滤 + 输出音频审查

语音水印技术:在合成音频中嵌入不可听的水印信息,用于溯源和版权保护:

# 简单示例:使用模型库嵌入水印
from wavmark import WatermarkEncoder, WatermarkDecoder

encoder = WatermarkEncoder()
audio, sr = librosa.load("synthetic.wav", sr=16000)
watermarked = encoder.encode(audio, message="copyright_birdor_2025")

# 解码验证
decoder = WatermarkDecoder()
msg = decoder.decode(watermarked)
print(f"Watermark: {msg}")

继续阅读

探索更多技术文章

浏览归档,发现更多关于系统设计、工具链和工程实践的内容。

全部文章 返回首页

「llm」更多文章

  1. AI Agent 产品设计方法论:从交互范式到产品落地的完整框架
  2. 大模型本地部署与私有托管:从 Ollama 到 vLLM 生产级推理集群
  3. LLM 商业化应用开发与产品化方法论:从价值验证到规模化盈利