3 Punkte von GN⁺ 2024-04-13 | 1 Kommentare | Auf WhatsApp teilen
  • Transformers.js ist eine Bibliothek zum Ausführen von 🤗-Transformers-Modellen im Browser ohne Server. Sie zielt auf funktionale Gleichwertigkeit und eine ähnliche API wie Hugging Faces Python-transformers ab
  • Für die Modellausführung wird ONNX Runtime verwendet; vortrainierte Modelle aus PyTorch, TensorFlow und JAX können mit 🤗 Optimum nach ONNX konvertiert und genutzt werden
  • Über die pipeline-API lassen sich Aufgaben wie Sentiment-Analyse ähnlich wie in Python aufrufen; als zweites Argument kann eine Modell-ID oder ein Pfad angegeben werden, um ein anderes Modell auszuwählen
  • Die Standardausführung im Browser erfolgt auf einer WASM-basierten CPU; mit device: 'webgpu' kann WebGPU-Ausführung gewählt werden, die WebGPU API ist in vielen Browsern jedoch noch experimentell
  • In ressourcenbeschränkten Umgebungen wie Webbrowsern lässt sich mit dtype ein Datentyp wie "fp32", "fp16", "q8" oder "q4" wählen, um Bandbreite und Performance abzustimmen

Transformers im Browser ausführen

  • Transformers.js ist eine Bibliothek, die dafür entwickelt wurde, 🤗 Transformers direkt im Browser ohne Server auszuführen
  • Sie zielt auf eine funktional gleichwertige Nutzungserfahrung zur Python-Bibliothek transformers von Hugging Face ab und kann dieselben vortrainierten Modelle über eine sehr ähnliche API ausführen
  • Unterstützte Aufgaben erstrecken sich über mehrere Modalitäten
    • Natural Language Processing: Textklassifikation, Named Entity Recognition, Question Answering, Sprachmodellierung, Zusammenfassung, Übersetzung, Multiple Choice, Textgenerierung
    • Computer Vision: Bildklassifikation, Objekterkennung, Segmentierung, Tiefenschätzung
    • Audio: automatische Spracherkennung, Audioklassifikation, Text-to-Speech
    • Multimodal: Embeddings, Zero-Shot-Audioklassifikation, Zero-Shot-Bildklassifikation, Zero-Shot-Objekterkennung

Ausführungsweise und Modellkonvertierung

Installation und Nutzung im Browser

  • Das NPM-Paket wird mit folgendem Befehl installiert
npm i @huggingface/transformers
  • Es kann auch in Vanilla JS ohne Bundler genutzt und über ein CDN oder statisches Hosting als ES Modules importiert werden
<script type="module">
    import { pipeline } from 'https://cdn.jsdelivr.net/npm/@huggingface/transformers@4.2.0';
</script>

Python-ähnliche pipeline API

  • Die pipeline-API bündelt vortrainierte Modelle, Eingabe-Preprocessing und Ausgabe-Postprocessing und ist der einfachste Weg, Modelle in der Bibliothek auszuführen
  • Ähnlich wie im Sentiment-Analyse-Beispiel von Python-transformers kann man auch in JavaScript pipeline('sentiment-analysis') erstellen, Text eingeben und Ergebnisse erhalten
import { pipeline } from '@huggingface/transformers';

const pipe = await pipeline('sentiment-analysis');
const out = await pipe('I love transformers!');
// [{'label': 'POSITIVE', 'score': 0.999817686}]
  • Um ein anderes Modell zu verwenden, gibt man als zweites Argument der Funktion pipeline eine Modell-ID oder einen Pfad an
const pipe = await pipeline(
  'sentiment-analysis',
  'Xenova/bert-base-multilingual-uncased-sentiment'
);

CPU, WebGPU und Quantisierungsoptionen

  • Der Standard für die Ausführung im Browser ist eine WASM-basierte CPU-Ausführung
  • Für die Ausführung auf der GPU wird device: 'webgpu' gesetzt
const pipe = await pipeline(
  'sentiment-analysis',
  'Xenova/distilbert-base-uncased-finetuned-sst-2-english',
  {
    device: 'webgpu',
  }
);
  • Weitere Details zu WebGPU stehen im WebGPU guide
  • Da die WebGPU API in vielen Browsern noch experimentell ist, wird bei Problemen empfohlen, einen WebGPU-Bug-Report einzureichen
  • In ressourcenbeschränkten Webbrowser-Umgebungen wird die Nutzung quantisierter Modelle empfohlen
    • Mit der Option dtype wird der Datentyp des Modells ausgewählt
    • Übliche Optionen sind "fp32" als WebGPU-Standard, "fp16", "q8" als WASM-Standard und "q4"
    • Weitere Details stehen im quantization guide
const pipe = await pipeline(
  'sentiment-analysis',
  'Xenova/distilbert-base-uncased-finetuned-sst-2-english',
  {
    dtype: 'q4',
  }
);

Benutzerdefinierte Konfiguration

