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 a ejecutarlo con la aceleración de hardware de Coral usando 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 perimetral Coral. En el repositorio de GitHub de sig-tfjs, se encuentra disponible una versión completamente funcional de este codelab.

¿Necesito un dispositivo 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 de WebNN.

Qué compilarás

En este codelab, compilarás una app de 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 Coral para aumentar el rendimiento, si hay uno disponible.
  • Usa WebNN para aumentar el rendimiento si tu plataforma lo admite.

Qué aprenderás

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

Este codelab se enfoca en TFLite en Node.js. Los conceptos y los bloques de código no relevantes se pasan por alto y se proporcionan para que simplemente los copies y pegues.

Requisitos

Para completar este codelab, necesitas lo siguiente:

  • Una computadora con cámara web
  • En el caso de Coral, recomendamos una Raspberry Pi que ejecute Raspberry Pi OS (64 bits) con escritorio.
  • Para WebNN, recomendamos una máquina Intel x86-64 que ejecute Ubuntu 20.04 o Windows 10.
  • La versión de Node.js debe ser igual o superior a 12.
  • Conocimientos de JavaScript
  • (Recomendado) Un acelerador USB Coral para acelerar el modelo

2. Prepárate

Obtén el código

Todo el código que necesitas para este proyecto se encuentra en un repositorio de Git. Para comenzar, obtén el código y ábrelo en tu entorno de desarrollo favorito. Para este codelab, te recomendamos que uses una Raspberry Pi que ejecute Raspberry Pi OS (64 bits) con escritorio. Esto facilita la conexión de un acelerador Coral.

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

Para obtener el código, abre una nueva ventana de terminal y clona el repo:

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

Todos los archivos que necesitas 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 demás archivos del repositorio, se encuentran los paquetes de NPM de los que depende tfjs-tflite-node-codelab. No tendrás que editar ninguno de estos archivos, pero deberás ejecutar algunas de sus pruebas para asegurarte de que tu entorno esté configurado correctamente.

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

Los dispositivos Coral requieren que instales la biblioteca de tiempo de ejecución de Edge TPU antes de usarlos. Para instalarlo, sigue las instrucciones correspondientes a tu plataforma.

En Linux o Raspberry Pi

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

Ejecuta este comando para agregar el PPA de Coral de Google y, luego, instalar la biblioteca del tiempo 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 archivos binarios precompilados están disponibles para las versiones x86-64 de macOS y Windows, y se pueden instalar ejecutando la secuencia de comandos install.sh o install.bat en el archivo una vez que se descarga.

Reinicia el dispositivo

Una vez que se instale el tiempo de ejecución de la TPU perimetral, reinicia el dispositivo para activar la nueva regla de Udev de Coral que agregó el instalador.

Verifica que se detecte tu dispositivo Coral

Para verificar que tu dispositivo Coral se detecte y funcione, 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 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, significa que no se detectó tu dispositivo Coral. Asegúrate de haber instalado la biblioteca del entorno de ejecución de la TPU perimetral 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 siguen fallando, envía un informe de errores para informarnos al respecto.

Ejecuta el código de partida

Ahora ya puedes ejecutar el código inicial. Sigue estos pasos para comenzar.

  1. Ve al directorio starter_code en el directorio tfjs-tflite-node-codelab.
  2. Ejecuta npm install para instalar las dependencias.
  3. Ejecuta npm start para iniciar el proyecto. Se abrirá una app que muestra el 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 de cámara básica de 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 parte del código en una app de producción, asegúrate de controlar los errores y probar todo el código.

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

Explora el código de partida

Hay muchos archivos en este código de inicio, pero el único que debes editar es renderer.js. Controla lo que aparece en la página, incluidos el feed de video y los elementos HTML, y es donde agregas tu modelo de aprendizaje automático a la app. Entre los otros archivos, se encuentra 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 para Electron. Controla el ciclo de vida de la app, incluido lo que se muestra cuando se abre y lo que se hace cuando se cierra, pero no necesitarás realizar ningún cambio en él.

Abre el depurador

Es posible que debas depurar tu app a medida que sigas este codelab. Como esta app se basa en Electron, tiene el depurador de Chrome integrado. En la mayoría de las plataformas, puedes abrirlo con Ctrl + Mayúsculas + I. Haz clic en la pestaña Consola para ver los registros y los mensajes de error de la app.

