{"id":1173,"date":"2025-09-12T12:00:00","date_gmt":"2025-09-12T10:00:00","guid":{"rendered":"https:\/\/matthias-gloeckner.de\/blog\/?p=1173"},"modified":"2025-09-20T13:21:47","modified_gmt":"2025-09-20T11:21:47","slug":"whisper-transkription-offline-nutzen","status":"publish","type":"post","link":"https:\/\/matthias-gloeckner.de\/blog\/whisper-transkription-offline-nutzen\/","title":{"rendered":"Whisper-Transkription offline nutzen"},"content":{"rendered":"<div style=\"text-align: right; font-style: italic;\">Version vom 12.09.2025<\/div>\n<p><\/p>\n<div style=\"text-align: justify;\">\n<a href=\"#Einleitung\">1. Einleitung<\/a><br \/>\n<a href=\"#Voraussetzungen\">2. Voraussetzungen<\/a><br \/>\n<a href=\"#Whisper\">3. Whisper<\/a><br \/>\n<a href=\"#WhisperAlsDiktiersoftware\">4. Whisper als Diktiersoftware<\/a><br \/>&nbsp;<\/p>\n<h2><a name=\"Einleitung\">1. Einleitung<\/a><\/h2>\n<p><\/p>\n<p>Viele Anwendungen der K\u00fcnstlichen Intelligenz (KI) k\u00f6nnen nur im Internet genutzt werden, z. B. die Chatbots <a href=\"https:\/\/chatgpt.com\" rel=\"noreferrer noopener\" target=\"_blank\">ChatGPT<\/a>, <a href=\"https:\/\/claude.ai\" rel=\"noreferrer noopener\" target=\"_blank\">Claude<\/a> und <a href=\"https:\/\/chat.mistral.ai\/chat\" rel=\"noreferrer noopener\" target=\"_blank\">Le Chat<\/a>. Offline gibt es dazu keine gleichwertigen Alternativen. Aber mit deutlichen Abstrichen an Leistungsf\u00e4higkeit und Schnelligkeit k\u00f6nnen <a href=\"https:\/\/www.youtube.com\/watch?v=3kBr0KhDqPw\" rel=\"noreferrer noopener\" target=\"_blank\">quelloffene KI-Modelle lokal genutzt werden<\/a>, ohne dass Daten den eigenen Rechner verlassen.<\/p>\n<p>Sicherer f\u00fcr den Datenschutz und die langfristige Verf\u00fcgbarkeit ist es, von Plattformen wie <a href=\"https:\/\/huggingface.co\/models\" rel=\"noreferrer noopener\" target=\"_blank\">Hugging Face<\/a> und <a href=\"https:\/\/github.com\/\" rel=\"noreferrer noopener\" target=\"_blank\">Github<\/a> Sprachmodelle kostenlos herunterzuladen. Auf dem eigenen Rechner lassen sie sich dann ohne Verbindung ins Internet zeitlich unbegrenzt nutzen. So k\u00f6nnen auch vertrauliche Daten verarbeitet werden. Ein Nachteil ist die wesentlich langsamere Verarbeitungsgeschwindigkeit.<\/p>\n<p>Ein relativ einfacher Einstieg in die Arbeit mit Sprachmodellen der K\u00fcnstlichen Intelligenz ist die im Jahr 2022 von dem US-amerikanischen Unternehmen OpenAI ver\u00f6ffentlichte <a href=\"https:\/\/openai.com\/de-DE\/index\/whisper\/\" rel=\"noreferrer noopener\" target=\"_blank\">Whisper-Spracherkennung<\/a>. Getestet habe ich die Installationen jeweils auf den Betriebssystemen Windows 11 Pro 24H2 und <a href=\"https:\/\/www.linuxmint.com\/download.php\" rel=\"noreferrer noopener\" target=\"_blank\">Linux Mint 22.2 Zara<\/a>. Klar zu bevorzugen ist dabei Linux: die Installation hat dort weniger Schritte und bei meinen Versuchen lief Whisper hinterher schneller als unter Windows. <\/p>\n<p>Whisper ist eine Software, mit der man Audioaufzeichnungen in rund 100 Sprachen zu Text transkribieren kann. Die von \u00e4lterer Diktiersoftware bekannte Trainingsphase mit der eigenen Stimme entf\u00e4llt ebenso wie eine Datenverarbeitung in der Cloud. Zus\u00e4tzlich erm\u00f6glicht Whisper eine \u00dcbersetzung von Audioaufzeichnungen in allen diesen Sprachen nach Englisch in hoher Qualit\u00e4t. Neben der allgemeinen Langsamkeit von Sprachmodellen auf Alltags-Hardware hat Whisper den Nachteil, keine Diktiersoftware zu sein. Befehle wie \u00bbZitat Anfang\u00ab oder \u00bbneuer Absatz\u00ab kennt es nicht. Mit der Funktion \u00bbSuchen und Ersetzen\u00ab in einer beliebigen Textverarbeitungssoftware oder mit etwas Geschick im Programmieren k\u00f6nnen die erkannten Texte jedoch nachbearbeitet werden.<br \/>&nbsp;<\/p>\n<h2><a name=\"Voraussetzungen\">2. Voraussetzungen<\/a><\/h2>\n<p><\/p>\n<p>Dieser Abschnitt beschreibt gemeinsame Grundlagen einer Installation von Whisper und von Sprachmodellen mit Chat-Funktionen, wie sie z. B. auf Hugging Face zu finden sind. Auch wer mit den dortigen <a href=\"https:\/\/de.wikipedia.org\/wiki\/Large_Language_Model\" rel=\"noreferrer noopener\" target=\"_blank\">gro\u00dfen Spachmodellen<\/a> experimentieren m\u00f6chte, findet in diesem Abschnitt einige Grundlagen.<br \/>&nbsp; <\/p>\n<h3>2.1. Kommandozeile statt grafischer Benutzeroberfl\u00e4che<\/h3>\n<p><\/p>\n<p>Die M\u00f6glichkeiten des <a href=\"https:\/\/de.wikipedia.org\/wiki\/Maschinelles_Lernen\" rel=\"noreferrer noopener\" target=\"_blank\">Maschinellen Lernens<\/a> entwickeln sich schnell und bringen immer neue Anwendungsm\u00f6glichkeiten und Datenformate hervor. Grafische Benutzeroberfl\u00e4chen daf\u00fcr zu programmieren und zu aktualisieren kostet Zeit, die man lieber zun\u00e4chst f\u00fcr die inhaltliche Besch\u00e4ftigung mit diesen technischen Fortschritten verwendet. Eine Benutzeroberfl\u00e4che zu bauen, die auf verschiedenen Betriebssystemen gleicherma\u00dfen gut l\u00e4uft, ist bis heute keine triviale Aufgabe. Beim L\u00f6sen auch dieses Problems k\u00f6nnen KI-Chatbots schon jetzt hilfreich sein.<\/p>\n<p>Textgeneratoren haben den Vorteil, dass sie nur mit Text arbeiten. Daher lassen sie sich auch ohne grafische Benutzeroberfl\u00e4che gut nutzen. Ein Programm, das Texte einlesen und ausgeben kann, hatten Computer schon, als grafische Anwendungsfenster noch nicht erfunden waren. Dieses Terminal, auch Konsole oder Eingabeaufforderung genannt, gibt es bis heute in allen Betriebssystemen. Damit werden wir arbeiten.<\/p>\n<p>Unter Windows \u00f6ffnet man das Terminal mit der Tastenkombination <code style=\"font-weight: bold;\">Windows + R<\/code>. Das blendet das kleine Fenster zum Ausf\u00fchren eines Programms ein. Dort hinein tippt man entweder <code style=\"font-weight: bold;\">cmd<\/code> oder <code style=\"font-weight: bold;\">wt<\/code> (nur Windows 11) und best\u00e4tigt mit der <code style=\"font-weight: bold;\">Eingabetaste<\/code>. Unter Linux \u00f6ffnet man das Terminal mit der Tastenkombination <code style=\"font-weight: bold;\">Strg + Alt + T<\/code>.<\/p>\n<p>Ein weiterer Weg zum \u00d6ffnen des Terminals ist es, im Datei-Explorer das Kontextmen\u00fc zu nutzen. Dazu klickt man mit der rechten Maustaste auf eine freie Stelle (d.h. wo keine Datei und kein Verzeichnis ist) und w\u00e4hlt dann \u00bbIn Terminal \u00f6ffnen\u00ab (Windows) bzw. \u00bbIm Terminal \u00f6ffnen\u00ab (Linux). Das ist praktisch, wenn man ein Kommando in das Terminal eingeben m\u00f6chte, das sich auf eine Datei bezieht, die in dem Verzeichnis liegt, das der Datei-Explorer gerade anzeigt. Sonst m\u00fcsste der ganz Verzeichnispfad bis zur Datei mit in das Terminal getippt werden.<\/p>\n<p>Zum Schlie\u00dfen des Terminals gibt man <code style=\"font-weight: bold;\">Alt + F4<\/code> oder <code style=\"font-weight: bold;\">exit<\/code> ein. Unter Linux funktioniert auch <code style=\"font-weight: bold;\">Strg + D<\/code>. In der Suche findet man das Terminal unter den Begriffen \u00bbTerminal\u00ab oder \u00bbEingabeaufforderung\u00ab. In beiden Betriebssystemen kann das Terminal auch \u00fcber das entsprechende Symbol im Startmen\u00fc ge\u00f6ffnet und per Mausklick auf das kleine Kreuz am oberen rechten Fensterrand wieder geschlossen werden. <\/p>\n<p>Das Terminal in Windows 11 hat in der Titelzeile einen kleinen, nach unten zeigenden Pfeil. Der Einfachheit halber w\u00e4hlen wir dort \u00bbEingabeaufforderung\u00ab aus, nicht \u00bbWindows Power Shell\u00ab oder \u00bbAzure Cloud Shell\u00ab. Dort unter \u00bbEinstellungen\u00ab l\u00e4sst sich die Ergabeaufforderung als \u00bbStandardprofil\u00ab setzen. Ganz unten in den Einstellungen muss dann noch \u00bbSpeichern\u00ab angeklickt werden.<\/p>\n<p>Wir werden das Terminal oft brauchen und k\u00f6nnen es nach dem ersten \u00d6ffnen direkt an die Taskleiste heften. Dazu klickt man mit der rechten Maustaste auf dessen Symbol mit dem <code style=\"font-weight: bold;\">&gt;_<\/code> (Windows) bzw. <code style=\"font-weight: bold;\">$_<\/code> (Linux) im schwarzen Rechteck und klickt dann mit der linken Maustaste auf \u00bbAn Taskleiste anheften\u00ab (Windows) bzw. \u00bbAn der Leiste anheften\u00ab (Linux).<\/p>\n<p>Wir werden im Verzeichnis des gegenw\u00e4rtig auf dem Computer angemeldeten Benutzers arbeiten. Falls das Terminal ein anderes Verzeichnis anzeigt, macht man mit <code style=\"font-weight: bold;\">cd %userprofile%<\/code> (Windows) bzw. <code style=\"font-weight: bold;\">cd \/<\/code> (Linux) das Benutzerverzeichnis zum Arbeits&shy;verzeichnis.<br \/>&nbsp;<\/p>\n<h3>2.2. Python<\/h3>\n<p><\/p>\n<p>Whisper ist in der Programmiersprache <a href=\"https:\/\/de.wikipedia.org\/wiki\/Python_(Programmiersprache)\" rel=\"noreferrer noopener\" target=\"_blank\">Python<\/a> geschrieben. Kenntnisse in Python-Programmierung erleichtern die Nutzung solcher Textgeneratoren, sind aber nicht unbedingt erforderlich.<\/p>\n<p>Welche Version von Python auf dem Rechner installiert ist, findet man heraus, indem man im Terminal <code style=\"font-weight: bold;\">python -&#45;version<\/code> (Windows) bzw. <code style=\"font-weight: bold;\">python3 -&#45;version<\/code> (Linux) eingibt und mit der <code style=\"font-weight: bold;\">Eingabetaste<\/code> best\u00e4tigt. Ben\u00f6tigt wird eine Python-Version zwischen 3.9 und 3.11. Eine h\u00f6here Python-Version kann zu Problemen f\u00fchren. Aber ist eine h\u00f6here Version schon vorinstalliert, ist auch sie einen Versuch wert, bevor man ein Downgrade ausf\u00fchrt.<\/p>\n<p>In Linux ist Python schon enthalten. Sollte dem nicht so sein, kann Python im Terminal mit dem Befehl <code style=\"font-weight: bold;\">sudo apt install python3<\/code> oder in der grafischen Anwendungsverwaltung unter dem Suchwort <code style=\"font-weight: bold;\">Python3<\/code> installiert werden.<\/p>\n<p>Unter Linux erfordern dieser und die folgenden Installationsschritte Administrator-Rechte, in einem Standard-Benutzerkonto funktionieren sie nicht.<\/p>\n<p>Gibt Windows eine Fehlermeldung aus wie \u00bbPython konnte nicht gefunden werden\u00ab oder \u00f6ffnet sich der Windows Store, muss Python installiert werden. Dann aber am besten nicht aus dem  Windows Store, sondern direkt von <a href=\"https:\/\/www.python.org\/downloads\/\" rel=\"noreferrer noopener\" target=\"_blank\">https:\/\/www.python.org\/downloads\/<\/a><\/p>\n<p>Bitte achten Sie darauf, <span style=\"font-weight: bold;\">nicht<\/span> den neuesten Python-Installer zu nehmen, sondern maximal die Version 3.11. Innerhalb der jeweiligen Version w\u00e4hlt man am besten den \u00bbWindows installer (64-bit)\u00ab.<\/p>\n<p>Idealerweise pr\u00fcft man nach dem Herunterladen die Echtheit des Installers anhand seiner MD5-Pr\u00fcfsumme am Ende der Download-Seite. Es k\u00f6nnte ja sein, dass Hacker in den Installer nachtr\u00e4glich einen Virus eingebaut haben oder dass einfach das Herunterladen der Datei vorzeitig abgebrochen ist. Wem die gesch\u00e4tzten 99% Sicherheit gen\u00fcgen, dass auch ohne diesen Schritt alles gut geht, kann ihn \u00fcberspringen.<\/p>\n<p>Unter Linux f\u00fchrt die Paketverwaltung die Integrit\u00e4tspr\u00fcfung automatisch im Hintergrund aus und der Benutzer muss nichts daf\u00fcr tun. Wer unter Windows die Integrit\u00e4tspr\u00fcfung nicht \u00fcberspringt, \u00f6ffnet im Verzeichnis mit dem heruntergeladenen Installer (meist \u00bbDownloads\u00ab) das Terminal (im Kontextmen\u00fc nach einem Klick mit der rechten Maustaste, siehe 2.1.), gibt <code style=\"font-weight: bold;\">certutil -hashfile python-3.11.6-amd64.exe md5<\/code> ein und best\u00e4tigt mit der <code style=\"font-weight: bold;\">Eingabetaste<\/code>. Wurde ein anderer Installer gew\u00e4hlt, muss der Name der zu pr\u00fcfenden Datei entsprechend angepasst werden.<\/p>\n<p>Die im Terminal angezeigte Pr\u00fcfsumme markiert man anschlie\u00dfend mit der Maus und kopiert sie mit <code style=\"font-weight: bold;\">Strg + C<\/code> in die Zwischenablage. Auf der Download-Seite des Python-Installers sucht man im Browser nach dieser Zeichenkombination mit  <code style=\"font-weight: bold;\">Strg + C<\/code> dann <code style=\"font-weight: bold;\">Strg + V<\/code>. Wird die Pr\u00fcfsumme gefunden und steht in der Zeile, die zu dem heruntergeladenen Installer geh\u00f6rt, ist die \u00dcberpr\u00fcfung erfolgreich und der Installer kann verwendet werden. <\/p>\n<p>Zum Start der Python-Installation unter Windows doppelklickt man auf den Installer und setzt im Installationsdialog ganz unten noch das H\u00e4kchen bei \u00bbAdd python.exe to PATH\u00ab. Um Python auch f\u00fcr andere Windows-Benutzerkonten verf\u00fcgbar zu machen, klickt man auf \u00bbCustomize installation\u00ab, \u00bbNext\u00ab und setzt ganz oben das H\u00e4kchen bei \u00bbInstall Python 3.xx for all users\u00ab. Nach Klick auf \u00bbInstall Now\u00ab bzw. \u00bbInstall\u00ab bittet Windows, die Installation mit Klick auf \u00bbJa\u00ab zu best\u00e4tigen. Hat man das getan und erh\u00e4lt man die Nachricht \u00bbSetup was successful\u00ab, kann das Installations\u00adfenster geschlossen werden.<\/p>\n<p>Vor der ersten Verwendung von Python muss das Terminal einmal geschlossen und neu ge\u00f6ffnet werden.<br \/>&nbsp;<\/p>\n<h3>2.3. Python pip<\/h3>\n<p><\/p>\n<p>Um in Python geschriebene KI-Anwendungen auf den Rechner herunterzuladen, wird der Paketmanager \u00bbPython pip\u00ab ben\u00f6tigt. Mit ihm verh\u00e4lt es sich anders herum als mit der Installation von Python selbst: unter Windows wurde \u00bbPython pip\u00ab durch den Python-Installer schon mit installiert, unter Linux fehlt es wahrscheinlich noch.<\/p>\n<p>Um herauszufinden, ob Python pip auf dem Rechner installiert ist und falls ja, in welcher Version, gibt man im Terminal <code style=\"font-weight: bold;\">pip -&#45;version<\/code> ein und bet\u00e4tigt anschlie\u00dfend die <code style=\"font-weight: bold;\">Eingabetaste<\/code>.<\/p>\n<p>Falls Python pip unter Linux noch fehlt, ist im Terminal <code style=\"font-weight: bold;\">apt -y install python3-pip<\/code> einzugeben und mit der <code style=\"font-weight: bold;\">Eingabetaste<\/code> zu best\u00e4tigen. Anschlie\u00dfend muss das Benutzerpasswort eingegeben werden.<br \/>&nbsp;<\/p>\n<h3>2.4. Virtuelle Python-Umgebung<\/h3>\n<p><\/p>\n<p>Arbeitet man an mehreren Python-Projekten zugleich, ist es n\u00fctzlich, sie logisch von einander zu trennen. Denn zwischen Projekten, die nichts mit einander zu tun haben, m\u00f6chte man nicht die Versionsnummern aller verwendeten Programmbibliotheken abgleichen m\u00fcssen. St\u00fcrzt ein Projekt ab, will man nicht, dass dieser Fehler Auswirkungen auf andere Projekte hat. Deshalb gibt es in Python virtuelle Umgebungen. Auf die virtuelle Python-Umgebung verzichten kann nur, wer kurz etwas ausprobieren m\u00f6chte und Python anschlie\u00dfend wieder deinstalliert. Also fast niemand.<\/p>\n<p>Unter Linux muss im Terminal <code style=\"font-weight: bold;\">apt -y install python3-venv<\/code> eingegeben und mit der <code style=\"font-weight: bold;\">Eingabetaste<\/code> best\u00e4tigt werden. Anschlie\u00dfend ist das Benutzerpasswort einzugeben. In Windows wurde \u00bbvenv\u00ab schon gemeinsam mit Python installiert.<\/p>\n<p>In dem nun folgenden Beispiel ist \u00bb[Benutzer]\u00ab der Name des Benutzerverzeichnisses unterhalb von \u00bb[Laufwerk:]\\Users\u00ab (Windows) bzw. \u00bb\/home\u00ab (Linux). H\u00e4ufig, aber nicht immer, ist er identisch mit dem Login-Namen. \u00bb[Projekt]\u00ab ist im folgenden Beispiel der Name eines Python-Projekts, z. B. Whisper oder MeinTestProjekt.<\/p>\n<p>Eine virtuelle Umgebung in Windows richtet man im Terminal mit dem folgenden Befehl ein: <code style=\"font-weight: bold;\">python -m venv [Laufwerk:]\\Users\\[Benutzer]\\[Projekt]<\/code><\/p>\n<p>In Linux lautet der Befehl: <code style=\"font-weight: bold;\">python3 -m venv \/home\/[Benutzer]\/[Projekt]<\/code><\/p>\n<p>Startet man ein Terminal mit jeder anderen Methode als aus dem Kontextmen\u00fc eines Verzeichnisses heraus (siehe 2.1.), ist das Benutzerverzeichnis schon als das aktuelle Arbeitsverzeichnis voreingestellt. Dann gen\u00fcgt zum Anlegen einer neuen virtuellen Umgebung der Befehl <code style=\"font-weight: bold;\">python -m venv [Projekt]<\/code> (Windows) bzw. <code style=\"font-weight: bold;\">python3 -m venv [Projekt]<\/code> (Linux). Wenige Sekunden nach Dr\u00fccken der <code style=\"font-weight: bold;\">Eingabetaste<\/code> ist die neue Umgebung eingerichtet.<\/p>\n<p>Vor jeder Benutzung muss die virtuelle Umgebung aktiviert werden. Das geschieht mit <code style=\"font-weight: bold;\">[Projekt]\\Scripts\\activate<\/code> (Windows) bzw. <code style=\"font-weight: bold;\">source [Projekt]\/bin\/activate<\/code> (Linux).<\/p>\n<p>Nun steht der Name des Projekts (der virtuellen Umgebung) in Klammern links vor der Eingabeaufforderung und die hier eingegebenen Befehle bleiben ohne Auswirkung auf andere Python-Projekte. Wieder verlassen kann man die virtuelle Umgebung mit dem Befehl <code style=\"font-weight: bold;\">deactivate<\/code> oder durch Schlie\u00dfen des Terminals.<\/p>\n<p>Nun ist der Rechner f\u00fcr die Installation von Whisper oder beliebiger anderer Sprachmodelle vorbereitet.<br \/>&nbsp;<\/p>\n<h3>2.5. CUDA<\/h3>\n<p><\/p>\n<p>Wessen Rechner keine <a href=\"https:\/\/developer.nvidia.com\/cuda-gpus\" rel=\"noreferrer noopener\" target=\"_blank\">CUDA-f\u00e4hige Grafikkarte von NVIDIA<\/a> hat, kann diesen Abschnitt \u00fcberspringen. Alle Daten liegen dann im Arbeitsspeicher (RAM) oder ausgelagert auf der Festplatte, Berechnungen werden ausschlie\u00dflich auf dem Hauptprozessor (CPU) durchgef\u00fchrt.<\/p>\n<p><a href=\"https:\/\/de.wikipedia.org\/wiki\/CUDA\" rel=\"noreferrer noopener\" target=\"_blank\">CUDA (Compute Unified Device Architecture)<\/a> ist eine von NVIDIA entwickelte Programmierschnittstelle, mit der hochgradig parallelisierbare Berechnungen auf einem Grafikprozessor (GPU) abgearbeitet werden k\u00f6nnen. Die statistischen Modelle f\u00fcr K\u00fcnstliche Intelligenz sind parallelisierbar, so dass es einen Schnelligkeitsgewinn um ca. den Faktor 10 bis 20 bedeutet, wenn man \u00fcber einen Computer mit ausreichend CUDA-Rechenleistung und Video-RAM verf\u00fcgt.<\/p>\n<p>Eine Grundvoraussetzung, damit CUDA funktioniert, ist es, den Treiber der Grafikkarte aktuell zu halten. Das tut man entweder \u00fcber die NVIDIA-Treiberverwaltung (Windows) oder \u00fcber die Treiberverwaltung des Betriebssystems (Linux, unter Systemverwaltung => Treiberverwaltung). In dem unwahrscheinlichen Fall, dass die Installation aus dem Betriebssystem heraus scheitert, kann der Treiber direkt von der NVIDIA-Website heruntergeladen werden.<\/p>\n<p>Damit unter Linux der NVIDIA-Treiber nach seiner Installation tats\u00e4chlich zum Einsatz kommt, muss er einmalig in Secure Boot registriert werden. Der professionelle Weg daf\u00fcr ist, <a href=\"https:\/\/askubuntu.com\/questions\/1438024\/gpu-driver-not-loaded-when-secure-boot-is-enabled\" rel=\"noreferrer noopener\" target=\"_blank\">Secure Boot zu aktualisieren<\/a>. Die unprofessionelle Alternative w\u00e4re, Secure Boot im Boot-Men\u00fc zu deaktivieren. Unter Windows sollte dieses Problem mit Whisper nicht aufteten, kann sich aber bei der Arbeit mit anderen LLMs zeigen. <\/p>\n<p>Gro\u00dfe Sprachmodelle haben mehrere <a href=\"https:\/\/arxiv.org\/abs\/1706.03762\" rel=\"noreferrer noopener\" target=\"_blank\">Transformer-Schichten<\/a>, von denen auch nur ein Teil auf den CUDA-f\u00e4higen Grafikprozessor ausgelagert werden kann, w\u00e4hrend die \u00fcbrigen im RAM und auf der Festplatte berechnet werden. Whisper hat nur eine \u00bbSchicht\u00ab, die entweder ganz in den RAM oder ganz in den Video-RAM des Grafikprozessors passen muss.<\/p>\n<p>Die kleineren Whisper-Modelle bis einschlie\u00dflich \u00bbmedium\u00ab und \u00bbturbo\u00ab laufen mit 6 GB RAM (bzw. VRAM und CUDA). Die \u00bblarge\u00ab-Modelle <a href=\"https:\/\/github.com\/openai\/whisper?tab=readme-ov-file#available-models-and-languages\" rel=\"noreferrer noopener\" target=\"_blank\">ben\u00f6tigen 10 GB RAM<\/a> (bzw. VRAM und CUDA).<\/p>\n<p>Um zu \u00fcberpr\u00fcfen, ob CUDA verf\u00fcgbar ist, gibt man im Terminal <code style=\"font-weight: bold;\">nvidia-smi<\/code> ein. SMI steht f\u00fcr System Management Interface. Es muss eine Tabelle erscheinen, welche die NVIDIA-Treiber-Version, die CUDA-Version, den Typ der Grafikkarte, die Gr\u00f6\u00dfe des belegten und insgesamt vorhandenen Video-RAM und weitere Informationen zeigt.<br \/>&nbsp;<\/p>\n<h2><a name=\"Whisper\">3. Whisper<\/a><\/h2>\n<p><\/p>\n<h3>3.1. Git<\/h3>\n<p><\/p>\n<p>Der in der Programmiersprache Python geschriebene Programmkode f\u00fcr Whisper befindet sich auf <a href=\"https:\/\/github.com\/openai\/whisper\" rel=\"noreferrer noopener\" target=\"_blank\">https:\/\/github.com\/openai\/whisper<\/a>.<\/p>\n<p>Das Werkzeug der Wahl zum Herunterladen und Aktualisieren von Github-Quellkode ist die Software-Versionsverwaltung Git. Welche Version von Git auf dem Rechner installiert ist, findet man heraus, indem man im Terminal <code style=\"font-weight: bold;\">git --version<\/code> eingibt und mit der  <code style=\"font-weight: bold;\">Eingabetaste<\/code> best\u00e4tigt. Erscheint die Fehlermeldung, dass \u00bbgit\u00ab nicht gefunden wurde, muss es installiert werden.<\/p>\n<p>Unter Linux erf\u00fcllt der Befehl <code style=\"font-weight: bold;\">apt -y install git<\/code> diesen Zweck. Er ist mit der <code style=\"font-weight: bold;\">Eingabetaste<\/code> zu best\u00e4tigen. Anschlie\u00dfend muss das Benutzerpasswort eingegeben werden.<\/p>\n<p>F\u00fcr Windows kann Git von <a href=\"https:\/\/git-scm.com\/download\/win\" rel=\"noreferrer noopener\" target=\"_blank\">https:\/\/git-scm.com\/download\/win<\/a> heruntergeladen werden. Den anderen Installer dort f\u00fcr das Winget-Tool ben\u00f6tigen wir nicht.<\/p>\n<p>Der Windows-Installer wird mit Doppelklick gestartet. Als verifizierter Herausgeber muss Johannes Schindelin angezeigt werden. Ist das der Fall, kann die Installation mit Klick auf \u00bbJa\u00ab best\u00e4tigt werden. Alle Voreinstellungen des Installers k\u00f6nnen mit \u00bbNext\u00ab durchgeklickt und beibehalten werden. Ist die Installation beendet, schlie\u00dft der Installer sich selbstst\u00e4ndig.<br \/>&nbsp;<\/p>\n<h3>3.2. FFmpeg<\/h3>\n<p><\/p>\n<p>Zum Einlesen von Audiodateien ben\u00f6tigt Whisper das quelloffene Multimedia-Softwarepaket \u00bbFFmpeg\u00ab. Welche Version davon auf dem Rechner installiert ist, findet man heraus, indem man im Terminal <code style=\"font-weight: bold;\">ffmpeg -version<\/code> eingibt (hier mit nur einem &#8211; vor version) und mit der <code style=\"font-weight: bold;\">Eingabetaste<\/code> best\u00e4tigt. Erscheint die Fehlermeldung, dass der Befehl \u00bbffmpeg\u00ab nicht gefunden wurde, muss es installiert werden.<\/p>\n<p>Unter Linux erf\u00fcllt der Befehl <code style=\"font-weight: bold;\">apt -y install ffmpeg<\/code> diesen Zweck. Er ist mit der <code style=\"font-weight: bold;\">Eingabetaste<\/code> zu best\u00e4tigen. Anschlie\u00dfend muss das Benutzerpasswort eingegeben werden. Alternativ kann dieses Paket in der grafischen Anwendungsverwaltung unter dem Suchwort <code style=\"font-weight: bold;\">Ffmpeg<\/code> installiert werden.<\/p>\n<p>Unter Windows ben\u00f6tigen wir ein weiteres Hilfsprogramm: Chocolatey. F\u00fcr dessen Installation wird von der Seite <a href=\"https:\/\/chocolatey.org\/install\" rel=\"noreferrer noopener\" target=\"_blank\">https:\/\/chocolatey.org\/install<\/a> (ca. in der Mitte) folgender Befehl in die Zwischenablage kopiert:<\/div>\n<div style=\"text-align: left;\"><code style=\"font-weight: bold;\">Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https:\/\/community.chocolatey.org\/install.ps1'))<\/code><\/div>\n<p><\/p>\n<p>Um den in die Zwischenablage kopierten Befehl auszuf\u00fchren, suchen wir im Startmen\u00fc die Windows Power Shell (ohne den Zusatz ISE) und klicken mit der rechten Maustaste darauf. In dem nun erscheinenden Kontextmen\u00fc muss \u00bbAls Administrator ausf\u00fchren\u00ab gew\u00e4hlt und mit Klick auf \u00bbJa\u00ab best\u00e4tigt werden. In die Windows Power Shell hinein kopieren wir den Befehl und best\u00e4tigen ihn mit der <code style=\"font-weight: bold;\">Eingabetaste<\/code>.<\/p>\n<p>Ist die Installation von Chocolatey abgeschlossen, installieren wir FFmpeg. Der Befehl dazu kann in derselben Windows Power Shell wie eben ausgef\u00fchrt werden:<\/p>\n<p><code style=\"font-weight: bold;\">choco install ffmpeg<\/code><\/p>\n<p>W\u00e4hrend der Installation von FFmpeg muss das Ausf\u00fchren eines Skripts mit Druck auf die Taste <code style=\"font-weight: bold;\">Y<\/code> erlaubt werden. Damit die \u00c4nderungen wirksam sind, m\u00fcssen wir uns nach erfolgreicher Installationen aus Windows ausloggen und neu einloggen. Ein Neustart des Rechners geht auch.<br \/>&nbsp;<\/p>\n<h3>3.3. Whisper installieren<\/h3>\n<p><\/p>\n<p>Ab diesem Schritt kann auch mit Linux die Installation in einem Standard-Konto ohne Administrator-Rechte fortgesetzt werden. Jetzt legen wir mit dem Terminal eine virtuelle Umgebung an und aktivieren sie:<\/p>\n<p><code style=\"font-weight: bold;\">python -m venv Whisper<\/code> (Windows) bzw. <code style=\"font-weight: bold;\">python3 -m venv Whisper<\/code> (Linux)<br \/>\n<code style=\"font-weight: bold;\">Whisper\\Scripts\\activate<\/code> (Windows) bzw. <code style=\"font-weight: bold;\">source Whisper\/bin\/activate<\/code> (Linux).<\/p>\n<p>Anschlie\u00dfend installieren wir Whisper mit: <code style=\"font-weight: bold;\">pip install git+https:\/\/github.com\/openai\/whisper.git<\/code><\/p>\n<p>Unter Linux kann gegen Ende der Installation die Warnung erscheinen, dass das Installationsverzeichnis nicht in der Systemvariable PATH enthalten ist. Das Problem wird gel\u00f6st, indem man sich nach Ende der Installation abmeldet und neu anmeldet.<br \/>&nbsp;<\/p>\n<h3>3.4. Whisper starten<\/h3>\n<p><\/p>\n<p>Wir \u00f6ffnen ein Terminal und aktivieren die virtuelle Umgebung:<\/p>\n<p><code style=\"font-weight: bold;\">Whisper\\Scripts\\activate<\/code> (Windows) bzw. <code style=\"font-weight: bold;\">source Whisper\/bin\/activate<\/code> (Linux).<\/p>\n<p>Als Test f\u00fcr die Transkription habe ich den Begriff \u00bbPodcast \u00fcber K\u00fcnstliche Intelligenz\u00ab ins Koreanische \u00fcbersetzen lassen und die \u00dcbersetzung dann in eine Suchmaschine kopiert. Aus den Suchergebnissen habe ich den folgenden, offensichtlich popul\u00e4ren Vortrag \u00fcber Ethik K\u00fcnstlicher Intelligenz gew\u00e4hlt: <a href=\"https:\/\/www.youtube.com\/watch?v=8dEqj7jvp4g\" rel=\"noreferrer noopener\" target=\"_blank\">https:\/\/www.youtube.com\/watch?v=8dEqj7jvp4g<\/a><\/p>\n<p>Die Audiodatei l\u00e4dt man entweder mit einer geeigneten Software herunter oder man legt ein Diktierger\u00e4t neben den Lautsprecher. Die Aufzeichnung habe ich in \u00bbVortrag.mp3\u00ab umbenannt und in das Projektverzeichnis \u00bb[Benutzer]\/Whisper\/\u00ab verschoben.<\/p>\n<p>Nun startet man die Transkription auf Koreanisch:<\/p>\n<p><code style=\"font-weight: bold;\">whisper Whisper\/Vortrag.mp3 --fp16 False --model large --language Korean --output_dir Whisper\/output<\/code><\/p>\n<p>Den nach rechts geneigten Trennstrich <code style=\"font-weight: bold;\">\/<\/code> versteht an dieser Stelle auch Windows. Das Argument <code style=\"font-weight: bold;\">--fp16 False<\/code> beugt Fehlermeldungen vor, dass der Hauptprozessor eine h\u00f6here Rechengenauigkeit besitzt als eine Grafikkarte und daher <a href=\"https:\/\/de.wikipedia.org\/wiki\/Minifloat\" rel=\"noreferrer noopener\" target=\"_blank\">\u00bbhalbe Genauigkeit\u00ab<\/a> nicht liefern k\u00f6nne. Gibt man kein Ausgabeverzeichnis an, speichert Whisper die Ergebnisse in dem Verzeichnis, von wo aus man im Terminal die Transkription gestartet hat. Dann vergisst man m\u00f6glicherweise, wo die Ergebnisdateien liegen, wenn man das Terminal nach Ende der Transkription wieder geschlossen hat. Das Ausgabeverzeichnis muss nicht identisch mit dem Verzeichnis sein, wo die zu transkribierende Audiodatei sich befindet. Existiert das angegebene Verzeichnis zur Ausgabe nicht, legt Whisper es an.<\/p>\n<p>Als Ergebnis erh\u00e4lt man u.a. <a href=\"..\/..\/Dateien\/Vortrag_ko.srt.txt\" rel=\"noreferrer noopener\" target=\"_blank\">eine Untertitel-Datei mit Zeitmarken<\/a> und <a href=\"..\/..\/Dateien\/Vortrag_ko.txt\" rel=\"noreferrer noopener\" target=\"_blank\">eine Datei nur mit dem erkannten Text<\/a>. Zur korrekten Darstellung der koreanischen Schrift m\u00fcssen diese Dateien evtl. heruntergeladen werden oder man klickt im Browser auf \u00bbAnsicht => Textkodierung reparieren\u00ab.<\/p>\n<p>So startet man die Transkription mit gleichzeitiger \u00dcbersetzung zu Englisch:<\/p>\n<p><code style=\"font-weight: bold;\">whisper Whisper\/Vortrag.mp3 --fp16 False --model large --language Korean --output_dir Whisper\/output --task translate<\/code><\/p>\n<p>Auch hier erh\u00e4lt man u.a. <a href=\"..\/..\/Dateien\/Vortrag_en.srt.txt\" rel=\"noreferrer noopener\" target=\"_blank\">eine Untertitel-Datei mit Zeitmarken<\/a> und <a href=\"..\/..\/Dateien\/Vortrag_en.txt\" rel=\"noreferrer noopener\" target=\"_blank\">eine Datei nur mit dem \u00fcbersetzten Text<\/a>.<\/p>\n<p>Die anderen in Whisper verf\u00fcgbaren Modelle sind \u00bbtiny\u00ab, \u00bbbase\u00ab, \u00bbsmall\u00ab, \u00bbmedium\u00ab, \u00bbturbo\u00ab, \u00bblarge-v1\u00ab und \u00bblarge-v2\u00ab. Meist liefert das Modell \u00bblarge-v2\u00ab eine genauere Transkription als \u00bblarge\u00ab, was identisch ist mit \u00bblarge-v3\u00ab. Bei \u00bbturbo\u00ab handelt es sich um eine schnellere Version von \u00bblarge-v3\u00ab. Dass auf Hugging Face \u00bblarge-v2\u00ab <a href=\"https:\/\/huggingface.co\/collections\/openai\/whisper-release-6501bba2cf999715fd953013\" rel=\"noreferrer noopener\" target=\"_blank\">wesentlich h\u00e4ufiger heruntergeladen<\/a> wurde als \u00bblarge\u00ab, spricht f\u00fcr seine Qualit\u00e4t.<\/p>\n<p>Jedes Sprachmodell wird bei seinem erstmaligen Start automatisch heruntergeladen und im Verzeichnis \u00bb[Laufwerk:]\\Users\\[Benutzer]\\.cache\\whisper\u00ab (Windows) bzw. \u00bb\/home\/[Benutzer]\/.cache\/whisper\u00ab (Linux) abgelegt. Hat man die Datei zuvor in ein anderes Verzeichnis heruntergeladen, teilt man das Whisper mit dem Kommandozeilenparameter <code style=\"font-weight: bold;\">--model_dir [Verzeichnis]<\/code> mit.<\/p>\n<p>Verzeichnisse und Dateien, deren Name mit einem Punkt beginnt, zeigt Linux normalerweise nicht an. Die Tastenkombinatioen <code style=\"font-weight: bold;\">Strg + H<\/code> im Datei-Explorer blendet sie ein bzw. bei erneutem Dr\u00fccken wieder aus.<\/p>\n<p>Vor allem in der Modell-Version \u00bblarge\u00ab bzw. \u00bblarge-v3\u00ab bleibt Whisper w\u00e4hrend der Transkription manchmal bei einem Satz stecken und wiederholt ihn mehrmals, bevor es weiter transkribiert. Es ist auch m\u00f6glich, dass Whisper am Ende einer Transkiption einen Satz hinzu \u00bbhalluziniert\u00ab. Insgesamt ist die Qualit\u00e4t der Spracherkennung jedoch sowohl in der Originalsprache als auch in Englisch sehr gut. Bisher kann Whisper in keine andere Sprache au\u00dfer Englisch \u00fcbersetzen, auch nicht nach Deutsch.<\/p>\n<p>Eine vollst\u00e4ndige Aufz\u00e4hlung aller Kommandozeilenoptionen befindet sich in der Datei <a href=\"https:\/\/github.com\/openai\/whisper\/blob\/main\/whisper\/transcribe.py\" rel=\"noreferrer noopener\" target=\"_blank\">https:\/\/github.com\/openai\/whisper\/blob\/main\/whisper\/transcribe.py<\/a> zu Beginn und dann ab Zeile 513. Die Namen der von Whisper unterst\u00fctzten Sprachen m\u00fcssen, anders als in der Datei <a href=\"https:\/\/github.com\/openai\/whisper\/blob\/main\/whisper\/tokenizer.py\" rel=\"noreferrer noopener\" target=\"_blank\">https:\/\/github.com\/openai\/whisper\/blob\/main\/whisper\/tokenizer.py<\/a>, am Wortanfang gro\u00df geschrieben werden.<br \/>&nbsp;<\/p>\n<h2><a name=\"WhisperAlsDiktiersoftware\">4. Whisper als Diktiersoftware<\/a><\/h2>\n<p><\/p>\n<p>Eine Diktiersoftware wandelt nicht nur eine Audiodatei in Text um, sie hat auch Sprachbefehle, um den erkannten Text zu formatieren. Beispiele f\u00fcr Sprachbefehle sind <code style=\"font-weight: bold;\">neue Zeile<\/code>, <code style=\"font-weight: bold;\">Komma<\/code>, <code style=\"font-weight: bold;\">Punkt<\/code>, <code style=\"font-weight: bold;\">Ausrufezeichen<\/code>, <code style=\"font-weight: bold;\">Fragezeichen<\/code>, <code style=\"font-weight: bold;\">Zitat Anfang<\/code> und <code style=\"font-weight: bold;\">Zitat Ende<\/code>. Die Zahl m\u00f6glicher Sprachbefehle l\u00e4sst sich fast ins Unendliche steigern, f\u00fcr runde, eckige und geschweifte Klammern, fetten, kursiven, unterstrichenen und durchge&shy;strichenen Text, Gro\u00df- und Kleinschreibung, Einr\u00fcckungen, Abs\u00e4tze, Tabellen usw.<\/p>\n<p>Manche Versionen von Diktiersoftware verlangen eine st\u00e4ndige Internetverbindung und verarbeiten die Daten auf dem Server des Anbieters. Oder man l\u00e4dt eine ausf\u00fchrbare Datei herunter, die dann ohne Verbindung ins Internet genutzt werden kann. Aber, besonders wenn sie kostenlos angeboten wird, ist nicht immer klar, ob diese Software <a href=\"https:\/\/de.wikipedia.org\/wiki\/Adware\" rel=\"noreferrer noopener\" target=\"_blank\">Adware<\/a> oder andere unerw\u00fcnschte Funktionen enth\u00e4lt. Kommerzielle Offline-Diktiersoftware andererseits ist mit ihrer Lizenz an bestimmte Rechner gebunden. Sie kann auch noch andere Nachteile haben, z. B. dass sie erst auf die eigene Stimme trainiert werden muss und sich der Rechner w\u00e4hrend der Transkription nicht mehr f\u00fcr andere Aufgaben nutzen l\u00e4sst.<\/p>\n<p>Whisper dagegen ist <a href=\"https:\/\/de.wikipedia.org\/wiki\/Open_Source\" rel=\"noreferrer noopener\" target=\"_blank\">quelloffen<\/a> und wird von vielen Menschen weltweit genutzt. Durch dieses \u00bbMehraugenprinzip\u00ab ist das Risiko, dass Whisper Schadkode enth\u00e4lt, sehr gering. Wer wegen dieses Vorteils Whisper als Diktiersoftware nutzen m\u00f6chte, steht vor dem Problem, dass Whisper nicht daf\u00fcr gemacht ist. Jeden Sprachbefehl m\u00fcsste man mit \u00bbsuchen und ersetzen\u00ab sowie anderen Formatierungsbefehlen einer Textverarbeitungs-Software selbst nachbauen. Weil die Trainingsdaten von Whisper keine Sprachbefehle enthielten, kann das Wahrscheinlichkeitsmodell (vor allem bei Gro\u00df- und Klein&shy;schreibung) kurz durcheinanderkommen, wenn in Flie\u00dftexten normalerweise seltene W\u00f6rter wie <code style=\"font-weight: bold;\">Komma<\/code> und <code style=\"font-weight: bold;\">Punkt<\/code> h\u00e4ufig auftreten.<\/p>\n<p>Dennoch ist Whisper eine zeitsparende Methode, um z. B. E-Mails zu diktieren und sie nicht mehr per Hand tippen zu m\u00fcssen. Zeitsparend in dem Sinn, dass man (jedenfalls in Abwesenheit von CUDA, siehe 2.5.) einige Minuten oder auch mal eine Stunde lang etwas anderes tut, bis Whisper die Transkription auf dem eigenen Rechner abgeschlossen hat. Den erkannten Text sollte man noch einmal lesen, ggf. korrigieren und kann die diktierte E-Mail dann absenden.<\/p>\n<p>Das folgende Programmbeispiel kann mit einem Aufruf beliebig viele Audiodateien nacheinander transkribieren. Mittels automatischer Textersetzungen wird es zu einer einfachen Diktiersoftware.<\/p>\n<p>Im Verzeichnis der virtuellen Umgebung f\u00fcr Whisper (siehe \u00bb3.4. Whisper starten\u00ab) legt man drei Textdateien an: \u00bbKonstanten.py\u00ab, \u00bbTranskribieren.py\u00ab und \u00bbVerschieben.py\u00ab. Diese Trennung des Programm-Kodes in mehrere Teile dient der \u00dcbersichtlichkeit.<\/p>\n<p>In die Datei \u00bbKonstanten.py\u00ab kopiert man den folgenden Python-Kode hinein:<\/p>\n<p><code style=\"font-weight: bold;\"><\/p>\n<pre># Definition von Konstanten\n\n# Ursprungsverzeichnis auf dem Diktierger\u00e4t\nSOURCE_DIRECTORY = \"E:\\\\MIC_A\\\\\"\n\n# Eingabeverzeichnis f\u00fcr zu transkribierende Audiodateien\nINPUT_DIRECTORY = \"D:\\\\Diktate\\\\Eingabe\\\\\"\n\n# Ausgabeverzeichnis f\u00fcr fertig transkribierte Audiodateien und ihre Transkripte\nOUTPUT_DIRECTORY = \"D:\\\\Diktate\\\\Ausgabe\\\\\"\n\n# 'cpu' zum Rechnen auf dem Hauptprozessor, 'cuda' zum Rechnen auf einer CUDA-f\u00e4higen Grafikkarte (wenn vorhanden)\nDEVICE = 'cpu'\n\n# Sprachmodell f\u00fcr die Transkription\nMODEL = 'large-v2'\n\n# Sprache der Transkription\nLANGUAGE = 'German'\n\n# Erweiterungen verarbeitbarer Audio- und Videodateien\nALLOWED_EXTENSIONS = {'.mp3', '.mp4', '.m4a', '.mpeg', '.mpga', '.flac', '.oga', '.ogg', '.wav', '.webm'}\n\n# W\u00f6rter, die mit hoher Wahrscheinlichkeit in der Audiodatei vorkommen werden und die Whisper wiedererkennen soll\nINITIAL_PROMPT = \"Ausrufezeichen Bindestrich Doppelpunkt Fragezeichen Klammer Komma klein Leertaste Absatz Zeile Punkt Schr\u00e4gstrich Semikolon Zitat\"\n\n# Zeichen vor oder nach einem zu ersetzenden Begriff, die mit dem Begriff gemeinsam ersetzt werden\nIS_WHITESPACE = \" -,.\"\n\n# erstes Suchen und Ersetzen f\u00fcr das Buchstabieralphabet, insgesamt 16 Durchl\u00e4ufe mit IS_WHITESPACE,\n# d.h. pro Zeile je einmal in Original- und einmal in Kleinschreibung\nREPLACE_WITH_WHITESPACE_1 = {\n    ' Gro\u00df ': ' A',\n    'Gro\u00df ': ' A',\n    ' Gro\u00df-': ' A',\n    'Gro\u00df-': ' A',\n    ' Klein ': ' a',\n    'Klein ': ' a',\n    ' Klein-': ' a',\n    'Klein-': ' a'\n}\n\n# anschlie\u00dfendes einfaches Suchen und Ersetzen von Diktierbefehlen, ohne IS_WHITESPACE\nREPLACE_NO_WHITESPACE = {\n    'Anton ': 'A',\n    'anton ': 'a',\n    'Umlaut Anton ': '\u00c4',\n    'umlaut Anton ': '\u00e4',\n    'Berta ': 'B',\n    'berta ': 'b',\n    'Bertha ': 'B',\n    'bertha ': 'b',\n    'C\u00e4sar ': 'C',\n    'c\u00e4sar ': 'c',\n    'Dora ': 'D',\n    'dora ': 'd',\n    'Emil ': 'E',\n    'emil ': 'e',\n    'Friedrich ': 'F',\n    'friedrich ': 'f',\n    'Gustav ': 'G',\n    'gustav ': 'g',\n    'Heinrich ': 'H',\n    'heinrich ': 'h',\n    'Ida ': 'I',\n    'ida ': 'i',\n    'Julius ': 'J',\n    'julius ': 'j',\n    'Konrad ': 'K',\n    'konrad ': 'k',\n    'Ludwig ': 'L',\n    'ludwig ': 'l',\n    'Martha ': 'M',\n    'martha ': 'm',\n    'Nordpol ': 'N',\n    'nordpol ': 'n',\n    'Otto ': 'O',\n    'otto ': 'o',\n    'Umlaut Otto ': '\u00d6',\n    'umlaut Otto ': '\u00f6',\n    'Paula ': 'P',\n    'paula ': 'p',\n    'Quelle ': 'Q',\n    'quelle ': 'q',\n    'Richard ': 'R',\n    'richard ': 'r',\n    'Siegfried ': 'S',\n    'siegfried ': 's',\n    'Theodor ': 'T',\n    'theodor ': 't',\n    'Ulrich ': 'U',\n    'ulrich ': 'u',\n    'Umlaut Ulrich ': '\u00dc',\n    'umlaut Ulrich ': '\u00fc',\n    'Victor ': 'V',\n    'victor ': 'v',\n    'Viktor ': 'V',\n    'viktor ': 'v',\n    'Wilhelm ': 'W',\n    'wilhelm ': 'w',\n    'Xaver ': 'X',\n    'xaver ': 'x',\n    'Ypsilon ': 'Y',\n    'ypsilon ': 'y',\n    'Zeppelin ': 'Z',\n    'zeppelin ': 'z',\n    'binde-': 'Bindestrich',\n    'bindestrich': 'Bindestrich',\n    'b\u00fcndestrich': 'Bindestrich',\n    'Bindestricht': 'Bindestrich',\n    'binde Strich': 'Bindestrich',\n    'Binde Strich': 'Bindestrich',\n    'Binde-Strich': 'Bindestrich',\n    'B\u00fcndestrich': 'Bindestrich',\n    'B\u00fcndesstrich': 'Bindestrich',\n    ' Bindestrich Leertaste ': '- ',\n    'Doppel, Punkt': 'Doppelpunkt',\n    'Doppelfunkt': 'Doppelpunkt',\n    'Euro ': '\u20ac ',\n    'Euro,': '\u20ac,',\n    '? Fragezeichen': 'Fragezeichen',\n    'Klammer Auf': 'Klammer auf',\n    'Klammer Zu': 'Klammer zu',\n    'kommer': 'Komma',\n    'Lehrtaste': 'Leertaste',\n    'schr\u00e4glich': 'Schr\u00e4gstrich',\n    'schr\u00e4gstrich': 'Schr\u00e4gstrich',\n    'Schr\u00e4glich': 'Schr\u00e4gstrich',\n    'sie dort anfangen': 'Zitat Anfang',\n    'sie hat angefangen': 'Zitat Anfang',\n    'Zitatanfang': 'Zitat Anfang',\n    'Zitternfang': 'Zitat Anfang',\n    'Zitatsanfang': 'Zitat Anfang',\n    'Zitat anfangen': 'Zitat Anfang',\n    'Zitat, anfangen': 'Zitat Anfang',\n    'Zitat, Anfang': 'Zitat Anfang',\n    'Zitat-Anfang': 'Zitat Anfang',\n    'Zitat. Anfang.': 'Zitat Anfang',\n    'Zitat. Anfang': 'Zitat Anfang',\n    'zittern Anfang': 'Zitat Anfang',\n    'Zittern Anfang': 'Zitat Anfang',\n    'Zittern anfangt': 'Zitat Anfang',\n    'zitternd Anfang': 'Zitat Anfang',\n    'Zitternanfang': 'Zitat Anfang',\n    'zitternden Anfang': 'Zitat Anfang',\n    'Zittert-Anfang': 'Zitat Anfang',\n    'zittert anfangen': 'Zitat Anfang',\n    'Zittert anfangen': 'Zitat Anfang',\n    'zitiert Anfang': 'Zitat Anfang',\n    'zittert Anfang': 'Zitat Anfang',\n    'Zittert Anfang': 'Zitat Anfang',\n    'zittert an von': 'Zitat Anfang',\n    'zu dem Anfang': 'Zitat Anfang',\n    'sie dort Ende': 'Zitat Ende',\n    'Zitatende': 'Zitat Ende',\n    'Zitatsende': 'Zitat Ende',\n    'Zitternende': 'Zitat Ende',\n    'Zitat-Ende': 'Zitat Ende',\n    'Zitat. Ende': 'Zitat Ende',\n    'Zitat, Ende': 'Zitat Ende',\n    'zittern Ende': 'Zitat Ende',\n    'Zittern Ende': 'Zitat Ende',\n    'Zittert-Ende': 'Zitat Ende',\n    'Zittertende': 'Zitat Ende',\n    'zitiert Ende': 'Zitat Ende',\n    'zittert Ende': 'Zitat Ende',\n    'Zittert Ende': 'Zitat Ende',\n    'Zitat. Endpunkt': 'Zitat Ende Punkt',\n    'Zitat Endpunkt': 'Zitat Ende Punkt',\n    'Zitat Endepunkt': 'Zitat Ende Punkt',\n    'Zitat, Endepunkt': 'Zitat Ende Punkt',\n    'Zittert-Endepunkt': 'Zitat Ende Punkt'\n}\n\n# abschlie\u00dfendes Suchen und Ersetzen von Diktierbefehlen, mit IS_WHITESPACE\n# Der Befehl a bei Semikolon und Komma wirkt einem h\u00e4ufigen Erkennungsfehler entgegen,\n# der das nachfolgende Wort immer gro\u00df schreibt und kann bei Bedarf gel\u00f6scht werden.\nREPLACE_WITH_WHITESPACE_2 = {\n    'Ausrufezeichen': '! A',\n    'Doppelpunkt': ': ',\n    'Fragezeichen': '? A',\n    'ist gleich': '=',\n    'Klammer auf': ' (',\n    'Klammer zu:': '): ',\n    'Klammer zu': ') ',\n    'neuer Absatz': '\\n\\nA',\n    'Neuer Absatz': '\\n\\nA',\n    'neue Zeile': '\\nA',\n    'Neue Zeile': '\\nA',\n    'Schr\u00e4gstrich': '\/',\n    'Semikolon': '; a',\n    'Zitat Anfang': ' \u00bb',\n    'Punkt Zitat Ende': '.\u00ab A',\n    'Zitat Ende Punkt': '\u00ab. A',\n    'Zitat Ende': '\u00ab ',\n    'Bindestrich': '-A',\n    'Leertaste': ' ',\n    'Komma': ', a',\n    'Punkt': '. A'\n}<\/pre>\n<p><\/code><\/p>\n<p>Das Ein- und Ausgabeverzeichnis, wie auch alle anderen Eintr\u00e4ge in dieser Datei, m\u00fcssen bzw. k\u00f6nnen individuell angepasst werden. Unter Linux m\u00fcssen Ein- und Ausgabeverzeichnis in die dortige Schreibweise ge\u00e4ndert werden, zum Beispiel <span style=\"font-weight: bold;\">&quot;\/home\/[Benutzer]\/Whisper\/Eingabe\/&quot;<\/span>.<\/p>\n<p>In die Datei \u00bbTranskribieren.py\u00ab kopiert man folgenden Python-Kode hinein:<\/p>\n<p><code style=\"font-weight: bold;\"><\/p>\n<pre>import io\nimport re\nimport os\nimport whisper\nimport Konstanten as const\nfrom datetime import datetime\n\n# alle Vorkommen eines Diktierbefehls ersetzen und den ge\u00e4nderten Text zur\u00fcckgeben\ndef search_and_replace_with_whitespace(text, find_phrase, replace_with):\n\n    lower_or_upper_case = replace_with[-1:]\n    if lower_or_upper_case == 'a' or lower_or_upper_case == 'A':\n        replace_with = replace_with[:-1]\n    else:\n        lower_or_upper_case = '='\n\n    text_position = text.find(find_phrase)\n    phrase_length = len(find_phrase)\n\n    while text_position >= 0:\n        # zu ersetzende Zeichenkette nach links erweitern\n        character_position = 0\n        while text_position > 0 and character_position >= 0:\n            character_position = const.IS_WHITESPACE.find(text[text_position - 1])\n            if (character_position >= 0):\n                text_position -= 1\n                phrase_length += 1\n\n        # zu ersetzende Zeichenkette nach rechts erweitern\n        character_position = 0\n        no_whitespace_right = True\n        while text_position + phrase_length < len(text) and character_position >= 0:\n            character_position = const.IS_WHITESPACE.find(text[text_position + phrase_length])\n            if (character_position >= 0):\n                phrase_length += 1\n                no_whitespace_right = False\n\n        if len(text) <= text_position + phrase_length:\n            lower_or_upper_character = ''\n        elif lower_or_upper_case == 'a':\n            lower_or_upper_character = text[text_position + phrase_length].lower()\n        elif lower_or_upper_case == 'A':\n            lower_or_upper_character = text[text_position + phrase_length].upper()\n        else:\n            lower_or_upper_character = text[text_position + phrase_length]\n\n        # 'Punkt' als Anfang eines l\u00e4ngeren Wortes nicht durch '.' ersetzen\n        if find_phrase == 'Punkt' and no_whitespace_right and lower_or_upper_character.isalpha():\n            text_position = text.find(find_phrase, text_position + len(find_phrase))\n        else:\n            if len(text) > text_position + phrase_length + 1:\n                text = text[:text_position] + replace_with + lower_or_upper_character + text[text_position + phrase_length + 1:]\n            else:\n                text = text[:text_position] + replace_with + lower_or_upper_character\n            text_position = text.find(find_phrase, text_position + len(replace_with))\n\n        phrase_length = len(find_phrase)\n\n    return text\n\n# mittels Regul\u00e4rer Ausdr\u00fccke Zeitangaben wie \"13 Uhr 30\" finden und durch das Format \"13:30 Uhr\" ersetzen\ndef convert_time_format(text):\n\n    pattern = re.compile(r'(\\d{1,2}) Uhr (\\d{1,2})')\n    \n    def replace_match(match):\n        hour = match.group(1)\n        minute = match.group(2)\n        return f'{hour}:{minute.zfill(2)} Uhr'\n\n    return re.sub(pattern, replace_match, text)\n\n# alle Diktierbefehle ersetzen und das Ergebnis als Textdatei speichern\ndef search_and_replace_all(srt_path, txt_path):\n\n    if os.path.isfile(txt_path):\n        print(f\"\u00fcberspringe vorhandenen Text {txt_path}\")\n    else:\n        no_line_breaks = \"\"\n        line_number = 2\n\n        # Untertitel-Datei ohne Zeitmarken und Zeilenumbr\u00fcche in eine Textvariable umkopieren\n        with io.open(srt_path, encoding='utf-8') as lines:\n            for line in lines:\n                if line_number % 4 == 0:\n                    if no_line_breaks == \"\":\n                        no_line_breaks = line.strip()\n                    else:\n                        no_line_breaks += \" \" + line.strip()\n                line_number += 1\n\n        # f\u00fcr reine Transkription ohne Diktierbefehle die folgenden drei for-Bl\u00f6cke entfernen\n        for key in const.REPLACE_WITH_WHITESPACE_1:\n            no_line_breaks = search_and_replace_with_whitespace(no_line_breaks, key, const.REPLACE_WITH_WHITESPACE_1[key])\n            no_line_breaks = search_and_replace_with_whitespace(no_line_breaks, key.lower(), const.REPLACE_WITH_WHITESPACE_1[key])\n\n        for key in const.REPLACE_NO_WHITESPACE:\n            no_line_breaks = no_line_breaks.replace(key, const.REPLACE_NO_WHITESPACE[key])\n\n        for key in const.REPLACE_WITH_WHITESPACE_2:\n            no_line_breaks = search_and_replace_with_whitespace(no_line_breaks, key, const.REPLACE_WITH_WHITESPACE_2[key])\n\n        no_line_breaks = convert_time_format(no_line_breaks)\n\n        # Ergebnis-Datei speichern\n        with io.open(txt_path, 'w', encoding='utf-8') as text:\n            print(no_line_breaks.strip(), file=text)\n\n\n# eine Audiodatei in Whisper zu transkribieren ist flexibler mit der Kommandozeile als direkt in Python\ndef transcribe(audio_file):\n\n    return_value = True\n    audio_path = os.path.join(const.INPUT_DIRECTORY, audio_file)\n    audio_file_without_extension = os.path.splitext(audio_file)[0]\n    output_dir = os.path.join(const.OUTPUT_DIRECTORY, audio_file_without_extension)\n    if not os.path.isdir(output_dir):\n        os.mkdir(output_dir)\n\n    srt_path = os.path.join(output_dir, audio_file_without_extension + '.srt')\n    txt_path = os.path.join(output_dir, audio_file_without_extension + '.txt')\n    destination_path = os.path.join(output_dir, audio_file)\n\n    print()\n    if os.path.isfile(srt_path):\n        print(f\"\u00fcberspringe vorhandenes Transkript {srt_path}\")\n        search_and_replace_all(srt_path, txt_path)\n    else:\n        print(f\"transkribiere Audiodatei {audio_path}\")\n        print()\n        use_fp16 = (const.DEVICE == 'cuda')\n        command_line = f\"whisper \\\"{audio_path}\\\" --device {const.DEVICE} --fp16 {use_fp16} --model {const.MODEL}\"\n        command_line += f\" --language {const.LANGUAGE} --initial_prompt \\\"{const.INITIAL_PROMPT}\\\"\"\n        command_line += f\" --output_dir \\\"{output_dir}\\\" --verbose True --output_format srt\"\n        os.system(command_line)\n        if os.path.isfile(srt_path):\n            search_and_replace_all(srt_path, txt_path)\n        else:\n            return_value = False\n            print(\"FEHLER: das Transkript wurde nicht gespeichert.\")\n\n    if os.path.isfile(destination_path):\n        os.remove(destination_path)\n\n    if return_value:\n        os.rename(audio_path, destination_path)\n\n    return return_value\n\n# Hauptprogramm, das in einer 'unendlichen' Schleife alle zu transkribierenden Audiodateien sucht\n# und nachtr\u00e4gliches Hinzuf\u00fcgen oder L\u00f6schen von Audiodateien w\u00e4hrend der Transkription erm\u00f6glicht\n\n# spart mehr als 10% Speicher auf der Grafikkarte\nos.environ['PYTORCH_CUDA_ALLOC_CONF'] = 'expandable_segments:True'\n\naudio_counter = 0\nstart = datetime.now()\n\nwhile True:\n    success = False\n    all_files = os.listdir(const.INPUT_DIRECTORY)\n    audio_files = [file for file in all_files if os.path.splitext(file)[1].lower() in const.ALLOWED_EXTENSIONS]\n        \n    if audio_files:\n        success = transcribe(audio_files[0])\n        if not success:\n            break\n        audio_counter += 1\n    else:\n        success = True\n        break\n\nend = datetime.now()\nelapsed = end - start\nprint()\n\nif not success:\n    print(f\"Die Transkription wurde nach {elapsed} wegen eines Fehlers abgebrochen.\")\nelif audio_counter == 1:\n    print(f\"Eine Audiodatei wurde in {elapsed} transkribiert.\")\nelif audio_counter > 1:\n    print(f\"{audio_counter} Audiodateien wurden in {elapsed} transkribiert.\")\nelse:\n    print(f\"Das Eingabeverzeichnis {const.INPUT_DIRECTORY} enth\u00e4lt keine Audiodateien.\")\nprint()<\/pre>\n<p><\/code><\/p>\n<p>Und in die Datei \u00bbVerschieben.py\u00ab kopiert man folgenden Python-Kode hinein:<\/p>\n<p><code style=\"font-weight: bold;\"><\/p>\n<pre>import os\nimport shutil\nfrom tqdm import tqdm\nimport Konstanten as paths\n\n# alle MP3-Dateien rekursiv sammeln\ndef find_mp3_files(source_directory):\n    # Alle .mp3 und .MP3 Dateien im Quellverzeichnis sammeln (keine Unterordner)\n    mp3_files = [\n        f for f in os.listdir(source_directory)\n        if os.path.isfile(os.path.join(source_directory, f)) and f.lower().endswith('.mp3')\n    ]\n    return mp3_files\n\n# Dateien mit Fortschrittsanzeige verschieben\ndef move_files(file_list, source_directory, destination_directory):\n    # sicherstellen, dass das Zielverzeichnis existiert\n    os.makedirs(destination_directory, exist_ok=True)\n\n    for filename in tqdm(file_list, desc=\"Verschiebe MP3-Dateien\", unit=\"Datei\"):\n        src_path = os.path.join(source_directory, filename)\n        dest_path = os.path.join(destination_directory, filename)\n        try:\n            shutil.move(src_path, dest_path)\n        except Exception as e:\n            print(f\"Fehler beim Verschieben von {filename}: {e}.\")\n\nif __name__ == \"__main__\":\n    if os.path.isdir(paths.SOURCE_DIRECTORY):\n        mp3s = find_mp3_files(paths.SOURCE_DIRECTORY)\n        if not mp3s:\n            print(\"\\nKeine MP3-Dateien auf dem Diktierger\u00e4t gefunden.\\n\")\n        else:\n            print(\"\")\n            move_files(mp3s, paths.SOURCE_DIRECTORY, paths.INPUT_DIRECTORY)\n            if len(mp3s) == 1:\n                print(f\"\\nEin Diktat erfolgreich verschoben.\\n\")\n            else:\n                print(f\"\\n{len(mp3s)} Diktate erfolgreich verschoben.\\n\")\n    else:\n        print(\"\\nDas Diktierger\u00e4t ist nicht mit dem Rechner verbunden.\\n\")<\/pre>\n<p><\/code><\/p>\n<p>Diese letzte Datei ist zum Transkribieren nicht erforderlich. Sie \u00fcbernimmt das Verschieben neuer Audiodaten vom Diktierger\u00e4t in das Eingabeverzeichnis. Sie ist ein Beispiel daf\u00fcr, wie sich man sich ohne wesentliche Programmierkenntnisse ein kurzes Programm von einem Chatbot schreiben lassen kann. Wer das ausprobieren will, kann in einen Chatbot der eigenen Wahl (siehe z. B. die Empfehlungen im ersten Satz dieses Textes) die folgende Anweisung hinein kopieren und sollte dann einen \u00e4hnlichen Programmkode erhalten:<\/p>\n<p><code style=\"font-weight: bold;\"><\/p>\n<pre>Schreibe ein Python-Programm mit folgenden Merkmalen:\n\n- l\u00e4uft in der Konsole, ohne grafische Benutzeroberfl\u00e4che\n- hat ein konstantes Eingabeverzeichnis\n- hat ein konstantes Ausgabeverzeichnis\n- verschiebt alle Audiodateien im Format mp3 (Gro\u00df- und Kleinschreibung der Dateierweiterung einbeziehen) aus dem Eingabeverzeichnis in das Ausgabeverzeichnis\n- ignoriert alle Unterverzeichnisse\n- ignoriert alle anderen Dateitypen\n- existiert das Eingabeverzeichnis nicht, wird die Meldung ausgegeben: \"Das Diktierger\u00e4t ist nicht an den Rechner angeschlossen.\"\n- werden im Eingabeverzeichnis keine mp3-Dateien gefunden, wird die Meldung ausgegeben: \"Das Eingabeverzeichnis enth\u00e4lt keine mp3-Dateien.\"\n- existiert das Ausgabeverzeichnis nicht, wird es angelegt\n- gibt es im Ausgabeverzeichnis schon eine Datei mit identischem Namen (auch Unterschiede in Gro\u00df- und Kleinschreibung als identisch betrachten), wird die betreffende Datei nicht verschoben und eine entsprechende Meldung ausgegeben\n- mit Fortschrittsbalken\n- wurde genau eine Datei erfolgreich verschoben, schreibe am Ende: \"Eine Datei wurde erfolgreich verschoben.\" \n- wurde eine andere Anzahl Dateien erfolgreich verschoben, schreibe am Ende: \"[Anzahl] Dateien wurden erfolgreich verschoben.\"\n<\/pre>\n<p><\/code><\/p>\n<p>Die Transkription l\u00e4sst sich nun entweder etwas umst\u00e4ndlich \u00fcber das Terminal starten:<\/p>\n<p><code style=\"font-weight: bold;\">Whisper\\Scripts\\activate<\/code> (Windows) bzw. <code style=\"font-weight: bold;\">source Whisper\/bin\/activate<\/code> (Linux) und dann<br \/>\n<code style=\"font-weight: bold;\">python .\\Whisper\\Transkribieren.py<\/code> (Windows) bzw. <code style=\"font-weight: bold;\">python3 .\/Whisper\/Transkribieren.py<\/code> (Linux).<\/p>\n<p>Oder man legt sich eine Verkn\u00fcpfung auf dem Desktop an. Unter Windows bearbeitet man dazu die Datei \u00bbWhisper\\Scripts\\activate.bat\u00ab und f\u00fcgt an ihrem Ende ein:<\/p>\n<p><code style=\"font-weight: bold;\"><\/p>\n<pre>@echo on\npython ..\/Transkribieren.py\n@echo off\npause<\/pre>\n<p><\/code><\/p>\n<p>Nach dem Speichern dieser \u00c4nderung (z. B. mit  <code style=\"font-weight: bold;\">Strg + S<\/code>) zieht man die Datei \u00bbactivate.bat\u00ab bei gehaltener rechter Maustaste aus dem Datei-Explorer auf den Desktop und w\u00e4hlt in dem bei Loslassen der Maustaste erscheinenden Kontextmen\u00fc \u00bbVerkn\u00fcpfung hier erstellen\u00ab. Optional kann dann noch mit Rechtsklick auf die Verkn\u00fcpfung ein anderer Name vergeben und unter \u00bbEigenschaften\u00ab ein anderes Symbol gew\u00e4hlt werden. Passende Symbolbilder zum Herunterladen sind unter anderem auf <a href=\"https:\/\/www.iconarchive.com\/show\/cristal-intense-icons-by-tatice\/Notepad-Bloc-notes-2-icon.html\" rel=\"noreferrer noopener\" target=\"_blank\">iconarchive.com<\/a> zu finden.<\/p>\n<p>Unter Linux \u00f6ffnen wir die Datei \u00bbWhisper\/bin\/activate\u00ab und f\u00fcgen an ihrem Ende ein:<\/p>\n<p><code style=\"font-weight: bold;\"><\/p>\n<pre>python3 \/home\/[Benutzer]\/Whisper\/Transkribieren.py\nread -n1 -r -p \"Dr\u00fccken Sie eine beliebige Taste . . .\" key<\/pre>\n<p><\/code><\/p>\n<p>Der Pfad zur Datei \u00bbTranskribieren.py\u00ab muss dabei individuell angepasst werden. Nun erstellen wir auf dem Desktop eine leere Textdatei und nennen sie \u00bbWhisper.desktop\u00ab. Dort hinein kopieren wir den folgenden Kode:<\/p>\n<p><code style=\"font-weight: bold;\"><\/p>\n<pre>[Desktop Entry]\nEncoding=UTF-8\nName=Whisper\nComment=Audiodateien transkribieren\nExec=bash \/home\/[Benutzer]\/Whisper\/bin\/activate\nIcon=\/home\/[Benutzer]\/Whisper\/Tatice-Cristal-Intense-Notepad-Bloc-notes-2.256.png\nTerminal=true\nType=Application<\/pre>\n<p><\/code><\/p>\n<p>Die Pfade f\u00fcr den auszuf\u00fchrenden Befehl und f\u00fcr die Symboldatei m\u00fcssen wieder individuell angepasst werden. Nach einem Klick mit der rechten Maustaste auf diese Datei muss unter \u00bbEigenschaften\u00ab und dann \u00bbZugriffsrechte\u00ab noch ein H\u00e4kchen gesetzt werden bei \u00bbDer Datei erlauben sie als Programm auszuf\u00fchren\u00ab.<\/p>\n<p>Auf dem gleichen Weg kann das Skript \u00bbVerschieben.py\u00ab einer Verkn\u00fcpfung auf dem Desktop zugeordnet werden.<\/p>\n<p>Nach dem Start (per Doppelklick auf das Desktop-Symbol oder, wie oben beschrieben, mit der Kommandozeile) kann sowohl unter Windows als auch unter Linux im Terminal der Fortschritt der Transkription verfolgt werden:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"\/blog\/wp-content\/uploads\/2024\/05\/Whisper.png\" width=\"712\" height=\"385\"><\/p>\n<p>Das Ausgabeverzeichnis enth\u00e4lt f\u00fcr jede transkribierte Audiodatei ein Unterverzeichnis. Darin liegen die aus dem Eingabeverzeichnis her\u00fcber verschobene Audiodatei, die von Whisper transkribierte Untertitel-Datei mit Zeitmarken und die daraus erzeugte Textdatei mit dem Diktat.<\/p>\n<p>Das Programm liest jeweils nur eine Audiodatei aus dem Eingabeverzeichnis. So ist es m\u00f6glich, w\u00e4hrend einer laufenden Transkription weitere Audiodateien im Eingabeverzeichnis abzulegen. Diese werden im Anschluss transkribiert, ohne dass daf\u00fcr das Programm neu gestartet werden muss.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Viele Anwendungen der K\u00fcnstlichen Intelligenz (KI) k\u00f6nnen nur im Internet genutzt werden, z. B. die Chatbots ChatGPT, Claude und Le Chat.  Offline gibt es dazu keine gleichwertigen &#8230;<\/p>\n","protected":false},"author":1,"featured_media":1181,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[45],"tags":[],"class_list":["post-1173","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-ki"],"_links":{"self":[{"href":"https:\/\/matthias-gloeckner.de\/blog\/wp-json\/wp\/v2\/posts\/1173","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/matthias-gloeckner.de\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/matthias-gloeckner.de\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/matthias-gloeckner.de\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/matthias-gloeckner.de\/blog\/wp-json\/wp\/v2\/comments?post=1173"}],"version-history":[{"count":35,"href":"https:\/\/matthias-gloeckner.de\/blog\/wp-json\/wp\/v2\/posts\/1173\/revisions"}],"predecessor-version":[{"id":1239,"href":"https:\/\/matthias-gloeckner.de\/blog\/wp-json\/wp\/v2\/posts\/1173\/revisions\/1239"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/matthias-gloeckner.de\/blog\/wp-json\/wp\/v2\/media\/1181"}],"wp:attachment":[{"href":"https:\/\/matthias-gloeckner.de\/blog\/wp-json\/wp\/v2\/media?parent=1173"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/matthias-gloeckner.de\/blog\/wp-json\/wp\/v2\/categories?post=1173"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/matthias-gloeckner.de\/blog\/wp-json\/wp\/v2\/tags?post=1173"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}