Usa las TPU de Coral Edge para ejecutar modelos de TFlite en Node con TensorFlow.js

1. Introducción

54e81d02971f53e8.png

Última actualización: 11/04/2022

En este Codelab, aprenderás a entrenar un modelo de clasificación de imágenes con Teachable Machine y ejecutarlo con aceleración de hardware de Coral con TensorFlow.js, una biblioteca de aprendizaje automático potente y flexible. para JavaScript. Compilarás una app de Electron que muestra imágenes de una cámara web y las clasifica con una TPU de Edge Coral. Hay una versión completamente funcional de este Codelab disponible en el repositorio de GitHub sig-tfjs.

¿Necesito un dispositivo de coral?

No. Puedes probar este codelab sin un dispositivo Coral y aun así obtener un buen rendimiento en una computadora de escritorio usando el acelerador WebNN.

Qué compilarás

En este codelab, crearás una app Electron que clasifica imágenes. Tu app:

  • Clasifica las imágenes de la cámara web en las categorías definidas en el modelo que entrenaste.
  • Usa un acelerador de coral para aumentar el rendimiento, si hay uno disponible.
  • Usa WebNN para aumentar el rendimiento, si es compatible con tu plataforma.

Qué aprenderá

  • Cómo instalar y configurar el paquete de NPM tfjs-tflite-node para ejecutar modelos de TFLite en Node.js
  • Cómo instalar la biblioteca del entorno de ejecución de Edge TPU para ejecutar modelos en un dispositivo Coral
  • Cómo acelerar la inferencia de modelo mediante una TPU de Edge TPU.
  • Cómo acelerar la inferencia de modelo con WebNN

Este codelab se enfoca en TFLite en Node.js. Los conceptos y los bloques de código que no son relevantes no se explican, pero se proporcionan para que los copies y pegues.

Requisitos

Para completar este codelab, necesitas lo siguiente:

2. Prepárate

Obtén el código

Incluimos todo el código necesario para este proyecto en un repositorio de Git. Para comenzar, toma el código y ábrelo en tu entorno de desarrollo favorito. En este codelab, te recomendamos usar una Raspberry Pi que ejecute Raspberry Pi OS (64 bits) con computadora de escritorio. De este modo, te resultará más fácil conectar un acelerador de coral.

Recomendación: Usa Git para clonar el repositorio en una Raspberry Pi

Para obtener el código, abra una nueva ventana de la terminal y clone el repositorio:

git clone https://github.com/tensorflow/sig-tfjs.git

Todos los archivos que debes editar para el codelab se encuentran en el directorio tfjs-tflite-node-codelab (dentro de sig-tfjs). En este directorio, encontrarás subdirectorios llamados starter_code, cpu_inference_working, coral_inference_working y webnn_inference_working. Estos son puntos de control para los pasos de este codelab.

Entre los otros archivos del repositorio, se encuentran los paquetes NPM de los que depende tfjs-tflite-node-codelab. No necesitarás editar ninguno de estos archivos, pero deberás ejecutar algunas de sus pruebas para asegurarte de que el entorno esté configurado correctamente.

Instala la biblioteca de entorno de ejecución de Edge TPU

Los dispositivos de coral requieren que instales la biblioteca de tiempo de ejecución de Edge TPU antes de usarla. Instálala siguiendo las instrucciones correspondientes a tu plataforma.

En Linux o Raspberry Pi

En Linux, la biblioteca está disponible desde el PPA de Google como un paquete de Debian, libedgetpu1-std, para arquitecturas x86-64 y Armv8 (64 bits). Si el procesador usa una arquitectura diferente, deberás compilarla desde la fuente.

Ejecuta este comando para agregar el PPA de Coral de Google y, luego, instalar la biblioteca de entorno de ejecución de Edge TPU.

# None of this is needed on Coral boards
# This repo is needed for almost all packages below
echo "deb https://packages.cloud.google.com/apt coral-edgetpu-stable main" | sudo tee /etc/apt/sources.list.d/coral-edgetpu.list
# This repo is needed for only python3-coral-cloudiot and python3-coral-enviro
echo "deb https://packages.cloud.google.com/apt coral-cloud-stable main" | sudo tee /etc/apt/sources.list.d/coral-cloud.list

curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -

sudo apt-get update
sudo apt-get install libedgetpu1-std

En Windows y otros SO

Los objetos binarios compilados previamente están disponibles para las versiones x86-64 de MacOS y Windows, y se pueden instalar mediante la ejecución de install.sh o install.bat secuencia de comandos en el archivo una vez que se descargó.

