Heute möchte ich Euch eine echte NLP-Suche im Browser vorstellen:
Aber eines nach dem anderen:
Vor ein paar Jahren wäre die Idee, Python-NLP direkt im Browser laufen zu lassen, noch ein typischer „nice try“-Moment gewesen. Heute ist das ein ernstzunehmender Ansatz nicht als Gimmick, sondern als Strategie: Du baust Web-UIs mit HTML/CSS/JavaScript, nutzt aber für die Rechenarbeit genau die Tools, die in ihrem Ökosystem seit Jahren am stärksten sind. Der Katalysator dafür heißt WebAssembly.
WebAssembly (oft nur „Wasm“) ist im Grunde eine zweite Ausführungsform neben JavaScript, die Browser nativ unterstützen. Während JavaScript als Sprache sehr flexibel ist, ist es für gewisse Aufgaben schlicht nicht ideal besonders dort, wo viel gerechnet, geparst oder analysiert wird. Wasm schließt diese Lücke: Es ist ein kompaktes Binärformat, das im Browser sehr schnell ausgeführt werden kann. Der Clou dabei ist weniger „noch schneller als JS“, sondern: Viele Sprachen können nach Wasm kompilieren. Das heißt: Jahrzehnte an Bibliotheken und Know-how aus anderen Communities werden plötzlich „browserfähig“, ohne dass jemand alles neu in JavaScript erfinden muss.
Damit sind wir mitten im Thema Natural Language Processing. Denn „Suche“ ist in der Praxis schnell frustrierend, wenn sie nur Teilstrings vergleicht. Gerade im Deutschen willst du, dass ein Nutzer „laufen“ eingibt und trotzdem „lief“ oder „gelaufen“ Treffer sind. Und du willst idealerweise auch Wortfamilien wie „Wahnsinn“ und „wahnsinnig“ zusammenbringen, weil das für Menschen offensichtlich zusammengehört für eine naive Suche aber nicht. Sobald man das ernst nimmt, landet man fast automatisch bei zwei Bausteinen: Lemmatisierung (Grundform) und Stemming (Wortstamm). Und an dieser Stelle ist die Realität ziemlich eindeutig: Viele der etablierten und praxiserprobten NLP-Bausteine, gerade auch für Deutsch, sind im Python-Ökosystem über Jahre gereift.
Wasm ist nicht „das neue JavaScript“. Im Gegenteil: JavaScript bleibt im Browser die Schaltzentrale für alles, was mit UI, DOM und Web-APIs zu tun hat. Wasm ergänzt das Bild, indem es einen performanten Ausführungsraum liefert, in dem andere Runtimes oder Libraries laufen können und über eine Brücke mit JS zusammenarbeiten. Genau dieses Zusammenspiel ist der Kern der „Technologie-Verschmelzung“: Du nutzt das Web als Plattform, aber du bist nicht mehr auf das JS-Ökosystem als einziges Werkzeugset beschränkt.
Ein wichtiger Aspekt, der dabei oft untergeht: Wasm läuft in der gleichen Sicherheitswelt wie der Browser. Es ist sandboxed, es muss sich an die Regeln des Web halten, und es kann nicht einfach beliebig auf Betriebssystem-Ressourcen zugreifen. Das ist gut aber es erklärt auch, warum man bestimmte Dinge (z. B. Dateisystem, Threads, bestimmte Systemmodule) bewusst gestalten muss, wenn man von „klassischen“ Desktop-Runtimes kommt.
An der Stelle wird Pyodide interessant. Pyodide bringt CPython als WebAssembly in den Browser. Praktisch heißt das: Du lädst eine Pyodide-Runtime (z. B. von einem CDN oder self-hosted), initialisierst sie in JavaScript und kannst dann Python-Code im Browser ausführen. Für NLP ist das extrem attraktiv, weil du plötzlich Zugriff auf Python-Bibliotheken bekommst, ohne dass du serverseitig rechnen musst oder alles neu implementieren musst.
In unserem konkreten Beispiel nutzen wir genau das als „Proof of Value“: Wir bauen eine Textsuche, die nicht bei exakten Teilstrings endet, sondern sprachlich robuster ist. Dazu kombinieren wir zwei Python-Bausteine: einen Lemmatizer (bei uns simplemma) und einen Stemmer (Snowball über snowballstemmer). Das Zusammenspiel ist der Trick: Lemmatisierung fängt Flexion ab, Stemming fängt Wortfamilien ab. Dadurch wird aus „string contains“ eine Suche, die deutlich näher an dem ist, was Nutzer erwarten.
Die Mechanik dahinter lässt sich gut in einem Bild erklären: Der Text wird in Tokens zerlegt, und jedes Token bekommt eine Art „Such-Fingerprint“. Dieser Fingerprint besteht aus mindestens zwei Teilen: dem Lemma (Grundform) und dem Stem (Wortstamm). Das gleiche passiert mit der Suchanfrage. Wenn dann beim Durchlaufen des Textes die Fingerprints übereinstimmen – oder sich zumindest schneiden – ist es ein Treffer.
Der praktische Effekt: Sucht jemand nach „Land“, kann „Ländern“ gefunden werden. Sucht jemand nach „Wahnsinn“, kann „wahnsinnig“ gefunden werden, weil der Wortstamm bzw. die Normalisierung die Brücke baut. Das ist genau die Art „Intelligenz“, die Nutzer im Kopf haben, wenn sie eine Suchbox bedienen ohne dass du gleich eine große semantische Suchmaschine bauen musst.
.whl Dateien nicht jedes Mal erneut aus dem Netz ziehen muss. Aber selbst wenn die Dateien aus dem Cache kommen, bleibt ein anderes Problem: Pyodide nutzt standardmäßig ein flüchtiges In-Memory-Dateisystem. Nach einem Reload ist das wieder leer. Wenn du also bei jedem Start die Wheels ins Pyodide-FS schreibst und entpackst, machst du diese Arbeit bei jedem Besuch wieder ganz unabhängig davon, ob der Download gecached ist.sys.path und Imports – und die Seite fühlt sich plötzlich wie eine normale Web-App an.runPythonAsync(…)). Das ist bequem, aber fragil: Python ist empfindlich bei Einrückungen, JavaScript bei Escaping, und Debugging ist manchmal wie ein Blick in zwei Welten gleichzeitig (JS-Stacktrace + Python-Traceback). In echten Projekten lohnt es sich fast immer, den Python-Code in eigene Dateien auszulagern und zu laden allein schon, weil das Versionsmanagement und die Lesbarkeit deutlich besser werden.lzma), musst du es gezielt nachladen sonst steht man plötzlich vor ModuleNotFoundError und fragt sich, warum „Python ohne Module“ existiert.Als erster einen Kommentar schreiben.
Schreibe einen Kommentar