Skip to content

文本转语音工作原理深度解析

理解文本转语音(TTS)的内部工作机制,对于选择合适的解决方案和优化应用效果至关重要。本文将深入剖析现代 TTS 系统的技术架构和核心算法。

TTS 系统架构概览

现代文本转语音系统通常由以下几个核心模块组成:

输入文本 → 文本分析 → 声学模型 → 声码器 → 音频输出

1. 文本分析模块

文本分析是 TTS 系统的第一步,负责将原始文本转换为机器可理解的语言学特征。

文本标准化

python
# 文本预处理示例
def normalize_text(text):
    # 数字转文字
    text = convert_numbers(text)  # "123" → "一百二十三"
    
    # 缩写展开
    text = expand_abbreviations(text)  # "Dr." → "Doctor"
    
    # 标点符号处理
    text = handle_punctuation(text)
    
    # 特殊符号转换
    text = convert_special_symbols(text)
    
    return text

分词与词性标注

python
import jieba
import jieba.posseg as pseg

def analyze_text(text):
    # 分词
    words = jieba.cut(text)
    
    # 词性标注
    words_with_pos = pseg.cut(text)
    
    # 提取语言学特征
    features = []
    for word, pos in words_with_pos:
        features.append({
            'word': word,
            'pos': pos,
            'syllables': count_syllables(word)
        })
    
    return features

# 示例输出
text = "今天天气真好"
result = analyze_text(text)
# [{'word': '今天', 'pos': 't', 'syllables': 2},
#  {'word': '天气', 'pos': 'n', 'syllables': 2},
#  {'word': '真', 'pos': 'd', 'syllables': 1},
#  {'word': '好', 'pos': 'a', 'syllables': 1}]

音素转换

音素(Phoneme)是语音的最小单位。TTS 系统需要将文本转换为音素序列。

python
# 中文音素转换示例
def text_to_phonemes(text):
    phoneme_map = {
        '你好': ['n', 'i', 'h', 'ao'],
        '世界': ['sh', 'i', 'j', 'ie'],
        '今天': ['j', 'in', 't', 'ian']
    }
    
    phonemes = []
    for word in text.split():
        if word in phoneme_map:
            phonemes.extend(phoneme_map[word])
        else:
            # 使用规则或字典转换
            phonemes.extend(rule_based_conversion(word))
    
    return phonemes

2. 声学模型

声学模型负责将语言学特征转换为声学特征,这是 TTS 系统的核心。

传统方法:拼接合成

早期的 TTS 系统使用拼接合成方法:

  1. 录制大量语音片段 - 建立语音数据库
  2. 选择合适的片段 - 根据文本选择最佳匹配
  3. 拼接和调整 - 将片段拼接成完整句子

缺点:

  • 语音库建设成本高
  • 自然度受限
  • 灵活性差

统计参数合成

使用统计模型(如 HMM)生成语音参数:

音素序列 → HMM模型 → 声学参数(频谱、F0) → 声码器 → 语音

优点:

  • 灵活性好
  • 可调节性强
  • 语音库需求小

缺点:

  • 音质一般
  • 机械感较强

神经网络合成(现代主流)

深度学习彻底改变了 TTS 技术。

Tacotron 2 架构
文本 → Encoder → Attention → Decoder → Mel频谱图 → WaveNet → 音频
python
# Tacotron 2 简化示意
class Tacotron2(nn.Module):
    def __init__(self):
        self.encoder = TextEncoder()
        self.decoder = MelDecoder()
        self.postnet = PostProcessingNet()
    
    def forward(self, text):
        # 编码文本
        encoder_outputs = self.encoder(text)
        
        # 解码为梅尔频谱图
        mel_outputs, attention = self.decoder(encoder_outputs)
        
        # 后处理
        mel_outputs = self.postnet(mel_outputs)
        
        return mel_outputs

class TextEncoder(nn.Module):
    def forward(self, text):
        # 字符嵌入
        embeddings = self.character_embedding(text)
        
        # 卷积层
        conv_outputs = self.conv_layers(embeddings)
        
        # 双向 LSTM
        encoder_outputs = self.bi_lstm(conv_outputs)
        
        return encoder_outputs