Reinicia el dispositivo

Una vez que el entorno de ejecución de Edge TPU esté instalado, reinicia el dispositivo para activar la nueva regla de Coral Udev que agregó el instalador.

Verifica que se detecte el dispositivo Coral

A fin de verificar que tu dispositivo Coral se detecta y funciona, ejecuta las pruebas de integración para el paquete coral-tflite-delegate. Este paquete se encuentra en el directorio raíz del repositorio. Para ejecutar las pruebas de integración, conecta tu acelerador de Coral y ejecuta estos comandos en el directorio del paquete:

npx yarn
npx yarn build-deps
npx yarn test-integration

Deberías ver un resultado como este:

yarn run v1.22.17
$ yarn build && yarn test-integration-dev
$ tsc
$ jasmine --config=jasmine-integration.json
Platform node has already been set. Overwriting the platform with node.
Randomized with seed 78904
Started

============================
Hi there 👋. Looks like you are running TensorFlow.js in Node.js. To speed things up dramatically, install our node backend, which binds to TensorFlow C++, by running npm i @tensorflow/tfjs-node, or npm i @tensorflow/tfjs-node-gpu if you have CUDA. Then call require('@tensorflow/tfjs-node'); (-gpu suffix for CUDA) at the start of your program. Visit https://github.com/tensorflow/tfjs-node for more details.
============================
WARNING: converting 'int32' to 'uint8'
.

1 spec, 0 failures
Finished in 2.777 seconds
Randomized with seed 78904 (jasmine --random=true --seed=78904)
Done in 6.36s.

No te preocupes por instalar @tensorflow/tfjs-node, como se menciona en los registros, ya que ejecutarás el modelo en TFLite.

Si, en cambio, el resultado contiene Encountered unresolved custom op: edgetpu-custom-op, esto significa que no se detectó el dispositivo Coral. Asegúrate de haber instalado la biblioteca de entorno de ejecución de Edge TPU y de haber conectado el dispositivo Coral a tu computadora. También puedes seguir la guía de introducción de Coral para probar la versión de Python de las vinculaciones de coral. Si la versión de Python funciona, pero estas pruebas fallan, completa un informe de errores para avisarnos.

Cómo ejecutar el código de inicio

Ahora, estás listo para ejecutar el código de inicio. Sigue estos pasos para comenzar.

  1. Ve al directorio starter_code en tfjs-tflite-node-codelab.
  2. Ejecuta npm install para instalar dependencias.
  3. Ejecuta npm start para iniciar el proyecto. Debería abrirse una app que muestre un feed de video de la cámara web de tu computadora.

¿Cuál es nuestro punto de partida?

Nuestro punto de partida es una app básica de cámara Electron diseñada para este codelab. El código se simplificó para mostrar los conceptos en el codelab y tiene poco control de errores. Si decides reutilizar algún código en una app de producción, asegúrate de controlar los errores y probar todo el código por completo.

Una app básica de electrones con un feed en vivo de la cámara del dispositivo.

Explora el código de inicio

Hay muchos archivos en este código de inicio, pero el único que debes editar es renderer.js. Controla lo que se muestra en la página, incluidos el feed de video y los elementos HTML. Aquí es donde agregas tu modelo de aprendizaje automático. Entre los demás archivos, hay un archivo index.html, pero lo único que hace es cargar el archivo renderer.js. También hay un archivo main.js, que es el punto de entrada de Electron. Controla el ciclo de vida de la app, incluido lo que se muestra cuando se abre y qué hacer cuando se cierra, pero no es necesario realizar ningún cambio.

Cómo abrir el depurador

Es posible que debas depurar tu app mientras sigues este codelab. Como esta app se basa en Electron, tiene integrado el depurador de Chrome. En la mayoría de las plataformas, puedes abrirlo con Ctrl + Mayúsculas + i. Haga clic en la pestaña Console para ver los registros y mensajes de error de la aplicación.

Aquí no hay mucho más para explorar, así que comencemos a entrenar el clasificador de imágenes.

3. Entrena un clasificador de imágenes

En esta sección, entrenarás las versiones TFLite y Coral de un modelo de clasificación de imágenes personalizado.

Entrena el clasificador

Un clasificador de imágenes toma imágenes de entrada y les asigna etiquetas. En este codelab, usarás Teachable Machine para entrenar un modelo en tu navegador. Para acelerar el entrenamiento de esta sección, puedes usar una computadora de escritorio o laptop en lugar de una Raspberry Pi, pero deberás copiar los archivos resultantes en la pila.

