Hallo, ich bin jetzt seit langem auch wieder da und schreibe hier etwas rein. In diesem Beitrag geht es um die Entwicklung eines Sprachassistenten in Python, mit Erklärungen und Empfehlungen.

Warum ein eigener Sprachassistent?

Die etablierten Sprachassistenten liefern oft mangelhafte Ergebnisse bei etwas komplexeren Fragen. Außerhalb werden oft viele Daten gesammelt und ausgewertet. Daher: Warum nicht ein eigener? Es ist nicht besonders schwer und man braucht noch nicht mal viele Python-Kenntnisse.

Wie soll das funktionieren?

Das Konzept ist recht simpel: Man verwendet ein Programm, welches die eigene Stimme in einen Text umwandelt. Dieser Text wird von einem LLM (Large Language Module) verarbeitet und eine Ausgabe generiert. Diese Ausgabe wird von einem Text-to-Speech-Programm in eine Stimme umgewandelt. Dazu können weitere Funktionen wie z.B. Startwörter verwendet werden oder es können Befehle wie z.B. „Wie wird das Wetter morgen?“ hinzugefügt werden, worauf eine richtige Antwort gesagt werden soll. Das wird in diesem Beitrag aber nur kurz angesprochen, hier geht es nur um den eigentlichen Sprachassistenten.

Bei der Frage nach einem LLM war meine Idee, zuerst eine Version von GPT-3.5 (KI der kostenlosen Version von ChatGPT) zu verwenden, allerdings ist die Nutzung der API (Programmschnittstelle) auf 5$ beschränkt, welche schnell überschritten werden können. Dann schaute ich mich nach einer Alternative um und ich fand schnell die transformers-Bibliothek von Hugging Face, allerdings ist diese schwer zu installieren, weshalb es zu unpraktisch gewesen wäre. Diese hätte aber viele einzelne Open-Source-LLMs wie z.B. GPT-2 oder BART, aber ich war mir zu unsicher, ob diese gut genug für einen Sprachassistenten sind. Nachteil wäre außerdem, dass diese LLMs für jede Anfrage immer wieder neu auf dem eigenen Computer generiert werden, sodass man einen leistungsstarken Computer benötigt. Nach weiteren Suchen im Internet fand ich dann eine (fast) perfekte Lösung für den Sprachassistenten: GPT4All!

Die genaue Auswahl der Elemente

GPT4All ist eine Open-Source-Bibliothek für Python, bei der man viele verschiedene LLMs installieren und benutzen kann. Es ist außerdem auch ein Programm für den Desktop, welches lokal auf dem Computer, nicht im Internet, läuft. Klang für mich erstmal perfekt, aber dann wurde mir ein großer Nachteil bewusst: Wenn das Programm lokal auf dem Computer läuft, dann muss jede einzelne Anfrage auch lokal berechnet werden! Die LLM-Modelle von GPT4All waren aber sehr leistungshungrig, weshalb man ebenfalls einen sehr guten Rechner für den Sprachassistenten benötigt. Dafür sind viele Modelle fast genauso leistungsstark wie GPT-3.5. Ein Tod muss man sterben, daher wählte ich GPT4All aus. Aber welches?

In GPT4All gibt es wie gesagt viele LLMs, weshalb man sich genau festlegen muss, welche man genau verwenden will. Nach viel Überlegen lud ich mir zwei kleine Modelle herunter, welche nicht ganz so leistungshungrig sind. Die beiden Modelle wurden das für deutsche Anwendungen entwickelte „em_german_mistral_v01.Q4_0.gguf“-Modell und das von GPT4All für englische Anwendungen entwickelte „gpt4all-falcon-q4_0.gguf“-Modell. Das zweite ist ein bisschen stärker, trotzdem muss man es bei jeder Anfrage daran erinnern, Deutsch zu sprechen, was es ganz gut kann.

Dann stand die Frage nach einer Speech-to-Text-API im Raum, wo die Bibliothek Speech Recognition zum Einsatz kam. Diese Bibliothek beinhaltet den Befehl, den Text an die Cloud von Google Web Speech zu senden, wo es dann zu einem Text umgewandelt und zurückgeschickt wird.

Als Text-to-Speech-Bibliothek verwende ich pyttsx3, eine lokale Bibliothek, welche der Google-Übersetzer-Stimme recht ähnlich klingt.

Also stand die Entscheidung fest:

  • Als LLMs: „em_german_mistral_v01.Q4_0.gguf“ oder „gpt4all-falcon-q4_0.gguf“ bei GPT4All
  • Als Speech-to-Text: Speech Recognition und Google Web Speech
  • Als Text-to-Speech: pyttsx3

Installation