FastSpeech 2(非自回归)

解决了 Tacotron 接理速度慢的问题:

文本 → Encoder → Duration Predictor → Length Regulator → Mel Decoder → 音频

优点:

  • 推理速度快(并行生成)
  • 音质优秀
  • 易于控制
VITS(端到端)

单阶段生成,无需声码器:

python
class VITS(nn.Module):
    def __init__(self):
        self.text_encoder = TextEncoder()
        self.flow = FlowModule()
        self.decoder = Decoder()
    
    def forward(self, text):
        # 文本编码
        text_features = self.text_encoder(text)
        
        # 隐变量生成
        latent = self.flow(text_features)
        
        # 直接生成音频波形
        audio = self.decoder(latent)
        
        return audio

3. 声码器(Vocoder)

声码器将声学特征(梅尔频谱图)转换为可听的音频波形。

Griffin-Lim 算法

经典快速方法:

python
def griffin_lim(mel_spectrogram, iterations=60):
    # 梅尔频谱图转换为线性频谱图
    linear_spec = mel_to_linear(mel_spectrogram)
    
    # 重建相位
    for i in range(iterations):
        # 估计波形
        waveform = spectrogram_to_waveform(linear_spec)
        
        # 重新计算频谱图
        estimated_spec = waveform_to_spectrogram(waveform)
        
        # 更新幅度
        linear_spec = np.abs(estimated_spec)
    
    return waveform

优点:

  • 速度快
  • 无需训练

缺点:

  • 音质较差
  • 需要多次迭代

WaveNet

Google DeepMind 开发的高质量声码器:

python
class WaveNet(nn.Module):
    def __init__(self):
        self.dilated_convs = DilatedConvStack()
        self.residual_blocks = ResidualBlocks()
    
    def forward(self, mel_spectrogram):
        # 上采样梅尔频谱图
        upsampled_mel = self.upsample(mel_spectrogram)
        
        # 逐样本生成
        waveform = []
        for t in range(target_length):
            # 条件化生成
            sample = self.generate_sample(waveform, upsampled_mel[t])
            waveform.append(sample)
        
        return waveform

优点:

  • 音质极佳
  • 接近真人

缺点:

  • 推理速度极慢
  • 计算资源消耗大

HiFi-GAN

现代高质量快速声码器:

python
class HiFiGAN(nn.Module):
    def __init__(self):
        self.generator = Generator()
        self.discriminators = MultiScaleDiscriminator()
    
    def forward(self, mel_spectrogram):
        # 多尺度上采样
        waveform = self.generator(mel_spectrogram)
        
        return waveform

class Generator(nn.Module):
    def forward(self, mel):
        # 上采样网络
        x = self.conv_pre(mel)
        
        for upsample in self.ups:
            x = upsample(x)
            x = self.residual_blocks(x)
        
        x = self.conv_post(x)
        waveform = torch.tanh(x)
        
        return waveform

优点:

  • 音质优秀
  • 推理速度快
  • 实时生成

梅尔频谱图详解

梅尔频谱图是连接文本和语音的关键中间表示。

什么是梅尔频谱图?

梅尔频谱图基于梅尔尺度(Mel Scale),更符合人类听觉感知:

python
def mel_scale(frequency):
    # 梅尔频率转换公式
    mel = 2595 * np.log10(1 + frequency / 700)
    return mel

def inverse_mel_scale(mel):
    # 逆梅尔频率转换
    frequency = 700 * (10 ** (mel / 2595) - 1)
    return frequency

生成梅尔频谱图

python
import librosa

def create_mel_spectrogram(audio, sr=22050):
    # 短时傅里叶变换
    stft = librosa.stft(audio)
    
    # 功率谱
    power_spec = np.abs(stft) ** 2
    
    # 梅尔滤波器组
    mel_filterbank = librosa.filters.mel(sr=sr, n_fft=2048, n_mels=80)
    
    # 梅尔频谱图
    mel_spec = mel_filterbank @ power_spec
    
    # 对数尺度
    log_mel_spec = np.log(mel_spec + 1e-10)
    
    return log_mel_spec