Ahora estás listo para entrenar un modelo. Si no sabes qué tipo de modelo entrenar, un modelo fácil de entrenar es un detector de personas, que solo detecta si una persona está en el marco.

  1. Abra la página de capacitación de Teachable Machine en una pestaña nueva.
  2. Seleccione Image Project y, luego, Standard image model.
  3. Agrega muestras de imágenes para cada clase. La entrada de cámara web es la forma más sencilla de hacerlo. También puedes cambiar el nombre de las clases.
  4. Cuando hayas recopilado suficientes datos para cada clase (50 muestras suele ser suficiente), presiona Entrenar modelo.

Cuando el modelo haya terminado de entrenar, deberías obtener una vista previa de los resultados del modelo.

Un modelo se entrena con imágenes de dos clases: "Persona" y "Ninguna persona". Una demostración del modelo entrenado se ejecuta en vivo en fotogramas desde la cámara del dispositivo, y el modelo en sí se puede descargar en varios formatos.

Intenta darle entradas diferentes al modelo. Si encuentras una entrada que está clasificada de manera incorrecta, agrégala a los datos de entrenamiento y vuelve a entrenar el modelo.

  1. Cuando estés satisfecho con la exactitud del modelo, haz clic en Exportar modelo. Tendrás que descargar dos versiones diferentes del modelo.
  2. Exporta el modelo como un modelo de punto flotante de Tensorflow Lite. Esta acción descarga un archivo llamado converted_tflite.zip. que se ejecuta en la CPU.
  3. Exporta el modelo como un modelo Edge TPU de Tensorflow. Esta acción descarga un archivo llamado converted_edgetpu.zip que se ejecuta en Coral TPU.

4. Ejecuta el modelo de CPU en tu app

Ahora que entrenaste un modelo, es momento de agregarlo a tu app. Al final de esta sección, la app podrá ejecutar tu modelo con la CPU del dispositivo.

Agrega el archivo de modelo a la app

Descomprime el archivo del modelo converted_tflite.zip que descargaste cuando entrenaste el clasificador. Hay dos archivos en el archivo. model_uquant.tflite es el modelo TFLite guardado, incluidos el gráfico y los pesos del modelo. labels.txt contiene las etiquetas legibles para las clases que predice el modelo. Coloca ambos archivos en el modeldirectory.

Instala dependencias

La carga de un modelo y el procesamiento previo de las entradas requieren algunas dependencias de TensorFlow.js:

  • tfjs-tflite-node: El paquete de TensorFlow.js para ejecutar modelos de TFLite en Node.js.
  • @tensorflow/tfjs: El paquete principal de TensorFlow.js

@tensorflow/tfjs ya está instalado, pero debes instalar tfjs-tflite-node con este comando:

npm install --save tfjs-tflite-node

Una vez instalado, agréguelo a la aplicación en la parte superior de renderer.js:

Parte 1 de LABLAB: Importa tfjs‐tflite-node

const {loadTFLiteModel} = require('tfjs-tflite-node');

Carga el modelo

Ya está listo para cargar el modelo. tfjs-tflite-node proporciona la función loadTFLiteModel para hacerlo. Puede cargar modelos desde una ruta de archivo, un ArrayBuffer o una URL de TFHub. Para cargar el modelo y sus pesos, agrega lo siguiente a la función main:

Parte 1 de LABLAB: Carga el modelo aquí

const modelPath = './model/model_unquant.tflite';
const model = await loadTFLiteModel(modelPath);
const labels = fs.readFileSync('./model/labels.txt', 'utf8')
      .split('\n');

Ejecuta el modelo

Ejecutar el modelo consta de tres pasos. Primero, debes extraer y procesar previamente un fotograma de entrada desde la cámara web. Luego, ejecutarás el modelo en ese marco y recibirás una predicción. A continuación, mostrarás la predicción en la página.

Procesa previamente la entrada de la cámara web

En este momento, la cámara web es solo un elemento HTML y los fotogramas que muestra no están disponibles para el archivo renderizador.js de JavaScript. Para extraer fotogramas de la cámara web, TensorFlow.js proporciona tf.data.webcam, que brinda un método capture() fácil de usar para capturar fotogramas de la cámara.

Para usarla, agrega este código de configuración a main():

Parte 1 de LABLAB: Configure tf.data.webcam aquí

const tensorCam = await tf.data.webcam(webcam);

Luego, para capturar una imagen en cada fotograma, agrega lo siguiente a run():

