Реализация Speech-to-Speech с сохранением голоса говорящего
Speech-to-Speech с сохранением голоса (Voice Preservation S2S) переводит речь на другой язык, сохраняя тембр, акцент и характеристики голоса оригинального говорящего. Это принципиально сложнее стандартного S2S, где используется фиксированный TTS-голос.
Компоненты voice preservation pipeline
Source Audio
↓
[1] Speaker Encoder → Speaker Embedding (d-vector)
↓
[2] STT → Transcript (source language)
↓
[3] Machine Translation → Transcript (target language)
↓
[4] TTS with Voice Conversion → Output Audio
(использует speaker embedding из шага 1)
Извлечение speaker embedding
from speechbrain.pretrained import EncoderClassifier
import torchaudio
import torch
encoder = EncoderClassifier.from_hparams(
source="speechbrain/spkrec-ecapa-voxceleb",
savedir="tmp_encoder"
)
def extract_speaker_embedding(audio_path: str) -> torch.Tensor:
signal, sr = torchaudio.load(audio_path)
if sr != 16000:
signal = torchaudio.functional.resample(signal, sr, 16000)
embedding = encoder.encode_batch(signal)
return embedding.squeeze() # (192,) вектор
Zero-shot TTS с conditioning на embedding
XTTS v2 принимает референсное аудио и кондиционируется на него при синтезе:
from TTS.api import TTS
tts = TTS("tts_models/multilingual/multi-dataset/xtts_v2").to("cuda")
async def voice_preserving_translate(
source_audio: str,
target_language: str,
target_text: str
) -> np.ndarray:
# XTTS использует source_audio для извлечения голосовых характеристик
wav = tts.tts(
text=target_text,
speaker_wav=source_audio, # исходное аудио как референс голоса
language=target_language
)
return np.array(wav)
SeamlessM4T (Meta) — end-to-end подход
Meta SeamlessM4T поддерживает S2ST с частичным сохранением просодики:
from transformers import SeamlessM4Tv2ForSpeechToSpeech, AutoProcessor
import torchaudio
processor = AutoProcessor.from_pretrained("facebook/seamless-m4t-v2-large")
model = SeamlessM4Tv2ForSpeechToSpeech.from_pretrained(
"facebook/seamless-m4t-v2-large"
).to("cuda")
audio, sr = torchaudio.load("source.wav")
inputs = processor(audios=audio, src_lang="rus", return_tensors="pt").to("cuda")
with torch.no_grad():
output = model.generate(**inputs, tgt_lang="eng")
translated_audio = output[0].cpu().numpy().squeeze()
Поддерживает 100+ языков, задержка 1–3 секунды на длинных фрагментах.
Качество сохранения голоса
| Подход | SECS | Perceptual Score |
|---|---|---|
| SeamlessM4T | 0.60–0.70 | 3.2–3.5 |
| XTTS v2 zero-shot | 0.78–0.88 | 3.8–4.2 |
| Fine-tuned XTTS | 0.88–0.93 | 4.2–4.5 |
Сроки: pipeline с XTTS — 2 недели. С SeamlessM4T + fine-tuning — 4–6 недель.







