前置:了解基础 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 / WebM | WAV 无损原始格式,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 VAD | 10-30ms | 中等 | 极低 | 移动端、实时通话 |
| Silero VAD | 30-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) | 中文准确率 | 适用场景 |
|---|---|---|---|---|
| tiny | 39MB | 0.05 | 70% | 低功耗设备 |
| base | 74MB | 0.1 | 80% | 实时移动端 |
| small | 244MB | 0.3 | 85% | 边缘计算 |
| medium | 769MB | 0.8 | 90% | 服务器 |
| large-v3 | 1550MB | 2.0 | 95% | 高精度离线 |
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. 总结与选型
| 场景 | ASR | TTS | 架构建议 |
|---|---|---|---|
| 客服机器人 | Whisper API | OpenAI TTS | 流式 ASR → LLM → 流式 TTS |
| 播客生成 | Whisper + 校对 | ElevenLabs | 批量处理,人工校对 |
| 语音助手(设备端) | Whisper tiny | PicoTTS | 本地运行,低延迟 |
| 多语言翻译 | Whisper large | XTTS v2 | ASR → LLM翻译 → TTS 目标语言 |
| 有声读物 | Whisper | Coqui TTS | 批量,低成本 |
📂 继续阅读:
8. 语音质量评估与调优
8.1 客观评估指标
语音合成质量的客观评估帮助开发者在迭代中量化改进:
| 指标 | 全称 | 计算方法 | 目标 |
|---|---|---|---|
| MCD | Mel 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}")
继续阅读
探索更多技术文章
浏览归档,发现更多关于系统设计、工具链和工程实践的内容。