Parte 1 de LABLAB: Captura marcos de cámaras web aquí.

const image = await tensorCam.capture();

También debes procesar previamente cada fotograma para que sea compatible con el modelo. El modelo que usa este codelab tiene una forma de entrada [1, 224, 224, 3], por lo que espera una imagen RGB de 224 x 224 píxeles. tensorCam.capture()proporciona una forma de [224, 224, 3], por lo que debes agregar una dimensión adicional al principio del tensor con tf.expandDims. Además, el modelo de CPU espera una entrada Float32 entre -1 y 1, pero la cámara web captura valores de 0 a 255. Puedes dividir el tensor de entrada por 127 para cambiar su rango de [0, 255] a [0, ~2] y, luego, restar 1 para obtener el rango deseado [-1, ~1]. Para ello, agrega estas líneas a tf.tidy() en la función run():

Parte 1 de LABLAB: Preprocesa los fotogramas de cámara web aquí.

const expanded = tf.expandDims(image, 0);
const divided = tf.div(expanded, tf.scalar(127));
const normalized = tf.sub(divided, tf.scalar(1));

Es importante desechar los tensores después de usarlos. tf.tidy() hace esto automáticamente para el código contenido en la devolución de llamada, pero no admite funciones asíncronas. Deberás desechar manualmente el tensor de imagen que creaste anteriormente llamando a su método dispose().

Parte 1 de LABLAB: Desecha los fotogramas de cámara web aquí.

image.dispose();

Ejecuta el modelo y muestra los resultados

Para ejecutar el modelo en la entrada procesada previamente, llama a model.predict() en el tensor normalizado. Esto muestra un tensor unidimensional que contiene la probabilidad prevista de cada etiqueta. Multiplica esta probabilidad por 100 para obtener el porcentaje de probabilidad de cada etiqueta y usa la función showPrediction incluida con el código de inicio para mostrar la predicción del modelo en la pantalla.

Este código también usa stats.js para medir el tiempo de demora con la predicción mediante llamadas a stats.begin y stats.end alrededor de model.predict.

Parte 1 de LABLAB: Ejecuta el modelo y muestra los resultados aquí.

stats.begin();
const prediction = model.predict(normalized);
stats.end();
const percentage = tf.mul(prediction, tf.scalar(100));
showPrediction(percentage.dataSync(), labels);

Vuelve a ejecutar la app con yarn start. Deberías ver clasificaciones de tu modelo.

El modelo de CPU TFLite se ejecuta en la app Electron. Clasifica imágenes de la cámara web y muestra los valores de confianza para cada clase.

Rendimiento

Cuando se configura, el modelo se ejecuta en la CPU. Esto es adecuado para computadoras de escritorio y la mayoría de las laptops, pero es posible que no desees hacerlo si lo ejecutas en una placa Raspberry Pi o en otro dispositivo de bajo consumo. En una Raspberry Pi 4, probablemente verás alrededor de 10 FPS, que podría no ser lo suficientemente rápida para algunas aplicaciones. Para obtener un mejor rendimiento sin usar una máquina más rápida, puedes usar silicio específico de la aplicación en forma de una TPU de Coral Edge.

5. Ejecuta el modelo de Coral en tu app

Si no tienes un dispositivo Coral, puedes omitir esta sección.

Este paso del codelab se basa en el código que escribiste en la sección anterior, pero puedes usar el punto de control cpu_inference_working si quieres comenzar con una lista limpia.

Los pasos para ejecutar el modelo de Coral son casi idénticos a los pasos para ejecutar el modelo de CPU. La principal diferencia es el formato del modelo. Debido a que Coral solo admite tensores uint8, el modelo es cuantizado. Esto afecta a los tensores de entrada pasados al modelo y a los tensores de salida que se muestran. Otra diferencia es que los modelos deben compilarse con el compilador de Edge TPU para ejecutarse en una TPU de Coral. TeachableMachine ya realizó este paso, pero puedes obtener más información sobre cómo hacerlo en otros modelos en la documentación de Coral.

Agrega el archivo de modelo Coral a la app

Descomprima el archivo de modelo converted_edgetpu.zip que descargó cuando entrenó el clasificador. Hay dos archivos incluidos en el archivo. model_edgetpu.tflite es el modelo TFLite guardado, incluidos el gráfico y los pesos del modelo. labels.txt contiene las etiquetas legibles para las clases que predice el modelo. Coloque el archivo de modelo en el directorio coral_model.

Instala dependencias

