TEKNİK YAZI / Yapay Zekâ Entegrasyonları

Text-to-Speech (TTS): Metin Normalizasyonundan Vocoder'a

Text-to-Speech (TTS) sistemlerinde metin normalizasyonu, akustik model ve vocoder; codec ve flow matching tabanlı modeller, Web Speech API ve gTTS örnekleri.

Text-to-Speech (TTS), yazılı metni konuşma sesine dönüştüren sistemlerin genel adıdır. Sistem yalnızca harfleri seslendirmez; sayıların, kısaltmaların ve noktalamanın nasıl okunacağını belirler, telaffuz ile ritmi modeller ve sonunda hoparlörden çalınabilen bir ses dalgası üretir.

TTS nasıl çalışır?

TTS mimarileri aynı işlem hattını kullanmak zorunda değildir. Bazı sistemlerde metin ön işleme, akustik model ve vocoder ayrı bileşenlerdir. VITS gibi uçtan uca yaklaşımlar ise bu sınırların bir bölümünü tek bir eğitim yapısında birleştirir. Yine de sistemi anlamak için aşağıdaki üç soruya ayırmak kullanışlıdır.

1. Metin nasıl okunacak?

Metin ön ucu ham girdiyi konuşulabilir bir gösterime dönüştürür. Bu aşamada:

Örneğin 120 değeri bağlama göre “yüz yirmi”, bir otobüs hattı numarası veya bir ürün kodu olarak farklı okunabilir. Bu nedenle metin normalizasyonu (text normalization) yalnızca karakter değiştirme değil, alan ve dil kuralı gerektiren bir adımdır.

2. Konuşmanın akustik yapısı nasıl temsil edilecek?

Klasik sinir ağı tabanlı boru hatlarında akustik model; karakter, fonem veya başka bir dilsel gösterimden mel-spektrogram gibi zaman-frekans özellikleri üretir. Süre, perde, enerji ve vurgu kararları konuşmanın ritmini ve tonlamasını etkiler.

Tacotron 2 (Shen vd., 2018) bu ayrımın bilinen örneklerinden biridir: metinden mel-spektrogram tahmini yapan bir ağın çıktısı, dalga biçimi üreten değiştirilmiş bir WaveNet vocoder’a koşul olarak verilir.

Bu, her güncel TTS sisteminin mutlaka mel-spektrogram ürettiği anlamına gelmez. VITS (Kim vd., 2021), metinden konuşmaya dönüşümün farklı bileşenlerini koşullu varyasyonel otokodlayıcı (conditional VAE) ve çekişmeli (adversarial) eğitimle paralel, uçtan uca bir yapıda birleştiren başka bir mimari örneğidir.

3. Dinlenebilir ses dalgası nasıl üretilecek?

Ayrı aşamalı sistemlerde vocoder, akustik gösterimi örneklenmiş ses dalgasına dönüştürür. WaveNet gibi otoregresif modeller bir sonraki ses örneğinin dağılımını önceki örneklere bağlı olarak üretirken, başka mimariler daha paralel üretim yöntemleri kullanabilir.

Seçim yalnızca ses kalitesine göre yapılmaz. Gerçek zamanlı bir okuyucuda ilk ses paketine kadar geçen süre ve akış (streaming) davranışı önemliyken, çevrimdışı üretimde toplam işleme süresi veya donanım maliyeti daha baskın olabilir.

2023 sonrası yaklaşımlar: codec dil modelleri ve flow matching

2023’ten itibaren iki yaklaşım öne çıktı. İkisi de büyük, çok konuşmacılı veri setleriyle eğitilir ve birkaç saniyelik bir referans kayıttan yeni bir konuşmacının sesini taklit edebilir (sıfır örnekli, zero-shot TTS).