import { env } from '@huggingface/transformers';

env.localModelPath = '/path/to/models/';
env.allowRemoteModels = false;
env.backends.onnx.wasm.wasmPaths = '/path/to/files/';
  • Die vollständigen verfügbaren Einstellungen stehen in der API Reference
  • Beim Konvertieren von PyTorch-Modellen nach ONNX wird der Ein-Befehl-Ansatz mit Optimum empfohlen

Unterstützte Aufgaben und Modellumfang

  • Um kompatible Modelle im Hugging Face Hub zu finden, kann nach dem Bibliotheks-Tag transformers.js gefiltert werden
  • Die unterstützten Aufgaben erstrecken sich über Natural Language Processing, Vision, Audio, Multimodal und Reinforcement Learning; einige Aufgaben werden noch nicht unterstützt
    • Im Natural Language Processing werden unter anderem fill-mask, question-answering, summarization, text-classification, text-generation, token-classification, translation, zero-shot-classification und feature-extraction unterstützt
    • Im Vision-Bereich werden unter anderem background-removal, depth-estimation, image-classification, image-segmentation, image-to-image, object-detection und image-feature-extraction unterstützt
    • Im Audiobereich werden audio-classification, automatic-speech-recognition und text-to-speech unterstützt
    • Im multimodalen Bereich werden unter anderem document-question-answering, image-to-text, zero-shot audio/image classification und zero-shot object detection unterstützt
  • Auch noch nicht unterstützte Aufgaben sind ausdrücklich aufgeführt
    • table-question-answering, mask-generation, video-classification, unconditional-image-generation
    • audio-to-audio, tabular-classification, tabular-regression
    • text-to-image, visual-question-answering
  • Die Liste unterstützter Modellarchitekturen umfasst zahlreiche Modellfamilien, darunter BERT, BART, CLIP, DistilBERT, Whisper, Llama, Qwen, Gemma, Phi, Segment Anything und ViT
  • Wenn eine gewünschte Aufgabe oder ein gewünschtes Modell nicht auf der Liste steht oder noch nicht unterstützt wird, kann ein Feature Request eröffnet werden

1 Kommentare

 
GN⁺ 2024-04-13
Meinungen auf Hacker News
  • Diese Library ist wirklich großartig. Es ist extrem einfach, schnell eine Demo aufzusetzen, daher habe ich sie ein paar Mal in Observable Notebooks verwendet
    CLIP im Browser: https://observablehq.com/@simonw/openai-clip-in-a-browser
    Objekterkennung in Bildern mit detra-resnet-50: https://observablehq.com/@simonw/detect-objects-in-images
    Die Modellgröße wirkt anfangs wie eine Einschränkung, aber es gibt durchaus Apps, bei denen es nicht völlig abwegig ist, Nutzer mit einem guten Notebook und einer guten Verbindung rund 30 Sekunden auf das Laden warten zu lassen
    Im neuesten Release wurde Unterstützung für Binary Embedding Quantization hinzugefügt, das möchte ich unbedingt ausprobieren: https://github.com/xenova/transformers.js/releases/tag/2.17....
    • Binary Embeddings werden wohl zusätzliches Reranking benötigen, aber es dürfte spannend sein, das zu testen
      Ich habe ein npm-Paket für transformers.js v3 erstellt und sollte es wohl aktualisieren. Ich bin mir nicht sicher, ob dieses Feature schon enthalten ist
      Ich habe hauptsächlich einen Fork gepflegt, damit es mit bun läuft; wenn v3 veröffentlicht wird, soll bun richtig unterstützt werden. WebGPU wird allerdings nicht funktionieren, ist aber optional
      [Edit: Wenn du es verwenden willst, schreib mir eine DM. Ich möchte den Fork nicht bewerben]
  • Ich nutze diese Library, um gte-small-Embeddings (~0,07 GB) zu erzeugen und in Upstash Vector zu speichern
    Es sind nur 384 Dimensionen, aber bei Text auf Absatzebene funktioniert es überraschend gut. In den Leaderboards liegt es sogar vor text-embedding-ada-002
    https://huggingface.co/spaces/mteb/leaderboard
  • Der Syntax-Podcast hat kürzlich eine Folge zu Transformers.js und dem Entwickler veröffentlicht
    https://syntax.fm/show/740/local-ai-models-in-javascript-mac...
  • transformers.js ist wirklich eine großartige Library
    Ich habe eine kleine Web-App gebaut, die mit dem RMBG1.4-Modell von BRIA AI Bildhintergründe entfernt: https://aether.nco.dev
    Dass man keine Daten an eine API schicken muss und es sogar auf Smartphones läuft, ist wirklich gut. Ich denke, künftig werden viele Projekte für kleine Vision-, Sprach- und andere Utility-Modelle (Tiefenschätzung, Hintergrundentfernung usw.) darauf setzen, und die Zukunft des Webs sieht vielversprechend aus
    Am nächsten Projekt arbeite ich bereits, und dort werde ich transformers.js sicher wieder verwenden
    • Ich nutze es für ein einfaches Projekt: https://github.com/sroussey/ellmers
      Geplant ist, Embeddings und Suchstrategien für verschiedene RAG-Strategien zu testen, die auf Servern oder in Electron-Apps eingesetzt werden sollen
  • Wirklich cool, aber leider scheint die Praxistauglichkeit ziemlich gering zu sein. Modelle sind in der Regel recht groß; selbst wenn der Browser sie ausführen kann, braucht es für den Weg bis in den Browser eines von zwei Dingen
    1. einen großen Download bei jedem Besuch der Website
    2. für jede Website, die ein großes Modell verwendet, einen großen Download und hohen Speicherbedarf. Zum Beispiel würden 150 Websites × ein 800-MB-Modell 120 GB Speicher belegen
      Beides ist nicht schön
      Langfristig könnte es richtig sein, dass Browser einige Modelle eingebaut haben und sie über standardisierte Web-APIs bereitstellen, aber ich habe noch nicht gehört, dass entsprechende Bemühungen laufen