No hay mucho más que explorar aquí, 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 de TFLite y Coral de un modelo personalizado de clasificación de imágenes.

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 Pi.

Ahora ya puedes entrenar un modelo. Si no sabes qué tipo de modelo entrenar, un modelo sencillo es el detector de personas, que solo detecta si hay una persona en el encuadre.

  1. Abre la página de entrenamiento de Teachable Machine en una pestaña nueva.
  2. Selecciona Image Project y, luego, Standard image model.
  3. Agrega muestras de imágenes para cada clase. Usar la entrada de la 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 (por lo general, 50 muestras son suficientes), presiona Train Model.

Cuando el modelo termine de entrenarse, deberías ver una vista previa de su resultado.

Se entrena un modelo con imágenes de dos clases.

Intenta darle diferentes entradas al modelo. Si encuentras una entrada que se clasificó de forma incorrecta, agrégala a los datos de entrenamiento y vuelve a entrenar el modelo.

  1. Cuando estés conforme con la precisión del modelo, haz clic en Export Model. Deberás descargar dos versiones separadas del modelo.
  2. Exporta tu 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 tu modelo como un modelo de TensorFlow Lite Edge TPU. Esta acción descarga un archivo llamado converted_edgetpu.zip que se ejecuta en la Coral Edge TPU.

4. Ejecuta el modelo de CPU en tu app

Ahora que entrenaste un modelo, es hora 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 del 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 de TFLite guardado, incluidos el grafo y los pesos del modelo. labels.txt contiene las etiquetas legibles por humanos para las clases que predice el modelo. Coloca ambos archivos en modeldirectory.

Instale dependencias

Cargar un modelo y preprocesar las entradas requiere algunas dependencias de TensorFlow.js:

  • tfjs-tflite-node: Es el paquete de TensorFlow.js para ejecutar modelos de TFLite en Node.js.
  • @tensorflow/tfjs: Es 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 que se instale, agrégalo a la app en la parte superior de renderer.js:

CODELAB, parte 1: Importa tfjs-tflite-node.

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

Carga el modelo

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

CODELAB, parte 1: 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

La ejecución de tu modelo consta de tres pasos. Primero, extrae y preprocesa un fotograma de entrada de la cámara web. Luego, ejecutas el modelo en ese fotograma y obtienes una predicción. Después, muestra la predicción en la página.

Preprocesa la entrada de la cámara web

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

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

CODELAB, parte 1: Configura tf.data.webcam aquí.

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

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

CODELAB, parte 1: Captura fotogramas de la cámara web aquí.

const image = await tensorCam.capture();

También debes preprocesar 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 por 224 píxeles. tensorCam.capture()proporciona una forma de [224, 224, 3], por lo que debes agregar una dimensión adicional al frente 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, restarle 1 para obtener el rango deseado [-1, ~1]. Agrega estas líneas a tf.tidy() en la función run() para hacerlo:

CODELAB, parte 1: Preprocesa los fotogramas de la 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() lo hace automáticamente para el código que contiene su 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().

CODELAB, parte 1: Desecha los fotogramas de la cámara web aquí.

image.dispose();

Ejecuta el modelo y muestra los resultados

Para ejecutar el modelo en la entrada preprocesada, llama a model.predict() en el tensor normalizado. Devuelve 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 en el código de inicio para mostrar la predicción del modelo en la pantalla.

Este código también usa stats.js para cronometrar cuánto tarda la predicción colocando llamadas a stats.begin y stats.end alrededor de model.predict.

CODELAB, parte 1: 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 y deberías ver las clasificaciones de tu modelo.

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

Rendimiento

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

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 última sección, pero puedes usar el punto de control cpu_inference_working si quieres comenzar desde cero.

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. Dado que Coral solo admite tensores uint8, el modelo se cuantifica. Esto afecta los tensores de entrada que se pasan al modelo y los tensores de salida que este devuelve. Otra diferencia es que los modelos deben compilarse con el compilador de Edge TPU para ejecutarse en una TPU de Coral. Teachable Machine ya realizó este paso, pero puedes aprender a hacerlo para otros modelos en la documentación de Coral.

Agrega el archivo del modelo de Coral a la app

Descomprime el archivo del modelo converted_edgetpu.zip que descargaste cuando entrenaste el clasificador. El archivo incluye dos archivos. model_edgetpu.tflite es el modelo de TFLite guardado, incluidos el grafo y los pesos del modelo. labels.txt contiene las etiquetas legibles por humanos para las clases que predice el modelo. Coloca el archivo del modelo en el directorio coral_model.

