Museumsprojekt · Handvermittlung

Whisper-Vermittlung
Installationsanleitung

OpenAI Whisper + Asterisk AGI auf Ubuntu MATE 24.04 LTS – Spracherkennung für eine historische Telefonvermittlung.

Ubuntu 24.04 LTS Python 3.12 Whisper Base Asterisk AGI gTTS sox Root erforderlich
Inhalt
  1. Voraussetzungen & Systemüberblick
  2. Systemvorbereitung (root)
  3. Whisper installieren
  4. Whisper-Modell herunterladen
  5. Python-Abhängigkeiten
  6. sox & Audiowerkzeuge
  7. Konfigurationsdatei vermittlung.json
  8. Skript einrichten
  9. Installation testen
  10. Troubleshooting
01

Voraussetzungen & Systemüberblick

Das Skript whisper_vermittlung.py läuft als Asterisk AGI-Prozess. Eingehende Audiodaten (WAV) werden von Whisper transkribiert; das Ergebnis (Nebenstellen-Nummer oder Name) wird als AGI-Variable zurückgegeben.

⚠ Wichtig Die Installation muss als root durchgeführt werden. Whisper schreibt in systemweite Verzeichnisse, und Asterisk AGI-Skripte benötigen Schreibrechte in /opt/ und /etc/asterisk/.

Folgende Komponenten werden installiert:

02

Systemvorbereitung

Als root einloggen und das System aktualisieren:

bash
# Als root arbeiten
sudo -i

# System aktualisieren
apt update && apt upgrade -y

# Benötigte Systempakete
apt install -y \
    python3-pip \
    python3-venv \
    python3-dev \
    ffmpeg \
    sox \
    libsox-fmt-mp3 \
    git \
    curl
ℹ Info libsox-fmt-mp3 wird benötigt, damit sox MP3-Dateien (gTTS-Output) in das Asterisk-WAV-Format konvertieren kann.
03

Whisper installieren

Whisper wird als root systemweit über pip installiert. PyTorch (CPU-Version) wird als Abhängigkeit automatisch mitgezogen. Dies dauert je nach Verbindung 5–15 Minuten.

bash
# Whisper + alle Python-Abhängigkeiten als root installieren
pip3 install \
    openai-whisper \
    gtts \
    torch \
    torchvision \
    torchaudio \
    --break-system-packages

# Alternativ nur CPU-PyTorch (deutlich kleiner, ausreichend):
pip3 install openai-whisper gtts --break-system-packages
pip3 install torch torchvision torchaudio \
    --index-url https://download.pytorch.org/whl/cpu \
    --break-system-packages
⚠ Ubuntu 24.04 Hinweis Ubuntu 24.04 verwendet „Externally Managed" Python. Das Flag --break-system-packages ist zwingend erforderlich, da es sonst zu einem externally-managed-environment-Fehler kommt. Als root ist dies unproblematisch.
04

Whisper-Modell herunterladen

Das Skript erwartet das Modell unter /opt/whisper-models/base.pt. Das base-Modell (ca. 145 MB) ist ein guter Kompromiss zwischen Genauigkeit und Geschwindigkeit auf älterer Hardware.

bash
# Zielverzeichnis anlegen
mkdir -p /opt/whisper-models

# Modell direkt mit Python herunterladen und in Zielverzeichnis speichern
python3 -c "
import whisper, shutil, os
# Lädt nach ~/.cache/whisper/ – danach verschieben
m = whisper.load_model('base')
src = os.path.expanduser('~/.cache/whisper/base.pt')
dst = '/opt/whisper-models/base.pt'
shutil.copy2(src, dst)
print('Modell kopiert nach', dst)
"

# Alternativ: direkt mit wget (offizieller Download-Link)
wget -O /opt/whisper-models/base.pt \
    https://openaipublic.azureedge.net/main/whisper/models/ed3a0b6b1c0edf879ad9b11b1af5a0e6ab5db9205f891f668f8b0e6c6326e34e/base.pt

# Berechtigungen setzen (Asterisk-User muss lesend zugreifen)
chmod 644 /opt/whisper-models/base.pt
chown root:root /opt/whisper-models/base.pt

Verfügbare Modelle

Falls bessere Erkennungsqualität gewünscht ist (auf leistungsfähiger Hardware):