La ejecución de modelos de Coral requiere la biblioteca de tiempo de ejecución de Edge TPU. Asegúrate de haberlo instalado siguiendo las instrucciones de configuración antes de continuar.

Se accede a los dispositivos corales como delegados de TFLite. Para acceder a ellos desde JavaScript, instala el paquete coral-tflite-delegate:

npm install --save coral-tflite-delegate

Luego, para importar el delegado, agregue la siguiente línea en la parte superior del archivo renderer.js:

Parte 2 de LABLAB: Importa el delegado aquí

const {CoralDelegate} = require('coral-tflite-delegate');

Carga el modelo

Ahora, estás listo para cargar el modelo Coral. Puedes hacerlo del mismo modo que con el modelo de la CPU, excepto que ahora pasas las opciones a la función loadTFLiteModel para cargar el delegado de Coral.

Parte 2 de CODELAB: Carga el modelo delegado aquí.

const coralModelPath = './coral_model/model_edgetpu.tflite';
const options = {delegates: [new CoralDelegate()]};
const coralModel = await loadTFLiteModel(coralModelPath, options);

No es necesario cargar las etiquetas porque son las mismas que para el modelo de CPU.

Agrega un botón para alternar entre la CPU y el coral

Agregues el modelo de Coral junto con el modelo de CPU que agregaste en la última sección. Ejecutarlos a la vez dificulta la visualización de las diferencias de rendimiento, por lo que un botón de activación alterna entre la ejecución de Coral y la CPU.

Agrega el botón con este código:

Parte 2 de LABLAB: Crea el botón de delegado aquí.

let useCoralDelegate = false;
const toggleCoralButton = document.createElement('button');
function toggleCoral() {
  useCoralDelegate = !useCoralDelegate;
  toggleCoralButton.innerText = useCoralDelegate
      ? 'Using Coral. Press to switch to CPU.'
      : 'Using CPU. Press to switch to Coral.';
}
toggleCoralButton.addEventListener('click', toggleCoral);
toggleCoral();
document.body.appendChild(toggleCoralButton);

Fijemos esta condición en la función run(). Cuando useCoralDelegate es falso, debe ejecutar la versión de la CPU. De lo contrario, ejecuta la versión de Coral (por ahora, no hará nada). Une el código de la ejecución del modelo de CPU en una sentencia if. Ten en cuenta que el tensor expanded no se incluye en la sentencia if, ya que el modelo de Coral lo usa.

Parte 2 de LABLAB: Verifica si deseas usar el delegado aquí.

// NOTE: Don't just copy-paste this code into the app.
// You'll need to edit the code from the CPU section.
const expanded = tf.expandDims(image, 0);
if (useCoralDelegate) {
  // CODELAB part 2: Run Coral prediction here.
} else {
  const divided = tf.div(expanded, tf.scalar(127));
  const normalized = tf.sub(divided, tf.scalar(1));
  stats.begin();
  const prediction = model.predict(normalized);
  stats.end();
  const percentage = tf.mul(prediction, tf.scalar(100));
  showPrediction(percentage.dataSync(), labels);
}

Ejecuta el modelo

La versión Coral del modelo espera tensores uint8 de 0 a 255, por lo que no es necesario normalizar su entrada. Sin embargo, la salida también es un tensor uint8 en el rango de 0 a 255. Debe convertirse a un número de punto flotante de 0 a 100 antes de mostrarse.

Parte 2 de CODELAB: Ejecuta la predicción de Coral aquí. (Esto es parte del fragmento de código anterior).

stats.begin();
const prediction = coralModel.predict(expanded);
stats.end();
const percentage = tf.div(tf.mul(prediction, tf.scalar(100)), tf.scalar(255));
showPrediction(percentage.dataSync(), labels);

Vuelve a ejecutar la app con yarn start, que debería mostrar clasificaciones del acelerador de coral.

Los modelos de CPU y Coral se ejecutan en la app de a uno, y un botón cambia entre ellos. El modelo de CPU obtiene alrededor de 20 FPS y el modelo de Coral obtiene alrededor de 45.

Puedes alternar entre la inferencia de coral y la de CPU si presionas el botón. Tal vez notes que las clasificaciones de confianza del modelo Coral son menos precisas que las del modelo de CPU y, por lo general, terminan con un decimal. Esta pérdida de precisión es una compensación de la ejecución de un modelo cuantificado en Coral. No suele tener importancia en la práctica, pero es algo para tener en cuenta.

Nota sobre el rendimiento

