Diese Seite wurde von der Cloud Translation API übersetzt.
Switch to English

Plattform und Umgebung

TensorFlow.js funktioniert im Browser und in Node.js, und auf beiden Plattformen stehen viele verschiedene Konfigurationen zur Verfügung. Jede Plattform hat eine Reihe von Überlegungen, die sich auf die Art und Weise auswirken, wie Anwendungen entwickelt werden.

Im Browser unterstützt TensorFlow.js sowohl mobile Geräte als auch Desktop-Geräte. Jedes Gerät verfügt über bestimmte Einschränkungen, z. B. verfügbare WebGL-APIs, die automatisch für Sie ermittelt und konfiguriert werden.

In Node.js unterstützt TensorFlow.js die direkte Bindung an die TensorFlow-API oder die Ausführung mit langsameren Vanilla-CPU-Implementierungen.

Umgebungen

Wenn ein TensorFlow.js-Programm ausgeführt wird, wird die spezifische Konfiguration als Umgebung bezeichnet. Die Umgebung besteht aus einem einzelnen globalen Backend sowie einer Reihe von Flags, die die detaillierten Funktionen von TensorFlow.js steuern.

Backends

TensorFlow.js unterstützt mehrere verschiedene Backends, die Tensorspeicher und mathematische Operationen implementieren. Zu jedem Zeitpunkt ist nur ein Backend aktiv. In den meisten Fällen wählt TensorFlow.js in der aktuellen Umgebung automatisch das beste Backend für Sie aus. Manchmal ist es jedoch wichtig zu wissen, welches Backend verwendet wird und wie es gewechselt werden kann.

So finden Sie das verwendete Backend:

 console.log(tf.getBackend());
 

Wenn Sie das Backend manuell ändern möchten:

 tf.setBackend('cpu');
console.log(tf.getBackend());
 

WebGL-Backend

Das WebGL-Backend 'webgl' ist derzeit das leistungsstärkste Backend für den Browser. Dieses Backend ist bis zu 100x schneller als das Vanilla-CPU-Backend. Tensoren werden als WebGL-Texturen gespeichert und mathematische Operationen werden in WebGL-Shadern implementiert. Hier sind einige nützliche Dinge, die Sie bei der Verwendung dieses Backends beachten sollten: \

Vermeiden Sie es, den UI-Thread zu blockieren

Wenn eine Operation wie tf.matMul (a, b) aufgerufen wird, wird der resultierende tf.Tensor synchron zurückgegeben, die Berechnung der Matrixmultiplikation ist jedoch möglicherweise noch nicht fertig. Dies bedeutet, dass der zurückgegebene tf.Tensor nur ein Handle für die Berechnung ist. Wenn Sie x.data() oder x.array() , werden die Werte aufgelöst, wenn die Berechnung tatsächlich abgeschlossen ist. Daher ist es wichtig, die asynchronen x.data() und x.array() gegenüber ihren synchronen Gegenstücken x.dataSync() und x.arraySync() zu verwenden, um zu vermeiden, dass der UI-Thread blockiert wird, während die Berechnung abgeschlossen ist.

Speicherverwaltung

Eine Einschränkung bei der Verwendung des WebGL-Backends ist die Notwendigkeit einer expliziten Speicherverwaltung. WebGLTextures, in denen letztendlich Tensor-Daten gespeichert werden, werden nicht automatisch vom Browser gesammelt.

Um den Speicher eines tf.Tensor zu zerstören, können Sie die tf.Tensor dispose() -Methode verwenden:

 const a = tf.tensor([[1, 2], [3, 4]]);
a.dispose();
 

Es ist sehr üblich, mehrere Vorgänge in einer Anwendung miteinander zu verketten. Das Halten eines Verweises auf alle Zwischenvariablen, um sie zu entsorgen, kann die Lesbarkeit des Codes verringern. Um dieses Problem zu lösen, bietet TensorFlow.js eine tf.tidy() -Methode, mit der alle tf.Tensor s bereinigt werden, die von einer Funktion nach ihrer Ausführung nicht zurückgegeben werden, ähnlich wie lokale Variablen bei der Ausführung einer Funktion bereinigt werden:

 const a = tf.tensor([[1, 2], [3, 4]]);
const y = tf.tidy(() => {
  const result = a.square().log().neg();
  return result;
});
 
Präzision

Auf Mobilgeräten unterstützt WebGL möglicherweise nur 16-Bit-Gleitkomma-Texturen. Die meisten Modelle für maschinelles Lernen werden jedoch mit 32-Bit-Gleitkommagewichten und -aktivierungen trainiert. Dies kann beim Portieren eines Modells für ein mobiles Gerät zu Präzisionsproblemen führen, da 16-Bit-Gleitkommazahlen nur Zahlen im Bereich [0.000000059605, 65504] . Dies bedeutet, dass Sie darauf achten sollten, dass Gewichte und Aktivierungen in Ihrem Modell diesen Bereich nicht überschreiten. Um zu überprüfen, ob das Gerät 32-Bit-Texturen unterstützt, überprüfen Sie den Wert von tf.ENV.getBool('WEBGL_RENDER_FLOAT32_CAPABLE') . Wenn dies falsch ist, unterstützt das Gerät nur 16-Bit-Gleitkomma-Texturen. Mit tf.ENV.getBool('WEBGL_RENDER_FLOAT32_ENABLED') überprüfen, ob TensorFlow.js derzeit 32-Bit-Texturen verwendet.