Modelle werden domainspezifisch gecacht (über die Web Cache API) und müssen nicht bei jedem Laden der Seite erneut heruntergeladen werden. Wenn man Modelle über Domains hinweg vorhalten möchte, kann man mit dieser Library eine Browser-Erweiterung bauen.
Zum zuletzt genannten Punkt laufen zwar Arbeiten, aber es ist noch nicht in einem Stadium, über das man sprechen kann.

  • Das ist fast dasselbe Problem, das Webgames seit den ersten Unreal-/Unity-asm.js-Demos vor 10 Jahren plagt, und seitdem gab es in Richtung Lösung kaum Fortschritte.
    Webapps, die gigabyteweise Daten auf dem Client benötigen, sind praktisch schwer umzusetzen. Es gibt keine zuverlässige Methode, um zu garantieren, dass sie so lange im Cache bleiben, wie der Nutzer es möchte, und selbst wenn man sie zuverlässig cachen könnte, führen die Cache-Partitioning-Richtlinien der Browser dazu, dass Downloads und Speicherplatz für jede Website, die dasselbe Modell nutzt, dupliziert werden.
  • Die Modelle sind unter 80 MB groß; der Rest sind LLMs und damit außerhalb des Scopes. Whisper hat 40 MB, Embeddings 23 MB.
    Formulierungen aus dem ursprünglichen Kommentar wie „wirkt sehr unpraktisch“, „Modelle sind im Allgemeinen ziemlich groß“ oder „150 Websites × 800-MB-Modell“ wirken, als würden sie selbst mit einem Hinweis auf mangelndes Verständnis versehen.
  • Manche Modelle sind ziemlich klein, sodass es sich lohnt, sie on-device laufen zu lassen, statt alle Daten zur Verarbeitung an einen Server zu schicken.
    Ein weiterer großer Vorteil ist, dass transformers auch unter Node.js läuft. Eine Laufzeitumgebung dafür aufzusetzen ist viel einfacher, als die seltsame Kombination aus Python und dessen Abhängigkeiten passend hinzubekommen.
  • Das ist nicht nur ein Browser-Problem, sondern ein grundlegendes Problem von On-Device-AI-Verarbeitung.
    Es dürfte besser werden, wenn Betriebssysteme anfangen, Modelle vorzuinstallieren, und Browser-Anbieter APIs bereitstellen, die diese ebenfalls nutzen können.
    Trotzdem sind Cloud-gehostete Modelle bei den meisten Aufgaben wahrscheinlich immer deutlich besser.
  • Heißt das, man kann jetzt ein Browser-Plugin bauen, das bei Google-Captchas alle Fahrräder oder Brücken auswählt?
  • Ist Training nicht möglich? Vor ein paar Jahren habe ich daran gearbeitet, im Browser ein kleines neuronales Netz zu erstellen und zu trainieren, und ich frage mich, ob so ein Ansatz heute mit einem kleinen Custom Transformer besser funktionieren würde.
    • Theoretisch ist es sicher möglich, aber vermutlich ist die Performance der Grund, warum es noch nicht implementiert wurde.
      Auf Hugging Face Space gibt es einen WebGPU-Embedding-Benchmark, mit dem man die Forward-Pass-Ausführung einschätzen kann: https://huggingface.co/spaces/Xenova/webgpu-embedding-benchm...
      An sich ist das beeindruckend, aber Training dürfte mit dieser Latenz schmerzhaft sein. Bei fp16, Batch 32 und einer Sequenzlänge von 512 dauert der Forward Pass eines Modells mit 22 Millionen Parametern etwa 500 ms.
  • Öffnet das nicht auch die Möglichkeit, solche Modelle in Node.js-Serverless Functions laufen zu lassen?
    Für On-Demand-Predictions dürfte sich damit definitiv Potenzial ergeben.
  • Unterstützt es Beschleunigung auf Apple Silicon?