F0(基频)预测

F0 代表语音的基频,决定了音调高低。

python
def extract_f0(audio, sr=22050):
    # 使用 PYIN 算法提取 F0
    f0, voiced_flags, voiced_probs = librosa.pyin(
        audio,
        fmin=librosa.note_to_hz('C2'),
        fmax=librosa.note_to_hz('C7'),
        sr=sr
    )
    
    return f0, voiced_flags

# F0 特征处理
def process_f0(f0):
    # 插值处理
    f0_interpolated = interpolate_f0(f0)
    
    # 对数转换
    log_f0 = np.log(f0_interpolated)
    
    # 标准化
    normalized_f0 = (log_f0 - mean_f0) / std_f0
    
    return normalized_f0

注意力机制

注意力机制让模型知道何时关注文本的哪个部分。

位置敏感注意力

python
class LocationSensitiveAttention(nn.Module):
    def __init__(self):
        self.location_conv = Conv1d()
        self.location_layer = Linear()
        self.query_layer = Linear()
        self.memory_layer = Linear()
    
    def forward(self, query, memory, attention_prev):
        # 计算能量
        energy = self.query_layer(query) + self.memory_layer(memory)
        
        # 位置特征
        location_features = self.location_conv(attention_prev)
        energy += self.location_layer(location_features)
        
        # 注意力权重
        attention_weights = torch.softmax(energy, dim=-1)
        
        # 上下文向量
        context = torch.bmm(attention_weights, memory)
        
        return context, attention_weights

多说话人建模

现代 TTS 可以生成不同说话人的声音。

说话人嵌入

python
class SpeakerEmbedding(nn.Module):
    def __init__(self, num_speakers=100, embedding_dim=128):
        self.embedding = nn.Embedding(num_speakers, embedding_dim)
    
    def forward(self, speaker_id):
        # 获取说话人嵌入向量
        speaker_embedding = self.embedding(speaker_id)
        
        return speaker_embedding

# 在声学模型中使用
class MultiSpeakerTTS(nn.Module):
    def __init__(self):
        self.text_encoder = TextEncoder()
        self.speaker_embedding = SpeakerEmbedding()
        self.decoder = Decoder()
    
    def forward(self, text, speaker_id):
        # 文本编码
        text_features = self.text_encoder(text)
        
        # 说话人特征
        speaker_features = self.speaker_embedding(speaker_id)
        
        # 结合说话人特征
        combined_features = text_features + speaker_features
        
        # 解码
        mel_outputs = self.decoder(combined_features)
        
        return mel_outputs

技术演进对比

技术时代代表方法音质灵活性训练成本推理速度
传统拼接Unit Selection⭐⭐⭐极高
统计参数HMM⭐⭐
早期神经Tacotron 2 + WaveNet⭐⭐⭐⭐⭐极慢
现代神经VITS / HiFi-GAN⭐⭐⭐⭐⭐最高

实际应用中的技术选型

高质量应用

推荐:VITS + HiFi-GAN

  • 音质接近真人
  • 支持多说话人
  • 推理速度快

低延迟应用

推荐:FastSpeech 2 + HiFi-GAN

  • 并行生成
  • 实时流式输出
  • 易于控制语速

快速原型

推荐:Web Speech API

  • 无需训练
  • 浏览器原生支持
  • 开发成本低

总结

现代 TTS 系统采用深度学习技术,通过以下流程实现高质量语音合成:

  1. 文本分析 → 提取语言学特征
  2. 声学模型 → 生成梅尔频谱图和F0
  3. 声码器 → 生成最终音频波形

理解这些技术原理,有助于:

  • 选择合适的 TTS 解决方案
  • 优化语音合成效果
  • 自定义语音特征
  • 解决技术问题

随着技术不断发展,TTS 系统的音质、速度和灵活性都在不断提升,为各行各业提供了强大的语音合成能力。


发布于 2025-06-28

基于 VitePress 构建