Shader-Kompilierung und Textur-Uploads

TensorFlow.js führt Operationen auf der GPU aus, indem WebGL-Shader-Programme ausgeführt werden. Diese Shader werden träge zusammengestellt und kompiliert, wenn der Benutzer eine Operation ausführen möchte. Die Kompilierung eines Shaders erfolgt auf der CPU im Hauptthread und kann langsam sein. TensorFlow.js speichert die kompilierten Shader automatisch zwischen, wodurch der zweite Aufruf derselben Operation mit Eingabe- und Ausgabe-Tensoren derselben Form viel schneller erfolgt. In der Regel verwenden TensorFlow.js-Anwendungen während der gesamten Lebensdauer der Anwendung dieselben Vorgänge mehrmals, sodass der zweite Durchgang durch ein Modell für maschinelles Lernen viel schneller ist.

TensorFlow.js speichert auch tf.Tensor-Daten als WebGLTextures. Wenn ein tf.Tensor erstellt wird, laden wir nicht sofort Daten auf die GPU tf.Tensor , sondern behalten die Daten auf der CPU, bis der tf.Tensor in einer Operation verwendet wird. Wenn der tf.Tensor ein zweites Mal verwendet wird, befinden sich die Daten bereits auf der GPU, sodass keine Upload-Kosten tf.Tensor . In einem typischen Modell für maschinelles Lernen bedeutet dies, dass Gewichte während der ersten Vorhersage durch das Modell hochgeladen werden und der zweite Durchgang durch das Modell viel schneller ist.

Wenn Sie sich für die Leistung der ersten Vorhersage durch Ihr Modell oder den TensorFlow.js-Code interessieren, empfehlen wir, das Modell aufzuwärmen, indem Sie einen Eingabe-Tensor derselben Form übergeben, bevor echte Daten verwendet werden.

Beispielsweise:

 const model = await tf.loadLayersModel(modelUrl);

// Warmup the model before using real data.
const warmupResult = model.predict(tf.zeros(inputShape));
warmupResult.dataSync();
warmupResult.dispose();

// The second predict() will be much faster
const result = model.predict(userData);
 

Node.js TensorFlow-Backend

Im Backend von TensorFlow Node.j, 'node', wird die TensorFlow C-API verwendet, um Vorgänge zu beschleunigen. Hierbei wird die verfügbare Hardwarebeschleunigung der Maschine wie CUDA verwendet, sofern verfügbar.

In diesem Backend geben Operationen genau wie im WebGL-Backend synchron tf.Tensor . Im Gegensatz zum WebGL-Backend wird der Vorgang jedoch abgeschlossen, bevor Sie den Tensor zurückerhalten. Dies bedeutet, dass ein Aufruf von tf.matMul(a, b) den UI-Thread blockiert.

Wenn Sie dies in einer Produktionsanwendung verwenden möchten, sollten Sie aus diesem Grund TensorFlow.js in Arbeitsthreads ausführen, um den Hauptthread nicht zu blockieren.

Weitere Informationen zu Node.js finden Sie in diesem Handbuch.

WASM-Backend

TensorFlow.js bietet ein WebAssembly-Backend ( wasm ), das CPU-Beschleunigung bietet und als Alternative zu den Vanilla-JavaScript-CPU- ( cpu ) und WebGL-beschleunigten ( webgl ) Backends verwendet werden kann. Um es zu benutzen:

 // Set the backend to WASM and wait for the module to be ready.
tf.setBackend('wasm');
tf.ready().then(() => {...});
 

Wenn Ihr Server die .wasm Datei unter einem anderen Pfad oder einem anderen Namen setWasmPath , verwenden Sie setWasmPath bevor Sie das Backend initialisieren. Weitere Informationen finden Sie im Abschnitt "Verwenden von Bundlern" in der README- Datei :

 import {setWasmPath} from '@tensorflow/tfjs-backend-wasm';
setWasmPath(yourCustomPath);
tf.setBackend('wasm');
tf.ready().then(() => {...});
 
Warum WASM?

WASM wurde 2015 als neues webbasiertes Binärformat eingeführt, das in JavaScript, C, C ++ usw. geschriebene Programme als Kompilierungsziel für die Ausführung im Web bereitstellt. Wasm wurde unterstützt von Chrome, Safari, Firefox und Edge - seit 2017 und wird unterstützt von 90% der Geräte weltweit.

Performance

Das WASM-Backend nutzt die XNNPACK-Bibliothek für die optimierte Implementierung von Betreibern neuronaler Netze.