La velocidad de fotogramas que ves incluye procesamiento previo y posterior, por lo que no representa lo que el hardware de coral puede hacer. Para obtener una mejor idea del rendimiento, haz clic en el medidor de FPS hasta que se muestre la latencia (en milisegundos), que mide solo la llamada a model.predict. Sin embargo, eso incluye el tiempo que lleva mover tensores a las vinculaciones C nativas de TFLite y, luego, al dispositivo Coral, por lo que no es una medición perfecta. Para obtener comparativas de rendimiento más precisas escritas en C++, consulta la página de comparativas de EdgeTPU.

Además, debes tener en cuenta que el video se grabó en una laptop en lugar de una Raspberry Pi, por lo que es posible que veas un FPS diferente.

Aceleración del procesamiento previo de Coral

En algunos casos, puedes acelerar el procesamiento previo si cambias los backends de TFJS. El backend predeterminado es WebGL, que es bueno para operaciones grandes que se pueden paralelizar, pero esta app no hace mucho en la etapa de procesamiento previo (la única operación que usa es expandDims, que no es paralela). Puedes cambiar al backend de la CPU para evitar la latencia adicional de mover los tensores hacia y desde la GPU. Para ello, agrega esta línea después de las importaciones en la parte superior del archivo.

tf.setBackend(‘cpu');

Esto también afecta el procesamiento previo del modelo de CPU TFLite, que es paralelo, por lo que ese modelo se ejecuta mucho más lento con este cambio.

6. Acelera el modelo de CPU con WebNN

Si no tienes un acelerador de coral o solo quieres probar otra forma de acelerar el modelo, usa el delegado de WebNN TFLite. Este delegado usa hardware de aprendizaje automático integrado en procesadores Intel para acelerar la inferencia de modelos con el kit de herramientas OpenVINO. Por lo tanto, tiene requisitos adicionales que no se trataron en la sección de configuración de este codelab y deberás instalar el kit de herramientas de OpenVINO. Asegúrate de verificar tu configuración con las Plataformas de sistema de destino compatibles antes de continuar, pero ten en cuenta que el delegado de WebNN aún no es compatible con macOS.

Instala el kit de herramientas de OpenVINO

El kit de herramientas OpenVINO usa hardware de aprendizaje automático integrado en procesadores Intel para acelerar los modelos. Puedes descargar una versión compilada previamente desde Intel o compilarla desde la fuente. Existen varias formas de instalar OpenVINO, pero a los fines de este Codelab, te recomendamos que uses la secuencia de comandos del instalador para Windows o Linux. Asegúrate de instalar la versión 2021.4.2 del entorno de ejecución de LTS, ya que es posible que otras versiones no sean compatibles. Después de ejecutar el instalador, asegúrese de configurar las variables de entorno de su shell como se describe en las instrucciones de instalación para Linux o Windows ( solución permanente). ), o mediante la ejecución del comando setupvars.sh (Linux) o setupvars.bat (Windows) ubicado en el directorio webnn-tflite-delegate.

Verifique que el delegado de WebNN funcione

Para verificar que el delegado de WebNN funcione correctamente, ejecuta las pruebas de integración para el paquete webnn-tflite-delegate que se encuentra en el directorio raíz del repositorio. Para ejecutar las pruebas de integración, ejecuta estos comandos en el directorio del paquete:

# In webnn-tflite-delegate/
npx yarn
npx yarn test-integration

Deberías ver un resultado como este:

WebNN delegate: WebNN device set to 0.
INFO: Created TensorFlow Lite WebNN delegate for device Default and power Default.

============================
Hi there 👋. Looks like you are running TensorFlow.js in Node.js. To speed things up dramatically, install our node backend, which binds to TensorFlow C++, by running npm i @tensorflow/tfjs-node, or npm i @tensorflow/tfjs-node-gpu if you have CUDA. Then call require('@tensorflow/tfjs-node'); (-gpu suffix for CUDA) at the start of your program. Visit https://github.com/tensorflow/tfjs-node for more details.
============================
label: wine bottle
score:  0.934505045413971
.

1 spec, 0 failures
Finished in 0.446 seconds
Randomized with seed 58441 (jasmine --random=true --seed=58441)
Done in 8.07s.

Si ves un resultado como este, indica un error de configuración:

Platform node has already been set. Overwriting the platform with node.
Randomized with seed 05938
Started
error Command failed with exit code 3221225477.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

Probablemente, este resultado significa que no configuró las variables de entorno de OpenVINO. Por ahora, puedes configurarlas mediante la ejecución del comando setupvars.sh (Linux) o setupvars.bat (Windows), pero se recomienda configurarlo de forma permanente mediante Linux o Instrucciones de Windows ( solución permanente). Si usas Windows, la