Nöral ses codec’i üzerinde dil modeli. SoundStream ve EnCodec (Défossez vd., 2022) gibi nöral ses codec’leri ses dalgasını ayrık token dizilerine sıkıştırır ve bu token’lardan sesi geri üretir. VALL-E (Wang vd., 2023), TTS’i sürekli bir sinyali regresyonla tahmin etmek yerine bu token’lar üzerinde koşullu dil modelleme problemi olarak ele alır. Metin ve konuşmacının 3 saniyelik kaydı istem (prompt) olarak verilir, model ses token’larını üretir ve codec çözücüsü dalga biçimini oluşturur. Makaledeki model 60 bin saatlik İngilizce konuşmayla eğitilmiştir ve istemdeki konuşmacının duygusunu ve akustik ortamını da koruyabildiği raporlanır. Token’ları sırayla üretmek PixelCNN ve WaveNet’teki otoregresif fikrin devamıdır; fark, üretim biriminin ham ses örneği yerine codec token’ı olmasıdır.

Flow matching. Voicebox (Le vd., 2023), metin ve çevresindeki ses bağlamı verildiğinde eksik konuşma bölümünü doldurmayı (infilling) öğrenen, otoregresif olmayan bir flow matching modelidir; aynı model sıfır örnekli TTS, gürültü giderme ve içerik düzenleme için kullanılabilir. F5-TTS (Chen vd., 2024) bu çizgiyi bir Diffusion Transformer ile sürdürür: süre modeli ve fonem hizalaması kullanmaz, metni dolgu token’larıyla konuşma uzunluğuna getirir ve konuşmayı gürültüden adım adım üretir. Flow matching’in görüntü üretimindeki karşılığı için FLUX.1 yazısına bakılabilir.

İki yaklaşım birlikte de kullanılabilir. CosyVoice (Du vd., 2024) metinden konuşma token’larını bir dil modeliyle üretir, token’lardan konuşmaya dönüşümü ise koşullu bir flow matching modeline bırakır.

Bu modellerin kısa bir kayıttan ses taklit edebilmesi, aşağıdaki güvenlik ve izin bölümünü daha da önemli kılar.

Tarayıcıda Web Speech API ile TTS

Web Speech API, konuşma sentezini SpeechSynthesis arayüzü üzerinden sunar. Ses listesi sayfa açıldıktan sonra yüklenebilir; bu durumda ilk getVoices() çağrısı boş dizi döndürür ve liste hazır olduğunda voiceschanged olayı tetiklenir. Aşağıdaki örnek listeyi sayfa yüklenirken bir kez ister, gerekirse bu olayı bekler ve konuşmayı bir düğmenin tıklama olayından başlatır:

// Ses listesini döndürür; liste boşsa voiceschanged olayını en fazla timeoutMs bekler
function loadVoices(timeoutMs = 2000) {
  if (!("speechSynthesis" in window)) return Promise.resolve([]);

  const synth = window.speechSynthesis;
  const voices = synth.getVoices();
  if (voices.length > 0) return Promise.resolve(voices);

  return new Promise(resolve => {
    const finish = () => {
      clearTimeout(timer);
      synth.removeEventListener("voiceschanged", finish);
      resolve(synth.getVoices());
    };
    const timer = setTimeout(finish, timeoutMs);
    synth.addEventListener("voiceschanged", finish);
  });
}

// Sayfa yüklenirken başlatılır; tıklama geldiğinde liste çoğunlukla hazırdır
const voicesReady = loadVoices();

async function speakTurkish(text) {
  if (!("speechSynthesis" in window)) return; // Tarayıcı konuşma sentezini desteklemiyor

  const synth = window.speechSynthesis;
  const utterance = new SpeechSynthesisUtterance(text);

  utterance.lang = "tr-TR";
  utterance.rate = 1;
  utterance.pitch = 1;
  utterance.volume = 1;

  const voices = await voicesReady;
  const turkishVoice = voices.find(voice =>
    voice.lang.toLowerCase().startsWith("tr")
  );

  if (turkishVoice) {
    utterance.voice = turkishVoice;
  }

  synth.cancel();
  synth.speak(utterance);
}

document
  .querySelector("#speak")
  .addEventListener("click", () => speakTurkish("Merhaba dünya!"));

Örnek, sayfada id="speak" olan bir düğme bulunduğunu varsayar. Olay hiç tetiklenmezse loadVoices() zaman aşımından sonra eldeki listeyle devam eder.

Ses listesini görmek için:

loadVoices().then(voices => {
  for (const voice of voices) {
    console.log(voice.name, voice.lang, voice.default);
  }
});