Für andere Modelle in whisper_vermittlung.py den Pfad MODELL_PFAD anpassen.

05

Python-Abhängigkeiten prüfen

Alle direkt im Skript verwendeten Module und ihr Status:

bash
# Installierte Pakete überprüfen
python3 -c "
import sys, subprocess
pkgs = ['whisper', 'gtts', 'torch']
for p in pkgs:
    try:
        __import__(p)
        print(f'  ✓ {p}')
    except ImportError:
        print(f'  ✗ {p} FEHLT')
"

# Übersicht aller installierten Versionen
pip3 show openai-whisper gtts torch 2>/dev/null | grep -E "^Name|^Version"

Folgende Module sind Python-Standardbibliothek und müssen nicht extra installiert werden:

06

sox & Audiowerkzeuge

Das Skript nutzt sox an zwei Stellen: zur Audiovorverarbeitung (Bandpass-Filter für Telefonfrequenzen) und zur MP3→WAV-Konvertierung für Asterisk.

bash
# sox mit MP3-Unterstützung (bereits in Schritt 2, zur Sicherheit nochmal)
apt install -y sox libsox-fmt-mp3 libsox-fmt-all

# ffmpeg (Whisper intern benötigt)
apt install -y ffmpeg

# sox-Installation testen
sox --version

# Kurztest: Stummes WAV erzeugen und konvertieren
sox -n /tmp/test.wav trim 0.0 1.0
sox /tmp/test.wav -r 16000 -c 1 /tmp/test16k.wav \
    highpass 300 lowpass 3200 norm -6
echo "sox OK"
✓ Was sox im Skript macht Der Bandpass-Filter (300–3200 Hz) entspricht exakt dem Telefonfrequenzband und verbessert die Whisper-Erkennungsrate bei Telefonaudio erheblich. norm -6 normalisiert die Lautstärke auf –6 dBFS.
07

Konfigurationsdatei vermittlung.json

Das Skript liest die Namensliste aus /etc/asterisk/vermittlung.json. Die Datei enthält ein JSON-Objekt mit dem Schlüssel "nebenstellen", in dem Namen (Kleinbuchstaben) auf Nummern gemappt werden.

json · /etc/asterisk/vermittlung.json
{
  "nebenstellen": {
    "roland":    "1004",
    "silvia":    "1006",
    "volker":    "1033",
    "sebastian": "1040",
    "michael":   "1050",
    "zeitansage": "222",
    "wetter":    "333"
  }
}
bash
# Datei anlegen und Berechtigungen setzen
nano /etc/asterisk/vermittlung.json

# Asterisk-User braucht Lesezugriff
chown root:asterisk /etc/asterisk/vermittlung.json
chmod 640 /etc/asterisk/vermittlung.json

# JSON-Syntax prüfen
python3 -c "import json; json.load(open('/etc/asterisk/vermittlung.json')); print('JSON OK')"
ℹ Fuzzy-Matching Das Skript verwendet Levenshtein-Distanz (Schwellenwert 2). Namen in der JSON-Datei sollten kleingeschrieben sein, da der erkannte Text ebenfalls normalisiert wird. Zwei-Wort-Namen wie "volker junghard" werden ebenfalls unterstützt.
08

Skript einrichten

Das AGI-Skript kommt in das Asterisk-AGI-Verzeichnis:

bash
# Skript ins AGI-Verzeichnis kopieren
cp whisper_vermittlung.py /usr/share/asterisk/agi-bin/
chmod 755 /usr/share/asterisk/agi-bin/whisper_vermittlung.py
chown asterisk:asterisk /usr/share/asterisk/agi-bin/whisper_vermittlung.py

# Shebang prüfen – muss auf python3 zeigen
head -1 /usr/share/asterisk/agi-bin/whisper_vermittlung.py
# Erwartet: #!/usr/bin/env python3

# Python3-Pfad ermitteln (für Debugging)
which python3

Asterisk Dialplan (extensions.conf – Beispiel)

asterisk dialplan
; Aufnahme starten, dann Whisper AGI aufrufen
exten => s,1,Answer()
 same => n,Record(/tmp/whisper_input.wav,3,10,k)
 same => n,AGI(whisper_vermittlung.py,/tmp/whisper_input)
 same => n,GotoIf($[${RECOGNIZED} = error]?fehler,1)
 same => n,GotoIf($[${RECOGNIZED} = nichts]?nochmal,1)
 same => n,Dial(SIP/${RECOGNIZED})