setupvars.bat

Command no es compatible con Git de Bash. Por lo tanto, asegúrate de ejecutarlo y otros comandos de este codelab desde el símbolo del sistema de Windows.

Instale el delegado de WebNN

Con OpenVINO instalado, ya estás listo para acelerar el modelo de CPU con WebNN. Esta sección del codelab se basa en el código que escribiste en la sección "Cómo ejecutar el modelo de CPU en tu app". Puedes usar el código que escribiste en este paso, pero si ya completaste la sección Coral, usa el punto de control cpu_inference_working para comenzar de cero.

La parte de Node.js del delegado de WebNN se distribuye en npmjs. Para instalarlo, ejecute este comando:

npm install --save webnn-tflite-delegate

Luego, para importar el delegado, agregue la siguiente línea en la parte superior del archivo renderer.js:

Parte 2 de LABLAB: Importa el delegado aquí

const {WebNNDelegate, WebNNDevice} = require('webnn-tflite-delegate');

El delegado de WebNN admite la ejecución en la CPU o la GPU. WebNNDevice te permite elegir cuál usar.

Carga el modelo

Ya está listo para cargar el modelo con el delegado WebNN habilitado. Para Coral, tenías que cargar un archivo de modelo diferente, pero WebNN admite el mismo formato de modelo que TFLite. Agregue WebNNDelegate a la lista de delegados que se pasan al modelo para habilitarlo:

Parte 2 de CODELAB: Carga el modelo delegado aquí.

let webnnModel = await loadTFLiteModel(modelPath, {
  delegates: [new WebNNDelegate({webnnDevice: WebNNDevice.DEFAULT})],
});

No es necesario que vuelva a cargar las etiquetas porque es el mismo modelo.

Agrega un botón para alternar entre la CPU TfLite y WebNN

Ahora que la versión WebNN del modelo está lista, agrega un botón para alternar entre la inferencia de CPU WebNN y TfLite. Ejecutarlos a la vez dificulta la visualización de las diferencias de rendimiento.

Agrega el botón con este código (ten en cuenta que aún no cambiará de modelo):

Parte 2 de LABLAB: Crea el botón de delegado aquí.

let useWebNNDelegate = false;
const divElem = document.createElement('div');
const toggleWebNNButton = document.createElement('button');
function toggleWebNN() {
  useWebNNDelegate = !useWebNNDelegate;
  toggleWebNNButton.innerHTML = useWebNNDelegate
      ? 'Using WebNN. Press to switch to TFLite CPU.'
      : 'Using TFLite CPU. Press to switch to WebNN.';
  divElem.hidden = useWebNNDelegate ? false : true;
}

toggleWebNNButton.addEventListener('click', toggleWebNN);
toggleWebNN();
document.body.appendChild(toggleWebNNButton);
document.body.appendChild(divElem);

En este código, también se agrega un elemento div que puedes usar para establecer la configuración de WebNN en la siguiente sección.

Agregue un menú desplegable para cambiar entre dispositivos WebNN

WebNN admite la ejecución en CPU y GPU, así que agrega un menú desplegable para alternar entre ellos. Agrega este código después del código que crea el botón:

// Create elements for WebNN device selection
divElem.innerHTML = '<br/>WebNN Device: ';
const selectElem = document.createElement('select');
divElem.appendChild(selectElem);

const webnnDevices = ['Default', 'GPU', 'CPU'];
// append the options
for (let i = 0; i < webnnDevices.length; i++) {
  var optionElem = document.createElement('option');
  optionElem.value = i;
  optionElem.text = webnnDevices[i];
  selectElem.appendChild(optionElem);
}

Ahora, si ejecutas la app, verás un menú desplegable predeterminado con GPU y CPU. La elección de una de estas opciones no hará nada ahora, ya que aún no se conectó el menú desplegable. La app muestra un menú desplegable en el que se puede seleccionar el dispositivo WebNN de forma predeterminada, GPU o CPU.

Cómo hacer que el menú desplegable cambie el dispositivo

Para conectar el menú desplegable a fin de cambiar el dispositivo WebNN que se usa, agrega un objeto de escucha al evento change del elemento del selector desplegable. Cuando cambie el valor seleccionado, vuelva a crear el modelo WebNN con el dispositivo WebNN correspondiente seleccionado en las opciones de delegado.

Agrega el siguiente código después del que se agregó el menú desplegable:

selectElem.addEventListener('change', async () => {
  let webnnDevice;
  switch(selectElem.value) {
    case '1':
      webnnDevice = WebNNDevice.GPU;
      break;
    case '2':
      webnnDevice = WebNNDevice.CPU;
      break;
    default:
      webnnDevice = WebNNDevice.DEFAULT;
      break;
  }
  webnnModel = await loadTFLiteModel(modelPath, {
    delegates: [new WebNNDelegate({webnnDevice})],
  });
});

Con este cambio, el menú desplegable crea un modelo nuevo con la configuración correcta cada vez que se modifica. Ahora, debes conectar el modelo WebNN y usarlo para inferencia.

Ejecute el modelo de WebNN

El modelo WebNN está listo para utilizarse, pero el botón para cambiar entre la CPU WebNN y TfLite aún no cambia el modelo. Para cambiar el modelo, primero debes cambiar el nombre de la variable model desde el momento en que cargaste el modelo de CPU TfLite en la primera sección del codelab.

Cambia la siguiente línea...

const model = await loadTFLiteModel(modelPath);

...de modo que coincida con esta línea.

const cpuModel = await loadTFLiteModel(modelPath);

Con la variable model renombrada como cpuModel, agrega lo siguiente a la función run para elegir el modelo correcto según el estado del botón:

Parte 2 de LABLAB: Verifica si deseas usar el delegado aquí.

let model;
if (useWebNNDelegate) {
  model = webnnModel;
} else {
  model = cpuModel;
}

Ahora, cuando ejecutas la app, el botón cambia entre la CPU TfLite y WebNN. El modelo de CPU de TFLite y los modelos de CPU y GPU de WebNN se ejecutan en la app. Cuando uno de los modelos WebNN está activo, un menú desplegable cambia entre ellos. El modelo de CPU obtiene aproximadamente 15 FPS y el modelo de CPU WebNN obtiene alrededor de 40.

También puedes alternar entre la CPU WebNN y la inferencia de GPU si tienes una GPU Intel integrada.

Nota sobre el rendimiento

La velocidad de fotogramas que ves incluye el procesamiento previo y posterior, por lo que no representa lo que puede hacer WebNN. Para obtener una mejor idea del rendimiento, haz clic en el medidor de FPS hasta que se muestre la latencia (en milisegundos), que mide solo la llamada a model.predict. Sin embargo, eso aún incluye el tiempo que lleva mover los tensores a las vinculaciones de C nativas de TFLite, por lo que no es una medición perfecta.

7. Felicitaciones

¡Felicitaciones! Acabas de completar tu primer proyecto de Coral / WebNN con tfjs-tflite-node en Electron.

Pruébalo y pruébalo en varias imágenes. También puede entrenar un modelo nuevo en TeachableMachine para clasificar algo completamente diferente.

Resumen

En este codelab, aprendiste lo siguiente:

  • Cómo instalar y configurar el paquete de npm tfjs-tflite-node para ejecutar modelos de TFLite en Node.js
  • Cómo instalar la biblioteca del entorno de ejecución de Edge TPU para ejecutar modelos en un dispositivo Coral
  • Cómo acelerar la inferencia de modelo mediante una TPU de Edge TPU.
  • Cómo acelerar la inferencia de modelo con WebNN.

¿Qué sigue?

Ahora que tienes una base de trabajo desde la cual comenzar, ¿qué ideas creativas se te ocurren para extender este ejecutor de modelos de aprendizaje automático a un caso de uso real en el que podrías estar trabajando? Quizás podría revolucionar la industria en la que trabaja con inferencia rápida y asequible, o bien podría modificar una tostadora para que se deje de abrigar cuando el pan se vea bien. Las posibilidades son infinitas.

Si quieres obtener más información sobre cómo TeachableMachine entrenó el modelo que usaste, consulta nuestro codelab sobre aprendizaje por transferencia. Si buscas otros modelos que funcionen con Coral, como el reconocimiento de voz y la estimación de poses, consulta coral.ai/models. También puedes encontrar versiones de CPU de esos modelos y muchos otros en TensorFlow Hub.

Comparte tus creaciones con nosotros

También puedes ampliar fácilmente lo que creaste hoy para otros casos de uso creativo. Te recomendamos pensar de manera creativa y seguir hackeando.

Recuerda etiquetarnos en redes sociales con el hashtag #MadeWithTFJS para tener la oportunidad de que se incluya tu proyecto en el blog de TensorFlow o, incluso, en eventos futuros. Nos encantaría ver tus creaciones.

Sitios web que puedes revisar