getVoices() yalnızca mevcut cihazda kullanılabilen sesleri döndürür. Liste işletim sistemi, tarayıcı ve kurulu ses paketlerine göre değişebilir; Türkçe ses bulunması garanti değildir. Türkçe ses bulunamazsa örnekte utterance.lang korunur ve ses seçimi platformun varsayılanına bırakılır.

Python ile MP3 üretme

gTTS, Google Translate’in TTS uç noktasına arayüz sağlayan üçüncü taraf bir Python paketidir:

from gtts import gTTS

tts = gTTS(text="Merhaba dünya!", lang="tr")
tts.save("merhaba.mp3")

Bu örnek çevrimdışı bir model çalıştırmaz. gTTS dokümantasyonunda belirtildiği gibi save() bir TTS API isteği yapar; dolayısıyla ağ erişimine ve uzak servisin yanıtına ihtiyaç duyar. Hassas metinleri uzak bir servise göndermeden önce gizlilik, kullanım koşulları ve veri konumu gereksinimlerini değerlendirin.

Üretilen dosyayı oynatmak ayrı bir sorumluluktur. Sunucu uygulamasında MP3’ü saklamak veya HTTP yanıtı olarak aktarmak; masaüstünde ise platforma uygun bir oynatıcı kullanmak gerekebilir.

TTS kalitesini zorlayan durumlar

Metin normalizasyonu

Tarih, para, ölçü, telefon numarası ve kısaltmalar alana göre farklı okunur. Test kümesi gerçek uygulamanın metin türlerini içermelidir.

Telaffuz

Kişi adları, marka adları, yabancı kelimeler ve kod parçaları sözlükte bulunmayabilir. Fonem sözlüğü, kullanıcı telaffuz ipucu veya modelin desteklediği başka bir kontrol mekanizması gerekebilir.

Prosodi

Noktalama tek başına doğru vurgu, duraklama ve duyguyu belirlemeye yetmez. Aynı cümle soru, uyarı veya anlatım bağlamında farklı söylenebilir.

Gecikme ve akış (streaming)

Uzun metnin tamamını üretip sonra çalmak, ilk sesin duyulmasına kadar geçen süreyi uzatır. Cümlelere bölme ve akış halinde üretim bu gecikmeyi azaltabilir; fakat bölüm sınırlarında prosodi tutarlılığını korumak gerekir.

Güvenlik ve izin

Bir kişinin sesine benzeyen çıktı üretmek teknik yeterlilikten fazlasını gerektirir. Açık rıza, kullanım hakkı, yanıltma riski ve üretilen sesin gerektiğinde işaretlenmesi ürün tasarımının parçası olmalıdır.

Uygulama seçerken kontrol listesi

  1. Gerekli dil ve lehçe gerçekten destekleniyor mu?
  2. Özel adlar ve alana özgü terimler nasıl yönlendiriliyor?
  3. Sesler cihazda mı üretiliyor, yoksa metin uzak sunucuya mı gidiyor?
  4. İlk ses gecikmesi ve toplam üretim süresi hedefi karşılıyor mu?
  5. Ses ve model lisansı hedef kullanıma izin veriyor mu?
  6. Uygulamanın gerçek metinlerinden oluşturulmuş bir telaffuz ve prosodi test kümesi var mı?

Tek bir demo cümlesinin doğal duyulması üretim kalitesini kanıtlamaz. Sayılar, kısaltmalar, özel adlar, uzun cümleler ve hatalı girdilerle tekrarlanabilir değerlendirme yapmak daha güvenilir sonuç verir.

Sonuç

Tarayıcıda kısa metinleri okutmak için Web Speech API ek bağımlılık gerektirmez, ancak ses kalitesi ve Türkçe sesin varlığı kullanıcının cihazına bağlıdır. Tutarlı ses ve kontrol gerektiğinde sunucu tarafında bir model ya da bulut servisi kullanılır; bulut servisinde metnin dışarı gönderildiği hesaba katılmalıdır. Codec dil modelleri ve flow matching tabanlı güncel modeller birkaç saniyelik kayıttan ses taklit edebildiği için rıza ve kötüye kullanım önlemleri olmadan ürüne alınmamalıdır.

Birincil kaynaklar