Einführung
Über einen längeren Zeitraum hinweg bedeutete die Ausführung von Transformermodellen, einen Python-Server zu betreiben, für GPU-Zeit zu bezahlen und jede Anfrage über eine API zu leiten. Der Benutzer gab etwas ein, es verließ sein Gerät, durchlief Ihre Infrastruktur und kam als Vorhersage zurück. Diese Architektur war sinnvoll, als die Modelle zu groß waren, um sie anderswo auszuführen. Dies ist jedoch nicht mehr die einzige Option.
Transformers.js verändert die Situation. Es führt hochmoderne NLP-Modelle direkt im Browser, auf dem Gerät des Benutzers, ohne dass ein Server erforderlich ist, aus. Die Modelle werden einmal heruntergeladen, lokal zwischengespeichert und laufen von diesem Punkt an offline. Die Übersetzung von Python nach JavaScript ist nahezu identisch:
// JavaScript -- nahezu identisch
import { pipeline } from '@huggingface/transformers';
const classifier = await pipeline('sentiment-analysis');
const result = await classifier('Ich liebe Transformatoren!');
Dieses Tutorial behandelt drei NLP-Aufgaben: Textklassifikation, Zero-Shot-Kategorisierung und Fragebeantwortung mithilfe der pipeline()-API von Transformers.js. Für jede Aufgabe sehen Sie, wie Sie die Pipeline initialisieren, wie die Ausgabestruktur aussieht und wie Sie sie interpretieren, sowie ein funktionierendes HTML-Beispiel, das Sie direkt im Browser öffnen können. Das Tutorial endet mit einer vollständigen Anwendung zur Routing von Supportanfragen, die alle drei Pipelines in einem praktischen Tool kombiniert.
Jedes Codebeispiel in diesem Artikel verwendet den CDN-Importpfad, sodass kein Build-Schritt erforderlich ist. Öffnen Sie einen Texteditor, fügen Sie den Code ein und führen Sie ihn aus.
Was ist Transformers.js?
Die Bibliothek ist so konzipiert, dass sie funktional äquivalent zur Python-Bibliothek von Hugging Face ist, was bedeutet, dass dieselben vortrainierten Modelle, dieselben Aufgabenbezeichnungen und dieselbe Pipeline-API in JavaScript verfügbar sind. Im Hintergrund ist die Brücke, die dies ermöglicht, das ONNX Runtime.
Modelle, die in PyTorch, TensorFlow oder JAX trainiert wurden, werden mit Hugging Face Optimum in das ONNX-Format konvertiert. ONNX Runtime führt diese Modelle dann im Browser aus. Standardmäßig läuft es auf der CPU über WebAssembly (WASM), was in jedem modernen Browser funktioniert. Wenn Sie GPU-Beschleunigung wünschen, leitet die Einstellung device: ‚webgpu‘ die Berechnung über die WebGPU-API des Browsers, was dort, wo verfügbar, erheblich schneller ist, obwohl es in einigen Umgebungen noch experimentell ist.
- Modell-Caching: Beim ersten Ausführen einer Pipeline werden die Modellgewichte vom Hugging Face Hub heruntergeladen und im IndexedDB des Browsers zwischengespeichert, im Dateisystem von Node.js. Entwickler-Tests zeigen, dass die Pipeline zur Sentimentanalyse beim ersten Laden etwa 111 MB herunterlädt. Bei nachfolgenden Ausführungen wird der Download vollständig übersprungen und aus dem Cache geladen. Dies bedeutet, dass die erste Benutzersitzung Kosten für die Bandbreite verursacht; jede nachfolgende Sitzung ist schnell und offline-fähig.
- Quantisierung: Die dtype-Option steuert die Modellgenauigkeit. q8 (8-Bit-Quantisierung) ist der WASM-Standard; es bietet ein gutes Gleichgewicht zwischen Größe und Genauigkeit. q4 halbiert die Datei ungefähr mit einem Genauigkeitsverlust von 1–3 % bei den meisten Aufgaben, was der richtige Kompromiss für mobile oder langsame Verbindungen ist. Für die serverseitige Verwendung in Node.js bietet fp32 volle Präzision ohne Größenbeschränkung.
// Standard WASM-Ausführung -- funktioniert überall
const pipe = await pipeline('sentiment-analysis');
// WebGPU für schnellere Inferenz auf kompatibler Hardware
const pipe = await pipeline('sentiment-analysis', null, { device: 'webgpu' });
// 4-Bit-Quantisierung für kleinere Modell-Downloads
const pipe = await pipeline('sentiment-analysis',
'Xenova/distilbert-base-uncased-finetuned-sst-2-english',
{ dtype: 'q4' }
);
Die pipeline() API
Die Pipeline-Funktion ist die gesamte öffentliche Schnittstelle für die meisten Anwendungsfälle. Sie bündelt drei Dinge: ein vortrainiertes Modell, einen Tokenizer und Postprocessing-Logik in einem einzigen aufrufbaren Objekt. Sie greifen nicht direkt auf den Tokenizer oder die Modellgewichte zu. Sie rufen die Pipeline mit Text auf und erhalten strukturierte Ausgaben zurück.
Die Signatur hat drei Teile:
const pipe = await pipeline(task, model?, options?);
const result = await pipe(input, inferenceOptions?);
task ist ein String-Identifikator, der der Bibliothek mitteilt, welche Art von Modell geladen werden soll und wie Eingaben und Ausgaben behandelt werden. model ist optional; wenn Sie es weglassen, lädt die Bibliothek das Standardmodell für diese Aufgabe. Wenn Sie eine Modell-ID angeben (wie ‚Xenova/distilbert-base-uncased-finetuned-sst-2-english‘), wird dieses Modell vom Hub geladen. options ist der Ort, an dem Sie device, dtype und progress_callback festlegen.
Beide Schritte sind asynchron. pipeline() lädt das Modell in den Speicher. Dies ist der langsame Teil beim ersten Ausführen. Der pipe-Aufruf selbst ist in der Regel schnell, sobald das Modell geladen ist. Beide geben Promises zurück, was bedeutet, dass Ihre Benutzeroberfläche den Ladezustand verwalten muss.
Ein progress_callback ermöglicht es Ihnen, den Download zu verfolgen und den Fortschritt dem Benutzer anzuzeigen:
// progress_callback wird während des Modell-Downloads mit Statusaktualisierungen aufgerufen
// Dies ist wichtig für die Benutzererfahrung -- Benutzer müssen wissen, dass etwas passiert
const pipe = await pipeline(
'sentiment-analysis',
'Xenova/distilbert-base-uncased-finetuned-sst-2-english',
{
dtype: 'q8',
progress_callback: (progress) => {
// progress.status kann sein: 'initiate', 'download', 'progress', 'done'
if (progress.status === 'progress') {
const pct = Math.round(progress.progress);
document.getElementById('progress').textContent =
`Modell wird geladen: ${pct}%`;
}
if (progress.status === 'ready') {
document.getElementById('progress').textContent = 'Modell bereit';
}
}
}
);
Ein wichtiger Hinweis aus der offiziellen Dokumentation: Transformers.js ist eine Inferenzbibliothek. Sie können Modelle damit nicht feinabstimmen oder trainieren. Wenn Ihre Aufgabe ein benutzerdefiniertes Modell benötigt, erfolgt das Training an anderer Stelle (Python, Cloud), und der resultierende ONNX-Export läuft im Browser.
Aufgabe 1: Textklassifikation
Die Textklassifikation weist einem Eingabetext ein Label und einen Vertrauensscore zu. Die häufigste Form ist die Sentimentanalyse, positiv vs. negativ, aber dieselbe Pipeline-Architektur verarbeitet jede feste Menge von Kategorien, auf die das Modell trainiert wurde.
So sieht die Ausgabe aus:
const result = await classifier('Dieses Produkt hat meine Erwartungen vollständig übertroffen.');
// [{ label: 'POSITIVE', score: 0.9997 }]
Die Ausgabe ist ein Array von Objekten. Jedes Objekt hat ein Label (die vorhergesagte Klasse als String) und einen Score (eine Fließkommazahl zwischen 0 und 1, die das Vertrauen des Modells darstellt). Ein Score von 0.9997 bedeutet, dass das Modell sehr zuversichtlich ist. Ein Score von 0.52 bedeutet, dass es gerade über der Entscheidungsgrenze liegt; behandeln Sie dies als unsicher und gehen Sie entsprechend in Ihrer Anwendungslogik damit um.
Die Ausgabe ist immer ein Array, selbst für eine einzelne Eingabe, da derselbe Pipeline-Aufruf Batchverarbeitung unterstützt:
const results = await classifier([
'Das ist großartig!',
'Völlig kaputt, Geldverschwendung.'
]);
// [
// { label: 'POSITIVE', score: 0.9998 },
// { label: 'NEGATIVE', score: 0.9991 }
// ]
Aufgabe 2: Zero-Shot-Klassifikation
Die Zero-Shot-Klassifikation macht etwas, das die reguläre Textklassifikation nicht kann: Sie klassifiziert Text in Kategorien, die Sie zur Laufzeit definieren, ohne dass Trainingsdaten erforderlich sind. Sie übergeben den Text und eine Liste von Labels in einfachem Englisch. Das Modell entscheidet, welches Label am besten passt, basierend auf seinem Verständnis der Sprachsemantik.
Dies ist nützlich, wenn Sie ein Modell nicht auf gekennzeichneten Beispielen trainieren können oder wollen, was in den meisten realen Projekten der Fall ist.
const classifier = await pipeline('zero-shot-classification',
'Xenova/bart-large-mnli');
const result = await classifier(
'Meine Rechnung ist falsch und ich wurde doppelt belastet.',
['Abrechnung', 'technischer Support', 'Versand', 'Rücksendungen', 'Kontozugang']
);
// {
// sequence: 'Meine Rechnung ist falsch und ich wurde doppelt belastet.',
// labels: ['Abrechnung', 'Rücksendungen', 'Kontozugang', 'technischer Support', 'Versand'],
// scores: [0.871, 0.063, 0.031, 0.022, 0.013]
// }
Die Ausgabe ist ein Objekt mit drei Feldern. sequence ist der ursprüngliche Eingabetext. labels ist ein Array Ihrer Kandidatenlabels, sortiert von der höchsten zur niedrigsten Punktzahl. scores ist ein Array von Vertrauensscores in derselben Reihenfolge. Das erste Element beider Arrays ist immer die gewinnende Vorhersage. Die Scores aller Labels summieren sich auf ungefähr 1, wenn multi_label false ist (Standard).
Die Einstellung multi_label: true ändert das Verhalten: Jedes Label wird unabhängig bewertet, anstatt miteinander zu konkurrieren, sodass mehrere Labels gleichzeitig hohe Scores haben können. Verwenden Sie dies, wenn der Text plausibel zu mehreren Kategorien gleichzeitig gehört.
Aufgabe 3: Fragebeantwortung
Die Fragebeantwortung in Transformers.js ist extraktiv: Sie geben einen Textabschnitt als Kontext an und stellen eine Frage in einfachem Englisch. Das Modell lokalisiert den Abschnitt innerhalb des Textes, der die Frage am besten beantwortet, und gibt ihn zurück. Es generiert keinen Text oder schlussfolgert über das hinaus, was im Kontext wörtlich enthalten ist. Die Antwort ist immer ein Teilstring des bereitgestellten Eingabetyps.
So sieht die Ausgabe aus:
const qa = await pipeline('question-answering', 'Xenova/distilbert-base-uncased-distilled-squad');
const result = await qa({
question: 'Wie lange ist das Rückgabefenster für Elektronik?',
context: `Unsere Rückgabebestimmungen erlauben es Kunden, die meisten Artikel innerhalb von 30 Tagen nach dem Kauf zurückzugeben. Elektronik muss innerhalb von 15 Tagen zurückgegeben werden und muss in der Originalverpackung sein. Software und digitale Downloads sind nicht erstattungsfähig.`
});
// {
// answer: '15 Tage',
// score: 0.9823,
// start: 97, // Zeichenindex des Antwortbeginns im Kontext
// end: 104 // Zeichenindex des Antwortendes im Kontext
// }
Die Ausgabe hat vier Felder. answer ist der extrahierte Teilstring. score ist das Vertrauen des Modells, dass dieser Abschnitt die Frage beantwortet. start und end sind Zeichenindizes im ursprünglichen Kontext, die Sie verwenden können, um die Antwort im Quelltext hervorzuheben, was für die Benutzererfahrung bei längeren Dokumenten wertvoll ist.
Wenn die Frage im Kontext keine klare Antwort hat, wird score niedrig sein und answer kann ein kurzer, scheinbar zufälliger Abschnitt sein. Es ist gängige Praxis, Antworten mit niedrigem Vertrauen (unter 0.3 oder 0.4) als „nicht gefunden“ zu behandeln.
Leistungsfähigkeit, Einschränkungen und wann man es nicht verwenden sollte
Transformers.js entfernt den Server, beseitigt jedoch nicht die Kompromisse. Wenn Sie diese im Voraus kennen, können Sie unangenehme Überraschungen in der Produktion vermeiden.
- Downloadgröße: Die Pipeline zur Sentimentanalyse lädt beim ersten Laden etwa 111 MB herunter, was nicht riesig, aber auch nicht unsichtbar ist. Für Anwendungen, die auf mobile Benutzer oder Benutzer mit gemessenen Verbindungen abzielen, verwenden Sie die Modelle, um die Modellgrößen ungefähr zu halbieren und behandeln Sie das Modell als progressive Verbesserung; blockieren Sie die Benutzeroberfläche nicht beim Laden des Modells.
- Inferenzgeschwindigkeit: Auf einem modernen Laptop dauert die WASM-Inferenz für eine kurze Textklassifikation 50–200 ms. Die Zero-Shot-Klassifikation ist langsamer, da sie mehrere NLI-Durchläufe durchführt, einen pro Kandidatenlabel. Ein Zero-Shot-Durchlauf mit fünf Labels dauert typischerweise 1–3 Sekunden auf der CPU. WebGPU reduziert dies erheblich, wo unterstützt.
- Nur Inferenz: Transformers.js kann Modelle nicht feinabstimmen oder trainieren. Wenn Ihr Anwendungsfall ein benutzerdefiniertes Modell erfordert, beispielsweise einen Klassifikator, der auf Ihren eigenen gekennzeichneten Tickets trainiert wurde, erfolgt das Training auf einem Server (Python, Cloud), und der ONNX-Export läuft im Browser.
- Modellverfügbarkeit: Nicht jedes Modell im Hugging Face Hub hat eine ONNX-Version verfügbar. Um kompatible Modelle zu finden, filtern Sie nach dem Tag der transformers.js-Bibliothek im Hub.
- Wann man einen Server bevorzugen sollte: Bei der Verarbeitung von Hunderten von Texten, bei denen die Latenz pro Element wichtig ist, Aufgaben, die die größten Grenzmodelle erfordern, die zu groß für die Bereitstellung im Browser sind, oder einfache Anwendungen, bei denen die Entwicklungskosten der browserbasierten Inferenz die Vorteile überwiegen.
Fazit
Transformers.js bringt produktionsreifes NLP in den Browser, ohne einen Server, ohne API-Schlüssel und ohne dass Benutzerdaten das Gerät verlassen. Die drei Pipelines in diesem Tutorial – Textklassifikation, Zero-Shot-Kategorisierung und Fragebeantwortung – decken die analytische Oberfläche eines großen Teils der realen NLP-Anwendungsfälle ab. Der Supportticket-Router zeigt, wie sie in weniger als 200 Zeilen HTML und JavaScript zu etwas wirklich Nützlichem kombiniert werden können.
Der Einstiegspunkt ist so niedrig wie möglich: ein CDN-Import, ein await pipeline()-Aufruf, ein Inferenzaufruf. Beginnen Sie mit dem einfachsten Beispiel in diesem Artikel und führen Sie es aus. Ändern Sie die Labels in der Zero-Shot-Demo. Richten Sie das QA-Modell auf ein anderes Dokument aus. Die offizielle Dokumentation zu Transformers.js und das Beispiel-Repository decken ein viel breiteres Aufgabenspektrum ab: Zusammenfassung, Übersetzung, benannte Entitätserkennung und mehr, die alle dem gleichen pipeline()-Muster folgen.
Für weitere Informationen zu Python-Bibliotheken, die für LLM-Ingenieure nützlich sind, lesen Sie unseren Artikel über wichtige Python-Bibliotheken. Wenn Sie lernen möchten, wie Sie ein Echtzeit-Sprach-zu-Sprach-AI-Modell lokal ausführen, schauen Sie sich unseren Leitfaden an, um ein Echtzeit-Sprach-zu-Sprach-AI-Modell lokal auszuführen. Für eine Einführung in die Verwendung von Tiny AI-Modellen lokal, besuchen Sie unseren Artikel über Tiny AI-Modelle.
„`
Quellen: kdnuggets
Bildquelle: KI generiert