Instale dependencias

Para ejecutar modelos de Coral, se requiere la biblioteca de tiempo de ejecución de Edge TPU. Antes de continuar, asegúrate de haberlo instalado siguiendo las instrucciones de configuración.

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

npm install --save coral-tflite-delegate

Luego, importa el delegado agregando esta línea en la parte superior del archivo renderer.js:

CODELAB part 2: Import the delegate here.

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

Carga el modelo

Ahora ya puedes cargar el modelo de Coral. Esto se hace de la misma manera que para el modelo de CPU, excepto que ahora pasas opciones a la función loadTFLiteModel para cargar el delegado de Coral.

CODELAB, parte 2: 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 que cargues las etiquetas, ya que son las mismas que las del modelo de CPU.

Agrega un botón para cambiar entre la CPU y Coral

Agregarás el modelo de Coral junto con el modelo de CPU que agregaste en la sección anterior. Ejecutarlos al mismo tiempo dificulta ver las diferencias de rendimiento, por lo que un botón de activación alterna entre la ejecución de Coral y la de la CPU.

Agrega el botón con este código:

CODELAB parte 2: 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);

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

CODELAB, parte 2: Comprueba si se debe 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 de Coral del modelo espera tensores uint8 de 0 a 255, por lo que su entrada no necesita normalizarse. Sin embargo, el resultado también es un tensor uint8 en el rango de 0 a 255. Debe convertirse en un número de punto flotante del 0 al 100 antes de mostrarse.

CODELAB, parte 2: Ejecuta la predicción de Coral aquí. (Esto forma 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. Debería mostrar las clasificaciones del acelerador Coral.

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

Para alternar entre la inferencia de Coral y la de CPU, presiona el botón. Es posible que notes que las clasificaciones de confianza del modelo de Coral son menos precisas que las del modelo de CPU y que suelen terminar con un decimal par. Esta pérdida de precisión es una compensación por ejecutar un modelo cuantificado en Coral. Por lo general, no importa en la práctica, pero es algo que debes tener en cuenta.

Nota sobre el rendimiento

La velocidad de fotogramas que ves incluye el preprocesamiento y el posprocesamiento, por lo que no representa lo que el hardware de Coral es capaz de hacer. Para obtener una mejor idea del rendimiento, haz clic en el medidor de FPS hasta que 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 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 Edge TPU.

También es importante tener en cuenta que el video se grabó en una laptop en lugar de una Raspberry Pi, por lo que es posible que veas una cantidad de FPS diferente.

Cómo acelerar el preprocesamiento de Coral

En algunos casos, puedes acelerar el preprocesamiento cambiando los backends de TFJS. El backend predeterminado es WebGL, que es adecuado para operaciones grandes y paralelizadas, pero esta app no realiza muchas de esas operaciones en la fase de procesamiento previo (la única operación que usa es expandDims, que no es paralela). Puedes cambiar al backend de CPU para evitar la latencia adicional de mover 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 de TFLite, que está paralelizado, por lo que el modelo se ejecuta mucho más lento con este cambio.

6. Acelera el modelo de CPU con WebNN

Si no tienes un acelerador Coral o si solo quieres probar otra forma de acelerar el modelo, puedes usar el delegado de WebNN TFLite. Este delegado usa el hardware de aprendizaje automático integrado en los procesadores Intel para acelerar la inferencia del modelo con el kit de herramientas OpenVINO. Por lo tanto, tiene requisitos adicionales que no se abordaron en la sección de configuración de este codelab, y deberás instalar el kit de herramientas de OpenVINO. Antes de continuar, asegúrate de verificar tu configuración con las plataformas de sistemas de destino compatibles, pero ten en cuenta que el delegado de WebNN aún no admite macOS.

Instala el kit de herramientas de OpenVINO

El kit de herramientas de OpenVINO usa el hardware de aprendizaje automático integrado en los procesadores Intel para acelerar los modelos. Puedes descargar una versión precompilada de Intel o compilarla desde la fuente. Existen varias formas de instalar OpenVINO, pero, para 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 del entorno de ejecución 2021.4.2 LTS, ya que es posible que otras versiones no sean compatibles. Después de ejecutar el instalador, asegúrate de configurar las variables de entorno de tu shell como se describe en las instrucciones de instalación para Linux o Windows ( solución permanente), o bien ejecutando el comando setupvars.sh (Linux) o setupvars.bat (Windows) ubicado en el directorio webnn-tflite-delegate.

Verifica que el delegado de WebNN funcione

Para verificar que el delegado de WebNN funcione correctamente, ejecuta las pruebas de integración del 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, significa que hay 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.

Es muy probable que este resultado signifique que no configuraste las variables de entorno de OpenVINO. Por el momento, puedes configurarlos ejecutando el comando setupvars.sh (Linux) o setupvars.bat (Windows), pero es posible que desees configurarlos de forma permanente siguiendo las instrucciones de Linux o Windows ( solución permanente). Si usas Windows, el

setupvars.bat

El comando no admite Git Bash, así que asegúrate de ejecutarlo y otros comandos de este codelab desde el símbolo del sistema de Windows.

Instala el delegado de WebNN

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

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

npm install --save webnn-tflite-delegate

Luego, importa el delegado agregando esta línea en la parte superior del archivo renderer.js:

CODELAB part 2: Import the delegate here.

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

Ahora puedes cargar el modelo con el delegado de WebNN habilitado. En el caso de Coral, debías cargar un archivo de modelo diferente, pero WebNN admite el mismo formato de modelo que TFLite. Agrega WebNNDelegate a la lista de delegados que se pasan al modelo para habilitarlo:

CODELAB, parte 2: Carga el modelo delegado aquí.

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

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

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

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

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

CODELAB parte 2: 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);

