Synteza mowy na mikrokomputerach: od eSpeak NG do Piper TTS
Rozwój syntezatorów mowy przeszedł etapy od urządzeń mechanicznych po modele oparte na sieciach neuronowych. Na przełomie XVIII i XIX wieku pojawiły się mechaniczne odpowiedniki traktu głosowego z membranami i pompy powietrzne do symulacji barw dźwięku. Przykładem jest Euphonia z 1846 roku z klawiaturą i elementami akustycznymi.
Era elektroniczna rozpoczęła się z Voderem (1930, Bell Labs): generatory tonu, szumy i filtry sterowane klawiszami. Pattern Playback (1940–1950) odtwarzał spektrogramy. W 1961 roku na komputerze IBM 704 za pomocą modelu traktu głosowego wygenerowano piosenkę Daisy Bell. W 1968 roku w Japonii stworzono pierwszy TTS oparty na syntezie formantowej. MUSA (1975–1978) zapewniała czas rzeczywisty dla języka włoskiego.
Od lat 80. – syntezowanie formantowe z fonemami, od lat 90. – statystyka, od 2010. – sieci neuronowe VITS do end-to-end TTS.
Lekki syntezator eSpeak NG
eSpeak NG to open source TTS oparte na syntezie formantowej bez próbek rzeczywistych głosów. Wynik to robotyzowany brzmienie, ale niskie wymagania sprzętowe pozwalają uruchomić go nawet na Repka-Pi 4 z 2 GB RAM. Idealny do powiadomień i prototypów.
Instalacja i uruchamianie przez CLI
Zaktualizuj pakiety i zainstaluj:
apt update
apt install espeak-ng
Sprawdź dostępne głosy:
espeak-ng --voices | grep Russian
Synteza tekstu:
espeak-ng "Witaj Repka Pi" -v ru
Tekst wielolinijkowy przez heredoc:
espeak-ng -v ru -s 150 << EOF
Witaj świecie!
To bardzo długi tekst,
który zajmuje kilka linii.
EOF
Z pliku z głosem kobiecym:
espeak-ng -v ru+f5 -s 150 -f hello-repka-pi.txt
Głosy: ru, ru+m1..m7, ru+f1..f5.
Integracja z Pythonem
Funkcja do uruchamiania przez subprocess:
import subprocess
def say(text, voice="ru", speed=150, pitch=50):
"""
voice — język/głos (ru, en, de).
speed — 80–200.
pitch — 0–99.
"""
try:
subprocess.run([
"espeak-ng",
"-v", voice,
"-s", str(speed),
"-p", str(pitch),
text
], check=True, capture_output=True)
except FileNotFoundError:
print("eSpeak NG nie znaleziony. Zainstaluj: sudo apt install espeak-ng")
except subprocess.CalledProcessError as e:
print("Błąd:", e.stderr.decode())
if __name__ == "__main__":
say("Witaj! To test głosu rosyjskiego.", voice="ru", speed=140)
say("Hello, this is a test in English", voice="en-us", speed=160, pitch=60)
say("Testujemy inny głos rosyjski", voice="ru+f3", speed=135)
Uruchomienie: python3 espeak-ng-test.py.
Synteza mowy oparta na sieciach neuronowych Piper TTS
Piper TTS oparte na VITS (Variational Inference with adversarial learning for end-to-end TTS) z modelami ONNX zapewnia naturalną mowę w czasie rzeczywistym na mikrokomputerach. Jakość przewyższa eSpeak NG, a opóźnienia są akceptowalne dla Repka-Pi 4.
Instalacja i przygotowanie modeli
Środowisko wirtualne:
sudo apt update
sudo apt install python3-pip
python3 -m venv ~/piper_env
source ~/piper_env/bin/activate
pip install --upgrade pip
pip install piper-tts sounddevice numpy
Pobierz rosyjski model (denis-medium):
mkdir -p ~/piper-voices/ru
cd ~/piper-voices/ru
wget https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/ru/ru_RU/denis/medium/ru_RU-denis-medium.onnx?download=true -O ru_RU-denis-medium.onnx
wget https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/ru/ru_RU/denis/medium/ru_RU-denis-medium.onnx.json?download=true -O ru_RU-denis-medium.onnx.json
Uruchamianie przez CLI i Pythona
Synteza do pliku WAV:
piper --model ~/piper-voices/ru/ru_RU-denis-medium.onnx --output_file duży_tekst.wav <<EOF
Witaj świecie!
To bardzo długi tekst...
EOF
aplay duży_tekst.wav
Z pliku: piper --model model.onnx --output_file output.wav -f input.txt.
Integracja z Pythonem podobna do eSpeak, z wywołaniem piper przez subprocess lub natywnym API.
Serwer TTS na FastAPI
Stwórz asynchroniczny serwer do obsługi kolejek żądań. Uruchamia się jako usługa systemd na Repka-Pi 4.
- Zalety: Klienci wysyłają POST HTTP bez oczekiwania, serwer umieszcza zadanie w kolejce.
- Stos: FastAPI, Piper TTS, kolejka zadań.
Kod źródłowy serwera (przykład):
from fastapi import FastAPI
import queue
import threading
from piper import PiperVoice
app = FastAPI()
voice = PiperVoice.load("~/piper-voices/ru/ru_RU-denis-medium.onnx")
task_queue = queue.Queue()
def process_queue():
while True:
text = task_queue.get()
wav = voice.synthesize(text)
# Zapisz/strimuj
task_queue.task_done()
threading.Thread(target=process_queue, daemon=True).start()
@app.post("/synthesize")
async def synthesize(text: str):
task_queue.put(text)
return {"status": "queued"}
Plik unit dla systemd:
[Unit]
Description=Piper TTS Server
After=network.target
[Service]
ExecStart=/path/to/server.py
Restart=always
[Install]
WantedBy=multi-user.target
Klient: curl -X POST http://repka-pi:8000/synthesize -d 'Tekst do syntezy'.
Co warto wiedzieć
- eSpeak NG: niski footprint, syntezowanie formantowe, idealne dla słabego sprzętu.
- Piper TTS: VITS/ONNX do naturalnej mowy, czas rzeczywisty na SBC.
- Serwer na FastAPI: asynchroniczna kolejka, autostart przez systemd.
- Zastosowania: asystenci głosowi, IoT, roboty na Repka-Pi 4/5.
- Repka-Pi 5: do 32 GB RAM, x2 wydajność w porównaniu do Raspberry Pi 5 dla TTS+ASR.
— Editorial Team
Brak komentarzy.