exten => fehler,1,Playback(sorry)
exten => nochmal,1,Playback(bitte-nochmals)
ℹ Pfad-Konvention Asterisk übergibt den WAV-Pfad ohne Endung. Das Skript hängt .wav automatisch an, falls die Datei nicht direkt gefunden wird.
09

Installation testen

Whisper-Erkennung ohne Asterisk direkt auf der Kommandozeile testen:

bash
# 1. Testaufnahme erzeugen (Text-to-Speech → WAV)
python3 -c "
from gtts import gTTS
tts = gTTS('Bitte verbinden Sie mich mit Roland', lang='de')
tts.save('/tmp/test_input.mp3')
"
sox /tmp/test_input.mp3 -r 8000 -c 1 -e signed-integer -b 16 /tmp/test_input.wav

# 2. Whisper direkt testen
python3 -c "
import whisper
model = whisper.load_model('/opt/whisper-models/base.pt')
r = model.transcribe('/tmp/test_input.wav', language='de', fp16=False)
print('Erkannt:', r['text'])
"

# 3. Vollständiges AGI-Skript mit simuliertem AGI-Kontext testen
# (leere Headerzeile am Anfang simuliert AGI-Protokoll)
echo "" | python3 /usr/share/asterisk/agi-bin/whisper_vermittlung.py /tmp/test_input
✓ Erwartete Ausgabe Das Skript gibt AGI-Befehle wie VERBOSE "Name erkannt: roland -> 1004" 1 und SET VARIABLE RECOGNIZED 1004 aus. Das ist korrekt.
10

Troubleshooting

ModuleNotFoundError: No module named 'whisper'

bash
# Prüfen, welches Python Asterisk verwendet
which python3
python3 -c "import sys; print(sys.path)"
# Whisper ggf. für den exakten Python-Pfad nochmals installieren
/usr/bin/python3 -m pip install openai-whisper --break-system-packages

sox: no handler for file extension 'mp3'

bash
apt install -y libsox-fmt-mp3 libsox-fmt-all
sox --version  # muss mp3 in der Liste zeigen

Datei nicht gefunden (WAV-Pfad)

⚠ Hinweis Asterisk übergibt Pfade ohne .wav-Endung. Das Skript ergänzt sie automatisch. Sicherstellen, dass /tmp/ für den Asterisk-User beschreibbar ist: ls -la /tmp/ – muss rwxrwxrwt zeigen.

Whisper sehr langsam

Auf älterer Hardware (ohne GPU) dauert die Transkription mit dem base-Modell 3–10 Sekunden. Das tiny-Modell ist deutlich schneller bei etwas geringerer Genauigkeit. MODELL_PFAD im Skript entsprechend anpassen und tiny.pt herunterladen.

gTTS schlägt fehl (kein Internet)

gTTS benötigt eine Internetverbindung (Google-Server). Für Offline-Betrieb kann pyttsx3 als lokale Alternative eingesetzt werden – dann müssen die Aufrufe in ansage_sprechen() angepasst werden.

bash
# Offline-Alternative installieren
apt install -y espeak espeak-ng
pip3 install pyttsx3 --break-system-packages

Alle Abhängigkeiten auf einen Blick

bash – Schnell-Check
python3 -c "
checks = {
    'whisper':     'openai-whisper',
    'gtts':        'gTTS',
    'torch':       'PyTorch',
    'subprocess':  'stdlib',
    'json':        'stdlib',
}
for mod, label in checks.items():
    try:
        __import__(mod)
        print(f'  ✓  {label}')
    except ImportError:
        print(f'  ✗  {label}  <-- FEHLT, bitte installieren')
"

which sox ffmpeg && echo "  ✓  sox + ffmpeg vorhanden"
test -f /opt/whisper-models/base.pt && echo "  ✓  Modell vorhanden" || echo "  ✗  Modell FEHLT"
test -f /etc/asterisk/vermittlung.json && echo "  ✓  vermittlung.json vorhanden" || echo "  ✗  vermittlung.json FEHLT"