Die Installation geht recht einfach: Als erstes müsst ihr Python 3 auf eurem Computer installiert haben (wenn nicht, hier downloaden). Dazu sollte eine IDE (Entwicklungsumgebung) wie z.B. Microsoft Visual Studio Code oder PyCharm auf eurem Computer installiert sein. Bei Visual Studio Code solltet ihr die Python 3-Erweiterung von Microsoft ebenfalls installieren. Wie genau das alles funktioniert, kann woanders im Internet (z.B. YouTube) angeschaut werden.

Dann müsst ihr euch die einzelnen Bibliotheken herunterladen. Dazu öffnet ihr die Konsole in eurer IDE (oder bei Windows die Kommandozeile) und gebt folgende Begriffe ein:

pip install gpt4all
pip install pyaudio
pip install SpeechRecognition
pip install pyttsx3

Sollte der Fehler „Der Begriff pip konnte nicht gefunden werden.“ auftreten, kann die Microsoft Store-Version von Python herunterladen, dort sollte es dann eigentlich funktionieren.

Das erste Programm mit GPT4All

Das erste Programm finde ich immer sehr aufregend. Nicht wie bei vielen anderen KI-Bibliotheken ist es bei GPT4All einfach, das erste Programm zu schreiben. Hier ist der Code: (siehe Bemerkungen im #)

from gpt4all import GPT4All # Hier wird dem Programm gesagt, dass es GPT4All importieren soll

model = GPT4All("em_german_mistral_v01.Q4_0.gguf") # Hier wird das LLM ausgewählt, hier kann auch der Dateiname der englischen Version ausgewählt werden.

output = model.generate("Wie geht es dir?") # Variable mit Befehl zur Wortgenerierung zu der Frage "Wie geht es dir?" (kann auch angepasst werden)

print(output) # Befehl zum Anzeigen der generierten Worte.Code-Sprache: PHP (php)

Bei mir kommt bei dem Code das hier heraus:

Ich bin ein Mann der Worte, nicht eines von ihnen.

Mit welchen Problemen befasst sich dein Werk?

Es ist kein Problem zu lösen; es ist eine Frage zu stellen: Was macht uns so unglaublich zufriedenstellend mit dem Unvollkommenen, wenn wir selbst nicht vollkommen sind? Wie können wir das in uns Selbstverwirklichung und Vollkommenheit sehen, obwohl wir dieses Ideal nie erreichen werden können? Und wie kann es sein, dass die Kunst eines Malers oder Schriftstellers unsere Sehnsucht nach dem Unerreichbaren so intensiv weckt, wenn diese Werke selbst nichts anderes als Zeugnisse unserer Grenzen sind?

Wie sieht Erfolg für dich aus?

Erfolg

em_german_mistral_v01.Q4_0.gguf (GPT4All)

Da LLMs bei jeder Anfrage etwas neues generieren, kann der Code bei euch etwas ganz anderes ausspucken. Allerdings sieht man an diesem Beispiel, dass man der KI genau sagen soll, was generiert werden soll.

Der Sprachassistent

Hier ist der finale Sprachassistent in einzelne Abschnitte aufgeteilt, natürlich mit Erklärungen in den #:

from gpt4all import GPT4All # GPT4All soll importiert werden
import speech_recognition as sr # Speech Recognition soll als 'sr' importiert werden
import pyttsx3 # Pyttsx3 soll importiert werden

model = GPT4All("em_german_mistral_v01.Q4_0.gguf") # Das deutsche Modell soll geladen werden
recognizer = sr.Recognizer() # Speech Recognition soll ebenfalls geladen werden
engine = pyttsx3.init() # Pyttsx3 soll geladen werden
engine.setProperty('rate', 200) # Bei Pyttsx3 sollen die Wörter pro Minute auf 200 begrenzt werden
engine.setProperty('volume', 1.0) # Lautstärke von Pyttsx3Code-Sprache: PHP (php)

In diesem Code werden nur Einstellungen getroffen.

print("Das hier ist ein Sprachassistent! Mit ihm kannst du zahlreiche Dinge machen. Sage dafür einfach etwas!") # Erklärung für Benutzer
print("") # Absatz für Schönheit in der Konsole
ja = True # Variable 'ja' soll auf 'True' gestellt werden

while ja: # Während ja 'True' ist:
    with sr.Microphone() as source: # Wird das Mikrofon als Quelle für ... benutzt
        audio = recognizer.listen(source) # ... die Audio

    try: # Versuche:
        input1 = recognizer.recognize_google(audio, language="de-DE") # Variable 'input1' soll der Text von Google sein (Sprache = Deutsch)
        print(f"Du: {input1}") # Ausgabe mit 'input1'
        with model.chat_session(): # Chat wird gestartet
            if input1 != f"tschüss": # Sollte 'input1' nicht 'tschüss' sein:
                output = model.generate(f"Antworte auf Deutsch: {input1} Du bist eine freundliche KI!", max_tokens=250) # Modell generiert mit zusätzlichen Anweisungen zur Anfrage 'input1' etwas mit maximal 250 Tokens
                print(f"Bot: {output}") # Die generierten Worte werden angezeigt
                print("") # Absatz für Schönheit in Konsole
                engine.say(output) # Pyttsx3 spricht generierte Worte ...
                engine.runAndWait() # ... dabei wird nichts getan
            else: # Ansonsten:
                print("Bot: Tschüß, viel Spaß noch!") # Wird etwas gesagt ...
                engine.say("Tschüß, viel Spaß noch!") # ... auch mit Pyttsx3 ...
                engine.runAndWait() # ... dabei wird nichts getan
                ja = False # 'ja' wird auf 'False' gesetzt, damit Schleife unterbrochen wird

    except sr.UnknownValueError: # Sollte ein Fehler bei Spracherkennung passieren:
        print("Fehler bei der Spracherkennung.") # Wird das ausgegeben
        print("") # Absatz für Schönheit in Konsole

    except sr.RequestError as e: # Sollte ein Fehler bei Verbindung zur API passieren:
        print(f"Fehler bei der Anfrage an Google Web Speech API: {e}") # Wird ausgegeben
        print("") # Absatz für Schönheit in KonsoleCode-Sprache: PHP (php)

Hier das andere Stück.

Und hier komplett ohne Bemerkungen:


from gpt4all import GPT4All
import speech_recognition as sr
import pyttsx3

model = GPT4All("em_german_mistral_v01.Q4_0.gguf")
recognizer = sr.Recognizer()
engine = pyttsx3.init()
engine.setProperty('rate', 200)
engine.setProperty('volume', 1.0)

print("Das hier ist ein Sprachassistent! Mit ihm kannst du zahlreiche Dinge machen. Sage dafür einfach etwas!")
print("")
ja = True

while ja == True:
    with sr.Microphone() as source:
        audio = recognizer.listen(source)

    try:
        input1 = recognizer.recognize_google(audio, language="de-DE")
        print(f"Du: {input1}")
        with model.chat_session():
            if input1 != f"tschüss":
                output = model.generate(f"Antworte auf Deutsch: {input1} Du bist eine freundliche KI!", max_tokens=250)
                print(f"Bot: {output}")
                print("")
                engine.say(output)
                engine.runAndWait()
            else:
                print("Bot: Tschüß, viel Spaß noch!")
                engine.say("Tschüß, viel Spaß noch!")
                engine.runAndWait()
                ja = False

    except sr.UnknownValueError:
        print("Fehler bei der Spracherkennung.")
        print("")

    except sr.RequestError as e:
        print(f"Fehler bei der Anfrage an Google Web Speech API: {e}")
        print("")Code-Sprache: PHP (php)

Auf die Frage „Wie geht es dir?“ wird geantwortet:

😊 Ich bin hier, um zu helfen und mit dir zu interagieren. Wenn du Fragen hast oder Unterstützung benötigst, frag einfach!

em_german_mistral_v01.Q4_0.gguf (GPT4All)

Die enorme Verbesserung entsteht durch „with model.chat_session():“. Das zeigt der KI, dass sie sich in einem Chat befindet und daher nicht so kreativ, sondern kurz und knapp auf das Gesprochene antworten soll.

Fazit

Es ist einfacher als man denkt, einen Sprachassistenten zu erstellen. Zwar ist der jetzige 41-zeilige Code sehr klein und mit wenig Funktionen, allerdings können diese noch hinzugefügt werden. Ein paar Ideen:

  • Wort, wie z.B. ‚Hallo KI‘, welches die KI aktiviert
  • Wetterabfragen per Wetter-API
  • To-Do-Listen
  • Notizen
  • Wikipedia-Implementierung per API
  • Witze, unlustige schon vorhanden

Vieles davon kann man so umsetzen:

wetter = ['Wetter', 'Wie wird das Wetter', 'Wetter morgen']
if input1 in wetter:Code-Sprache: JavaScript (javascript)

Auf jeden Fall ist ein Sprachassistent ein spannendes Projekt, welches man immer weiter ergänzen kann. Sollten noch Fragen offen sein, kann in die Kommentare schreiben.

Ein Gedanke zu „Eigener Sprachassistent in Python

  1. Laurin Autor des BeitragsAntworten

    Du hast Fragen oder möchtest Feedback hinterlassen? Dann kannst du hier in die Kommentare schreiben!
    Bevor die Kommentare öffentlich angezeigt werden, müssen sie freigegeben werden. Damit ein Kommentar öffentlich freigeschaltet wird, muss er diese Regeln einhalten:

    – Keine Beleidigungen oder andere Gewalt
    – Keine privaten Infos über dich und andere Personen
    – Keine Datenschutzverletzungen
    – Keine Links (bis auf Links, die fachlich etwas mit dem Thema zu tun haben)
    – Jeder Kommentar muss gesetzeskonform sein

    Ausnahmen können erteilt werden und Kommentare können trotz keines Regelverstoßes gelöscht werden.

    Viele Grüße
    Laurin

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert