Cette page a été traduite par l'API Cloud Translation.
Switch to English

Plateforme et environnement

TensorFlow.js fonctionne dans le navigateur et Node.js, et dans les deux plates-formes, il existe de nombreuses configurations disponibles. Chaque plate-forme a un ensemble unique de considérations qui affecteront la façon dont les applications sont développées.

Dans le navigateur, TensorFlow.js prend en charge les appareils mobiles ainsi que les appareils de bureau. Chaque appareil possède un ensemble spécifique de contraintes, telles que les API WebGL disponibles, qui sont automatiquement déterminées et configurées pour vous.

Dans Node.js, TensorFlow.js prend en charge la liaison directe à l'API TensorFlow ou s'exécute avec les implémentations de CPU vanilla plus lentes.

Environnements

Lorsqu'un programme TensorFlow.js est exécuté, la configuration spécifique est appelée l'environnement. L'environnement est composé d'un seul backend global ainsi que d'un ensemble d'indicateurs qui contrôlent les fonctionnalités affinées de TensorFlow.js.

Backends

TensorFlow.js prend en charge plusieurs backends différents qui implémentent le stockage de tenseurs et les opérations mathématiques. À tout moment, un seul backend est actif. La plupart du temps, TensorFlow.js choisira automatiquement le meilleur backend pour vous compte tenu de l'environnement actuel. Cependant, il est parfois important de savoir quel backend est utilisé et comment le changer.

Pour trouver quel backend vous utilisez:

console.log(tf.getBackend());

Si vous souhaitez modifier manuellement le backend:

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

Backend WebGL

Le backend WebGL, «webgl», est actuellement le backend le plus puissant pour le navigateur. Ce backend est jusqu'à 100 fois plus rapide que le backend CPU vanilla. Les tenseurs sont stockés sous forme de textures WebGL et les opérations mathématiques sont implémentées dans les shaders WebGL. Voici quelques informations utiles à connaître lors de l'utilisation de ce backend: \

Évitez de bloquer le thread de l'interface utilisateur

Lorsqu'une opération est appelée, comme tf.matMul (a, b), le tf.Tensor résultant est renvoyé de manière synchrone, mais le calcul de la multiplication matricielle peut ne pas être encore prêt. Cela signifie que le tf.Tensor renvoyé n'est qu'un descripteur du calcul. Lorsque vous appelez x.data() ou x.array() , les valeurs seront x.array() fois le calcul terminé. Cela rend important d'utiliser les x.data() asynchrones x.data() et x.array() sur leurs homologues synchrones x.dataSync() et x.arraySync() pour éviter de bloquer le thread d'interface utilisateur pendant la fin du calcul.

Gestion de la mémoire

Une mise en garde lors de l'utilisation du backend WebGL est la nécessité d'une gestion explicite de la mémoire. WebGLTextures, qui est l'endroit où les données Tensor sont finalement stockées, ne sont pas automatiquement collectées par le navigateur.

Pour détruire la mémoire d'un tf.Tensor , vous pouvez utiliser la méthode dispose() :

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

Il est très courant d'enchaîner plusieurs opérations dans une application. Le fait de conserver une référence à toutes les variables intermédiaires pour les éliminer peut réduire la lisibilité du code. Pour résoudre ce problème, TensorFlow.js fournit une méthode tf.tidy() qui nettoie tous les tf.Tensor qui ne sont pas retournés par une fonction après son exécution, de la même manière que les variables locales sont nettoyées lorsqu'une fonction est exécutée:

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

Sur les appareils mobiles, WebGL peut ne prendre en charge que les textures à virgule flottante 16 bits. Cependant, la plupart des modèles d'apprentissage automatique sont entraînés avec des pondérations et des activations en virgule flottante 32 bits. Cela peut entraîner des problèmes de précision lors du portage d'un modèle pour un appareil mobile car les nombres flottants 16 bits ne peuvent représenter que des nombres compris dans la plage [0.000000059605, 65504] . Cela signifie que vous devez faire attention à ce que les poids et les activations de votre modèle ne dépassent pas cette plage. Pour vérifier si le périphérique prend en charge les textures 32 bits, vérifiez la valeur de tf.ENV.getBool('WEBGL_RENDER_FLOAT32_CAPABLE') , si cela est faux, le périphérique ne prend en charge que les textures flottantes 16 bits. Vous pouvez utiliser tf.ENV.getBool('WEBGL_RENDER_FLOAT32_ENABLED') pour vérifier si TensorFlow.js utilise actuellement des textures 32 bits.

Compilation de shaders et téléchargements de textures

TensorFlow.js exécute des opérations sur le GPU en exécutant des programmes de shader WebGL. Ces shaders sont assemblés et compilés paresseusement lorsque l'utilisateur demande à exécuter une opération. La compilation d'un shader se produit sur le CPU sur le thread principal et peut être lente. TensorFlow.js mettra automatiquement en cache les shaders compilés, faisant le deuxième appel à la même opération avec des tenseurs d'entrée et de sortie de la même forme beaucoup plus rapidement. En règle générale, les applications TensorFlow.js utiliseront les mêmes opérations plusieurs fois au cours de la durée de vie de l'application, de sorte que le deuxième passage dans un modèle d'apprentissage automatique est beaucoup plus rapide.

TensorFlow.js stocke également les données tf.Tensor sous forme de WebGLTextures. Lorsqu'un tf.Tensor est créé, nous ne téléchargeons pas immédiatement les données sur le GPU, nous les conservons plutôt sur le CPU jusqu'à ce que le tf.Tensor soit utilisé dans une opération. Si le tf.Tensor est utilisé une deuxième fois, les données sont déjà sur le GPU, il n'y a donc aucun coût de téléchargement. Dans un modèle d'apprentissage automatique typique, cela signifie que les pondérations sont téléchargées lors de la première prédiction via le modèle et que le deuxième passage dans le modèle sera beaucoup plus rapide.

Si vous vous souciez des performances de la première prédiction via votre modèle ou le code TensorFlow.js, nous vous recommandons de réchauffer le modèle en passant un Tensor d'entrée de la même forme avant d'utiliser des données réelles.

Par exemple:

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);

Backend Node.js TensorFlow

Dans le backend TensorFlow Node.js, «node», l'API TensorFlow C est utilisée pour accélérer les opérations. Cela utilisera l'accélération matérielle disponible de la machine, comme CUDA, si disponible.

Dans ce backend, tout comme le backend WebGL, les opérations renvoient tf.Tensor synchrone. Cependant, contrairement au backend WebGL, l'opération est terminée avant que vous ne récupériez le tenseur. Cela signifie qu'un appel à tf.matMul(a, b) bloquera le thread d'interface utilisateur.

Pour cette raison, si vous avez l'intention de l'utiliser dans une application de production, vous devez exécuter TensorFlow.js dans les threads de travail pour ne pas bloquer le thread principal.

Pour plus d'informations sur Node.js, consultez ce guide.

Backend WASM

TensorFlow.js fournit un backend WebAssembly ( wasm ), qui offre une accélération du processeur et peut être utilisé comme alternative aux webgl vanilla JavaScript CPU ( cpu ) et WebGL ( webgl ). Pour l'utiliser:

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

Si votre serveur sert le fichier .wasm sur un chemin ou un nom différent, utilisez setWasmPath avant d'initialiser le backend. Consultez la section "Utilisation des bundlers" dans le README pour plus d'informations:

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

WASM a été introduit en 2015 en tant que nouveau format binaire basé sur le Web, fournissant des programmes écrits en JavaScript, C, C ++, etc., une cible de compilation pour s'exécuter sur le Web. WASM est pris en charge par Chrome, Safari, Firefox et Edge depuis 2017, et est pris en charge par 90% des appareils dans le monde.

Performance

Le backend WASM exploite la bibliothèque XNNPACK pour une implémentation optimisée des opérateurs de réseaux neuronaux.

Par rapport à JavaScript : les binaires WASM sont généralement beaucoup plus rapides que les bundles JavaScript pour les navigateurs à charger, analyser et exécuter. JavaScript est dynamiquement typé et récupéré, ce qui peut entraîner des ralentissements lors de l'exécution.

Par rapport à WebGL : WebGL est plus rapide que WASM pour la plupart des modèles, mais pour les modèles minuscules, WASM peut surpasser WebGL en raison des frais généraux fixes liés à l'exécution des shaders WebGL. La section «Quand dois-je utiliser WASM» ci-dessous traite des heuristiques pour prendre cette décision.

Portabilité et stabilité

WASM dispose d'une arithmétique flottante 32 bits portable, offrant une parité de précision sur tous les appareils. WebGL, en revanche, est spécifique au matériel et différents appareils peuvent avoir une précision variable (par exemple, le repli vers les flottants 16 bits sur les appareils iOS).

Comme WebGL, WASM est officiellement pris en charge par tous les principaux navigateurs. Contrairement à WebGL, WASM peut s'exécuter dans Node.js et être utilisé côté serveur sans qu'il soit nécessaire de compiler des bibliothèques natives.

Quand dois-je utiliser WASM?

Taille du modèle et demande de calcul

En général, WASM est un bon choix lorsque les modèles sont plus petits ou que vous vous souciez des périphériques bas de gamme qui ne prennent pas en charge WebGL (extension OES_texture_float ) ou ont des GPU moins puissants. Le graphique ci-dessous montre les temps d'inférence (à partir de TensorFlow.js 1.5.2) dans Chrome sur un MacBook Pro 2018 pour 5 de nos modèles officiellement pris en charge sur les backends WebGL, WASM et CPU:

Modèles plus petits

Modèle WebGL ÉTAIT M CPU Mémoire
BlazeFace 22,5 ms 15,6 ms 315,2 ms 0,4 Mo
FaceMesh 19,3 ms 19,2 ms 335 ms 2,8 Mo

Modèles plus grands

Modèle WebGL ÉTAIT M CPU Mémoire
PoseNet 42,5 ms 173,9 ms 1514,7 ms 4,5 Mo
BodyPix 77 ms 188,4 ms 2683 ms 4,6 Mo
MobileNet v2 37 ms 94 ms 923,6 ms 13 Mo

Le tableau ci-dessus montre que WASM est 10 à 30 fois plus rapide que le backend du processeur JS ordinaire sur tous les modèles, et compétitif avec WebGL pour les modèles plus petits comme BlazeFace , qui est léger (400 Ko), mais a un nombre décent d'opérations (~ 140). Étant donné que les programmes WebGL ont un coût supplémentaire fixe par exécution d'opération, cela explique pourquoi des modèles comme BlazeFace sont plus rapides sur WASM.

Ces résultats varient en fonction de votre appareil. La meilleure façon de déterminer si WASM convient à votre application est de le tester sur nos différents backends.

Inférence vs entraînement

Pour répondre au cas d'utilisation principal du déploiement de modèles pré-entraînés, le développement du backend WASM donnera la priorité à l' inférence par rapport au support de la formation . Consultez une liste à jour des opérations prises en charge dans WASM et indiquez-nous si votre modèle a une opération non prise en charge. Pour les modèles d'entraînement, nous vous recommandons d'utiliser le backend Node (TensorFlow C ++) ou le backend WebGL.

Processeur backend

Le backend CPU, «cpu», est le backend le moins performant, mais c'est le plus simple. Les opérations sont toutes implémentées en JavaScript vanilla, ce qui les rend moins parallélisables. Ils bloquent également le thread de l'interface utilisateur.

Ce backend peut être très utile pour les tests ou sur les appareils sur lesquels WebGL n'est pas disponible.

Drapeaux

TensorFlow.js dispose d'un ensemble d'indicateurs d'environnement qui sont automatiquement évalués et déterminent la meilleure configuration dans la plate-forme actuelle. Ces indicateurs sont pour la plupart internes, mais quelques indicateurs globaux peuvent être contrôlés avec une API publique.

  • tf.enableProdMode(): active le mode production, qui supprimera la validation du modèle, les vérifications NaN et autres vérifications d'exactitude en faveur des performances.
  • tf.enableDebugMode() : active le mode débogage, qui enregistrera dans la console chaque opération exécutée, ainsi que les informations sur les performances d'exécution telles que l'empreinte mémoire et le temps total d'exécution du noyau. Notez que cela ralentira considérablement votre application, ne l'utilisez pas en production.