MockingBird là công cụ mã nguồn mở cho phép tái tạo giọng nói người thật với độ trễ thấp, hỗ trợ đặc biệt tốt cho tiếng Trung Quốc phổ thông. Dự án tận dụng kiến trúc encoder-synthesizer-vocoder để tạo ra âm thanh tự nhiên từ đoạn văn bản đầu vào.
Triển khai môi trường
Trước tiên cần tải mã ngun và cài đặt các phụ thuộc:
git clone https://github.com/babysor/MockingBird.git
cd MockingBird
pip install -r requirements.txt
Cấu trúc bộ mã hóa (Encoder)
Bộ encoder đóng vai trò trích xuất đặc trưng âm thanh, chuyển đổi file âm thanh thành vector nhúng đại diện cho giọng nói. File triển khai chính nằm tại models/encoder/:
import torch.nn as nn
class VoiceEmbedder(nn.Module):
def __init__(self, mel_channels=40, hidden_dim=256):
super().__init__()
self.lstm_stack = nn.LSTM(
input_size=mel_channels,
hidden_size=hidden_dim,
num_layers=3,
batch_first=True
)
self.projection = nn.Linear(hidden_dim, hidden_dim)
def forward(self, mel_spectrogram):
outputs, _ = self.lstm_stack(mel_spectrogram)
# Lấy frame cuối cùng làm đại diện
embedding = self.projection(outputs[:, -1, :])
return embedding / torch.norm(embedding, dim=1, keepdim=True)
Xây dựng bộ tổng hợp (Synthesizer)
Bộ synthesizer nhận vector nhúng từ encoder và chuỗi ký tự văn bản, sau đó sinh ra mel-spectrogram tương ứng. ây là phần cốt lõi quyết định chất lượng đầu ra:
class TacotronSynthesizer(nn.Module):
def __init__(self, embed_dim=256, vocab_size=70, mel_frames=80):
super().__init__()
self.char_embed = nn.Embedding(vocab_size, embed_dim)
self.encoder_rnn = nn.LSTM(embed_dim, 256, 2, batch_first=True)
self.attention = LocationSensitiveAttention(256)
self.decoder_rnn = nn.LSTM(256 + mel_frames, 256, 2, batch_first=True)
self.mel_proj = nn.Linear(256, mel_frames)
def synthesize(self, text_indices, speaker_embed, max_steps=1000):
encoded = self.char_embed(text_indices)
encoder_out, _ = self.encoder_rnn(encoded)
mel_outputs = []
decoder_state = None
prev_mel = torch.zeros(speaker_embed.size(0), 1, 80)
for t in range(max_steps):
context = self.attention(decoder_state, encoder_out)
decoder_input = torch.cat([context, prev_mel], dim=-1)
decoder_out, decoder_state = self.decoder_rnn(decoder_input)
mel_frame = self.mel_proj(decoder_out)
mel_outputs.append(mel_frame)
prev_mel = mel_frame
# iều kiện dừng khi gặp frame im lặng
if self._is_silent(mel_frame):
break
return torch.stack(mel_outputs, dim=1)
Tích hợp Vocoder HiFi-GAN
Sau khi có mel-spectrogram, cần chuyển đổi thành sóng âm thanh tần số lấy mẫu cao. HiFi-GAN được tích hợp sẵn trong models/vocoder/hifigan/:
class HiFiGenerator(nn.Module):
def __init__(self, upsample_rates=[8,8,2,2]):
super().__init__()
self.conv_pre = nn.Conv1d(80, 128, 7, padding=3)
self.upsample_blocks = nn.ModuleList([
ResBlockUpsample(128, 256, rate)
for rate in upsample_rates
])
self.conv_post = nn.Conv1d(128, 1, 7, padding=3)
def waveform_generate(self, mel_spec):
x = self.conv_pre(mel_spec)
for upsample in self.upsample_blocks:
x = upsample(x)
return torch.tanh(self.conv_post(x))
Pipeline nhái giọng hoàn chỉnh
Kết hợp các thành phần để tạo luồng xử lý end-to-end:
class RealTimeVoiceCloner:
def __init__(self, encoder_ckpt, synth_ckpt, vocoder_ckpt):
self.embedder = VoiceEmbedder()
self.synthesizer = TacotronSynthesizer()
self.vocoder = HiFiGenerator()
self.embedder.load_state_dict(torch.load(encoder_ckpt))
self.synthesizer.load_state_dict(torch.load(synth_ckpt))
self.vocoder.load_state_dict(torch.load(vocoder_ckpt))
def clone(self, reference_audio, target_text, text_processor):
# Bước 1: Trích xuất giọng từ mẫu tham chiếu
mel_ref = audio_to_mel(reference_audio)
speaker_vec = self.embedder(mel_ref.unsqueeze(0))
# Bước 2: Mã hóa văn bản đích
text_indices = text_processor.chinese_to_sequence(target_text)
# Bước 3: Tổng hợp mel-spectrogram
mel_synth = self.synthesizer.synthesize(
text_indices, speaker_vec
)
# Bước 4: Tạo sóng âm thanh
waveform = self.vocoder.waveform_generate(mel_synth.squeeze(0))
return waveform
Tối ưu cho tiếng Trung
Để đạt chất lượng tốt nhất với tiếng Trung, cần lưu ý:
- Sử dụng bộ tokenizer phù hợp như
pypinyinhoặcg2pMđể chuyển Hán tự thành phiên âm - Điều chnh
vocab_sizetheo số lượng âm vị tiếng Trung (khoảng 400 âm vị cơ bản) - Trong file
configs/hifigan_16k.json, tăngfmaxlên 8000Hz để bắt các sắc âm cao
Xử lý sự cố thường gặp
| Hiện tượng | Nguyên nhân | Cách khắc phục |
|---|---|---|
| Âm thanh bị rè, méo tiếng | HiFi-GAN chưa hội tụ | Tăng số bước warmup, giảm learning rate |
| Giọng nói không giống mẫu | Encoder chưa tách bạch speaker | Tăng số lượng speaker trong batch |
| Ngắt quãng giữa các từ | Attention alignment kém | Kiểm tra guided attention loss |
Chạy inference nhanh
Demo command-line để kiểm tra kết quả:
python demo_toolbox.py \
--encoder_path saved_models/encoder.pt \
--synthesizer_path saved_models/synthesizer.pt \
--vocoder_path saved_models/vocoder.pt \
--input_wav samples/reference.wav \
--text "这是一个语音合成的测试"