Bemerkung
Hallo und herzlich willkommen in der SunFounder Raspberry Pi & Arduino & ESP32 Enthusiasten-Community auf Facebook! Tauchen Sie gemeinsam mit anderen Technikbegeisterten tiefer in die Welt von Raspberry Pi, Arduino und ESP32 ein.
Warum beitreten?
Expertenunterstützung: Lösen Sie technische Probleme und Herausforderungen nach dem Kauf mit Unterstützung unserer Community und unseres Teams.
Lernen & Teilen: Tauschen Sie Tipps und Anleitungen aus, um Ihre Fähigkeiten zu erweitern.
Exklusive Vorschauen: Erhalten Sie vorab Einblicke in neue Produkte und Ankündigungen.
Sonderrabatte: Profitieren Sie von exklusiven Rabatten auf unsere neuesten Produkte.
Feiertagsaktionen & Verlosungen: Nehmen Sie an spannenden Verlosungen und saisonalen Aktionen teil.
👉 Bereit, mit uns gemeinsam zu entdecken und zu gestalten? Klicken Sie auf [here] und treten Sie noch heute bei!
6. Lokaler Sprach-Chatbot
In dieser Lektion kombinieren Sie alles, was Sie gelernt haben — Spracherkennung (STT), Text-to-Speech (TTS) und ein lokales LLM (Ollama) — um einen vollständig offline arbeitenden Sprach-Chatbot zu bauen, der auf Ihrem Pironman 5 Pro MAX läuft.
Der Arbeitsablauf ist einfach:
Hören — Das Mikrofon nimmt Ihre Sprache auf und transkribiert sie mit Vosk.
Denken — Der Text wird an ein lokales LLM gesendet, das auf Ollama läuft (z.B.
llama3.2:3b).Sprechen — Der Chatbot antwortet mithilfe von Piper TTS laut.
Dies erschafft einen freihändig bedienbaren Konversationsroboter, der in Echtzeit verstehen und antworten kann.
Vorbereitung
Stellen Sie sicher, dass Sie Folgendes vorbereitet haben:
Piper TTS getestet (1. Piper testen) und ein funktionierendes Sprachmodell ausgewählt.
Vosk STT getestet (Vosk testen) und das richtige Sprachpaket ausgewählt (z.B.
de).Ollama installiert (1. Ollama (LLM) installieren und Modell herunterladen) auf Ihrem Pi oder einem anderen Computer und ein Modell wie
llama3.2:3bheruntergeladen (oder ein kleineres wiemoondream:1.8b, wenn der Speicher begrenzt ist).
Code ausführen
Öffnen Sie das Beispielskript:
cd ~/sunfounder-voice-assistant/examples/ sudo nano local_voice_chatbot.py
Aktualisieren Sie die Parameter nach Bedarf:
stt = Vosk(language="de"): Ändern Sie dies, um es an Ihren Akzent/Ihr Sprachpaket anzupassen (z.B.de,en-us,es).tts.set_model("de_DE-thorsten-low"): Ersetzen Sie dies mit dem Piper-Sprachmodell, das Sie in 1. Piper testen überprüft haben.llm = Ollama(ip="localhost", model="llama3.2:3b"): Aktualisieren Sie sowohlipals auchmodelentsprechend Ihrem eigenen Setup.ip: Wenn Ollama auf dem gleichen Pi läuft, verwenden Sielocalhost. Wenn Ollama auf einem anderen Computer in Ihrem LAN läuft, aktivieren Sie Für Netzwerk freigeben in Ollama und setzen Sieipauf die LAN-IP dieses Computers.model: Muss exakt mit dem Modellnamen übereinstimmen, den Sie in Ollama heruntergeladen/aktiviert haben.
Führen Sie das Skript aus:
cd ~/sunfounder-voice-assistant/examples/ sudo python3 local_voice_chatbot.py
Nach dem Start sollten Sie Folgendes sehen/hören:
Der Bot begrüßt Sie mit einer gesprochenen Willkommensnachricht.
Er wartet auf Spracheingabe.
Vosk transkribiert Ihre Sprache in Text.
Der Text wird an Ollama gesendet, das eine Antwort zurückgibt.
Die Antwort wird bereinigt (Entfernung versteckter Gedankengänge) und von Piper laut ausgesprochen.
Stoppen Sie das Programm jederzeit mit
Strg+C.
Code
import re
import time
from sunfounder_voice_assistant.llm import Ollama
from sunfounder_voice_assistant.stt import Vosk
from sunfounder_voice_assistant.tts import Piper
# Spracherkennung initialisieren
stt = Vosk(language="de")
# TTS initialisieren
tts = Piper()
tts.set_model("de_DE-thorsten-low")
# Anweisungen für das LLM
INSTRUCTIONS = (
"Du bist ein hilfreicher Assistent. Antworte direkt auf Deutsch. "
"Füge KEINE versteckten Gedanken, Analysen oder Tags wie <think> hinzu."
)
WELCOME = "Hallo! Ich bin dein Sprach-Chatbot. Sprich, wenn du bereit bist."
# Ollama-Verbindung initialisieren
llm = Ollama(ip="localhost", model="llama3.2:3b")
llm.set_max_messages(20)
llm.set_instructions(INSTRUCTIONS)
# Hilfsfunktion: Entferne versteckte Gedankengänge
def strip_thinking(text: str) -> str:
if not text:
return ""
text = re.sub(r"<\s*think[^>]*>.*?<\s*/\s*think\s*>", "", text, flags=re.DOTALL|re.IGNORECASE)
text = re.sub(r"<\s*thinking[^>]*>.*?<\s*/\s*thinking\s*>", "", text, flags=re.DOTALL|re.IGNORECASE)
text = re.sub(r"```(?:\s*thinking)?\s*.*?```", "", text, flags=re.DOTALL|re.IGNORECASE)
text = re.sub(r"\[/?thinking\]", "", text, flags=re.IGNORECASE)
return re.sub(r"\s+\n", "\n", text).strip()
def main():
print(WELCOME)
tts.say(WELCOME)
try:
while True:
print("\n🎤 Höre zu... (Drücke Strg+C zum Beenden)")
# Endgültiges Transkript von Vosk sammeln
text = ""
for result in stt.listen(stream=True):
if result["done"]:
text = result["final"].strip()
print(f"[DU] {text}")
else:
print(f"[DU] {result['partial']}", end="\r", flush=True)
if not text:
print("[INFO] Nichts erkannt. Versuche es erneut.")
time.sleep(0.1)
continue
# Ollama mit Streaming abfragen
reply_accum = ""
response = llm.prompt(text, stream=True)
for next_word in response:
if next_word:
print(next_word, end="", flush=True)
reply_accum += next_word
print("")
# Bereinigen und sprechen
clean = strip_thinking(reply_accum)
if clean:
tts.say(clean)
else:
tts.say("Entschuldigung, das habe ich nicht verstanden.")
time.sleep(0.05)
except KeyboardInterrupt:
print("\n[INFO] Stoppe...")
finally:
tts.say("Auf Wiedersehen!")
print("Tschüss.")
if __name__ == "__main__":
main()
Code-Analyse
Importe und globales Setup
import re
import time
from sunfounder_voice_assistant.llm import Ollama
from sunfounder_voice_assistant.stt import Vosk
from sunfounder_voice_assistant.tts import Piper
Bindet die drei Subsysteme ein, die Sie zuvor gebaut haben: Vosk für Speech-to-Text (STT), Ollama für das LLM und Piper für Text-to-Speech (TTS).
STT (Vosk) initialisieren
stt = Vosk(language="de")
Lädt das Vosk-Modell für Deutsch.
Ändern Sie den Sprachcode (z.B. en-us, es), um es an Ihr Sprachpaket für bessere Genauigkeit anzupassen.
TTS (Piper) initialisieren
tts = Piper()
tts.set_model("de_DE-thorsten-low")
Erstellt eine Piper-Engine und wählt eine bestimmte Stimme aus. Wählen Sie ein Modell, das Sie in 1. Piper testen getestet haben. Stimmen mit geringerer Qualität sind schneller und verbrauchen weniger CPU.
LLM-Anweisungen und Willkommenszeile
INSTRUCTIONS = (
"Du bist ein hilfreicher Assistent. Antworte direkt auf Deutsch. "
"Füge KEINE versteckten Gedanken, Analysen oder Tags wie <think> hinzu."
)
WELCOME = "Hallo! Ich bin dein Sprach-Chatbot. Sprich, wenn du bereit bist."
Zwei wichtige UX-Entscheidungen:
Halten Sie Antworten kurz und direkt (hilft bei der TTS-Klarheit).
Verbieten Sie explizit versteckte „Chain-of-Thought“-Tags, um verrauschte Ausgaben zu reduzieren.
Mit Ollama verbinden und Gesprächsumfang festlegen
llm = Ollama(ip="localhost", model="llama3.2:3b")
llm.set_max_messages(20)
llm.set_instructions(INSTRUCTIONS)
ip="localhost"nimmt an, dass der Ollama-Server auf demselben Pi läuft. Wenn er auf einem anderen LAN-Rechner läuft, geben Sie die LAN-IP dieses Computers ein und aktivieren Sie Für Netzwerk freigeben in Ollama.set_max_messages(20)behält einen kurzen Gesprächsverlauf. Verringern Sie dies, wenn Speicher/Latenz knapp sind.
Versteckte Gedankengänge/Tags vor dem Sprechen entfernen
def strip_thinking(text: str) -> str:
if not text:
return ""
text = re.sub(r"<\s*think[^>]*>.*?<\s*/\s*think\s*>", "", text, flags=re.DOTALL|re.IGNORECASE)
text = re.sub(r"<\s*thinking[^>]*>.*?<\s*/\s*thinking\s*>", "", text, flags=re.DOTALL|re.IGNORECASE)
text = re.sub(r"```(?:\s*thinking)?\s*.*?```", "", text, flags=re.DOTALL|re.IGNORECASE)
text = re.sub(r"\[/?thinking\]", "", text, flags=re.IGNORECASE)
return re.sub(r"\s+\n", "\n", text).strip()
Einige Modelle geben interne Tags aus (z.B. <think>…).
Diese Funktion entfernt diese, so dass Ihre TTS nur die endgültige Antwort spricht.
Tipp: Wenn Sie andere Artefakte auf dem Bildschirm sehen (weil Sie rohe Token streamen), stellt diese Funktion bereits sicher, dass die gesprochene Ausgabe sauber bleibt.
Hauptschleife: Einmal begrüßen, dann hören → denken → sprechen
print(WELCOME)
tts.say(WELCOME)
Begrüßt den Benutzer über Terminal und Lautsprecher. Geschieht einmal beim Start.
Hören (Streaming-STT mit Live-Teilergebnissen)
print("\n🎤 Höre zu... (Drücke Strg+C zum Beenden)")
text = ""
for result in stt.listen(stream=True):
if result["done"]:
text = result["final"].strip()
print(f"[DU] {text}")
else:
print(f"[DU] {result['partial']}", end="\r", flush=True)
stream=Trueliefert partielle Transkripte für sofortiges Feedback und ein endgültiges Transkript, wenn die Äußerung endet.Der endgültig erkannte Text wird in
textgespeichert und einmal ausgegeben.
Schutz: Wenn nichts erkannt wurde, überspringen Sie den LLM-Aufruf:
if not text:
print("[INFO] Nichts erkannt. Versuche es erneut.")
time.sleep(0.1)
continue
Dies vermeidet das Senden leerer Eingabeaufforderungen an das Modell (spart Zeit und Tokens).
Denken (LLM) mit gestreamter Ausgabe
reply_accum = ""
response = llm.prompt(text, stream=True)
for next_word in response:
if next_word:
print(next_word, end="", flush=True)
reply_accum += next_word
print("")
Sendet das endgültige Transkript an das lokale LLM und gibt Token aus, während sie eintreffen für geringe Latenz.
Gleichzeitig sammeln Sie die vollständige Antwort in
reply_accumfür die Nachbearbeitung.
Hinweis: Wenn Sie die rohen Token nicht anzeigen möchten, setzen Sie stream=False und geben Sie nur die endgültige Zeichenkette aus.
Sprechen (zuerst bereinigen, dann einmal TTS)
clean = strip_thinking(reply_accum)
if clean:
tts.say(clean)
else:
tts.say("Entschuldigung, das habe ich nicht verstanden.")
Bereinigt den endgültigen Text, um versteckte Tags zu entfernen, und spricht dann genau einmal.
Wenn TTS auf einen einzigen Durchlauf beschränkt bleibt, werden wiederholte Aufforderungen wie „[LLM] / [SAGEN]“ vermieden.
Beenden und Aufräumen
except KeyboardInterrupt:
print("\n[INFO] Stoppe...")
finally:
tts.say("Auf Wiedersehen!")
print("Tschüss.")
Verwenden Sie Strg+C zum Stoppen. Der Bot sagt einen kurzen Abschiedsgruß, um ein sauberes Ende zu signalisieren.
Fehlerbehebung & FAQ
Modell ist zu groß (Speicherfehler)
Verwenden Sie ein kleineres Modell wie
moondream:1.8boder führen Sie Ollama auf einem leistungsstärkeren Computer aus.Keine Antwort von Ollama
Stellen Sie sicher, dass Ollama läuft (
ollama serveoder Desktop-App geöffnet). Bei Remote-Zugriff aktivieren Sie Für Netzwerk freigeben und überprüfen Sie die IP-Adresse.Vosk erkennt Sprache nicht
Überprüfen Sie, ob Ihr Mikrofon funktioniert. Versuchen Sie bei Bedarf ein anderes Sprachpaket (
de,en-us,esetc.).Piper ist stumm oder gibt Fehler aus
Bestätigen Sie, dass das ausgewählte Sprachmodell heruntergeladen und in 1. Piper testen getestet wurde.
Antworten zu lang oder themenfremd
Bearbeiten Sie
INSTRUCTIONS, um hinzuzufügen: „Halte Antworten kurz und prägnant.“