Versus JavaScript : WASM-Binärdateien sind im Allgemeinen viel schneller als JavaScript-Bundles, damit Browser sie laden, analysieren und ausführen können. JavaScript wird dynamisch typisiert und Müll gesammelt, was zur Laufzeit zu Verlangsamungen führen kann.

Versus WebGL : WebGL ist für die meisten Modelle schneller als WASM, aber für kleine Modelle kann WASM WebGL aufgrund der festen Gemeinkosten für die Ausführung von WebGL-Shadern übertreffen. Im folgenden Abschnitt „Wann sollte ich WASM verwenden?“ Werden die Heuristiken für diese Entscheidung erläutert.

Portabilität und Stabilität

WASM verfügt über eine tragbare 32-Bit-Float-Arithmetik, die Präzisionsparität für alle Geräte bietet. WebGL hingegen ist hardwarespezifisch und verschiedene Geräte können unterschiedliche Genauigkeiten aufweisen (z. B. Fallback auf 16-Bit-Floats auf iOS-Geräten).

Wie WebGL wird WASM offiziell von allen gängigen Browsern unterstützt. Im Gegensatz zu WebGL kann WASM in Node.js ausgeführt und serverseitig verwendet werden, ohne dass native Bibliotheken kompiliert werden müssen.

Wann sollte ich WASM verwenden?

Modellgröße und Rechenaufwand

Im Allgemeinen ist WASM eine gute Wahl, wenn Modelle kleiner sind oder Sie sich für Geräte der unteren OES_texture_float , die keine WebGL-Unterstützung ( OES_texture_float Erweiterung) haben oder weniger leistungsfähige GPUs haben. Die folgende Tabelle zeigt die Inferenzzeiten (ab TensorFlow.js 1.5.2) in Chrome auf einem 2018 MacBook Pro für 5 unserer offiziell unterstützten Modelle im WebGL-, WASM- und CPU-Backend:

Kleinere Modelle

Modell WebGL WASM Zentralprozessor Erinnerung
BlazeFace 22,5 ms 15,6 ms 315,2 ms 0,4 MB
FaceMesh 19,3 ms 19,2 ms 335 ms 2,8 MB

Größere Modelle

Modell WebGL WASM Zentralprozessor Erinnerung
PoseNet 42,5 ms 173,9 ms 1514,7 ms 4,5 MB
BodyPix 77 ms 188,4 ms 2683 ms 4,6 MB
MobileNet v2 37 ms 94 ms 923,6 ms 13 MB

Die obige Tabelle zeigt, dass WASM modellübergreifend 10 bis 30 Mal schneller als das einfache JS-CPU-Backend ist und mit WebGL für kleinere Modelle wie BlazeFace konkurriert , das leicht (400 KB) ist und dennoch eine anständige Anzahl von Operationen (~ 140) aufweist. Angesichts der Tatsache, dass WebGL-Programme feste Betriebskosten pro Op-Ausführung haben, erklärt dies, warum Modelle wie BlazeFace in WASM schneller sind.

Diese Ergebnisse variieren je nach Gerät. Der beste Weg, um festzustellen, ob WASM für Ihre Anwendung geeignet ist, besteht darin, es auf unseren verschiedenen Backends zu testen.

Inferenz gegen Training

Um den primären Anwendungsfall für die Bereitstellung vorab trainierter Modelle anzugehen, wird bei der WASM-Backend-Entwicklung die Inferenz Vorrang vor der Schulungsunterstützung haben . Sehen Sie sich eine aktuelle Liste der unterstützten Operationen in WASM an und teilen Sie uns mit, ob Ihr Modell eine nicht unterstützte Operation hat. Für Trainingsmodelle empfehlen wir die Verwendung des Node-Backends (TensorFlow C ++) oder des WebGL-Backends.

CPU-Backend

Das CPU-Backend 'cpu' ist das Backend mit der geringsten Leistung, jedoch das einfachste. Alle Vorgänge sind in Vanille-JavaScript implementiert, wodurch sie weniger parallelisierbar sind. Sie blockieren auch den UI-Thread.

Dieses Backend kann zum Testen oder auf Geräten, auf denen WebGL nicht verfügbar ist, sehr nützlich sein.

Flaggen

TensorFlow.js verfügt über eine Reihe von Umgebungsflags, die automatisch ausgewertet werden und die beste Konfiguration auf der aktuellen Plattform ermitteln. Diese Flags sind größtenteils intern, aber einige globale Flags können mit der öffentlichen API gesteuert werden.

  • tf.enableProdMode(): den Produktionsmodus, der die Modellvalidierung, NaN-Prüfungen und andere Korrektheitsprüfungen zugunsten der Leistung entfernt.
  • tf.enableDebugMode() : tf.enableDebugMode() den Debug-Modus, der jede ausgeführte Operation sowie Informationen zur Laufzeitleistung wie Speicherbedarf und Gesamtausführungszeit des Kernels in der Konsole protokolliert. Beachten Sie, dass dies Ihre Anwendung erheblich verlangsamt. Verwenden Sie dies nicht in der Produktion.