Este código también agrega un elemento div que usarás para configurar los parámetros de WebNN en la siguiente sección.

Agrega un menú desplegable para cambiar entre dispositivos WebNN

WebNN admite la ejecución en CPU y GPU, por lo que debes agregar un menú desplegable para cambiar entre ellas. 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 con las opciones Default, GPU y CPU. Elegir una de ellas no hará nada por el momento, ya que el menú desplegable aún no se conectó. La app muestra un menú desplegable en el que se puede seleccionar el dispositivo WebNN entre Predeterminado, GPU o CPU.

Haz que el menú desplegable cambie el dispositivo

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

Agrega el siguiente código después del código que 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 cambia. Ahora es el momento de conectar el modelo de WebNN y usarlo para la inferencia.

Ejecuta el modelo de WebNN

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

Cambia la siguiente línea…

const model = await loadTFLiteModel(modelPath);

…para que coincida con esta línea.

const cpuModel = await loadTFLiteModel(modelPath);

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

CODELAB, parte 2: Comprueba si se debe usar el delegado aquí.

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

Ahora, cuando ejecutes la app, el botón cambiará entre la CPU de 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 de WebNN está activo, un menú desplegable permite cambiar entre ellos. El modelo de CPU obtiene aproximadamente 15 FPS, y el modelo de CPU de WebNN obtiene aproximadamente 40.

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

Nota sobre el rendimiento

La velocidad de fotogramas que ves incluye el preprocesamiento y el posprocesamiento, por lo que no representa lo que WebNN es capaz de hacer. Para obtener una mejor idea del rendimiento, haz clic en el medidor de FPS hasta que 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 nativas de C 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 experimenta con una variedad de imágenes. También puedes entrenar un modelo nuevo en Teachable Machine para clasificar algo completamente diferente.

Resumen

En este codelab, aprendiste lo siguiente:

  • Cómo instalar y configurar el paquete npm tfjs-tflite-node para ejecutar modelos de TFLite en Node.js
  • Cómo instalar la biblioteca de tiempo de ejecución de Edge TPU para ejecutar modelos en un dispositivo Coral
  • Cómo acelerar la inferencia del modelo con una TPU perimetral de Coral
  • Cómo acelerar la inferencia de modelos 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 del mundo real en el que podrías estar trabajando? Quizás podrías revolucionar la industria en la que trabajas con inferencias rápidas y asequibles, o tal vez podrías modificar una tostadora para que deje de tostar cuando el pan se vea perfecto. Las posibilidades son infinitas.

Para ir más allá y obtener más información sobre cómo Teachable Machine 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 la pose, consulta coral.ai/models. También puedes encontrar versiones para CPU de esos modelos y muchos otros en TensorFlow Hub.

Comparte tus creaciones con nosotros

También puedes extender fácilmente lo que creaste hoy para otros casos de uso creativos, y te recomendamos que pienses de manera innovadora y sigas hackeando.

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

Sitios web que puedes revisar