Apps inteligentes

Domina la inteligencia integrada en el dispositivo con el ML Kit y LiteRT en los Servicios de Google Play

Bocinas

  • Chintan Parikh

    Gerente de producto principal

  • Fergus Henderson

    Ingeniero de software del personal

Acerca de

Acerca de la charla

Deja de elegir entre la comodidad de la IA lista para usar y la flexibilidad de los modelos personalizados: puedes implementar ambas opciones en una sola app ultraliviana sin agregar megabytes de código binario innecesario.

En esta sesión, demostraremos cómo compilar esta arquitectura de pila doble exacta en una sola app para Android. Verás cómo aprovechar el ML Kit para tareas de AA clásicas listas para usar (como el escaneo de documentos) junto con LiteRT independiente en los Servicios de Play para tus cargas de trabajo personalizadas de visión artificial o audio. Analizaremos en profundidad cómo ambas rutas de implementación se unen de forma interna para utilizar el entorno de ejecución moderno de LiteRT, lo que le brinda a tu app un rendimiento fluido y acelerado por hardware en CPU y GPU con un espacio de descarga de prácticamente cero bytes.

Conclusiones clave para los desarrolladores:

-Rendimiento sin concesiones: Tanto los modelos listos para usar como los personalizados se aceleran automáticamente por hardware con la API de CompiledModel unificada.

-Micro-APKs: Reduce drásticamente el tamaño de descarga de tu app descargando los entornos de ejecución de ML Kit y LiteRT en los Servicios de Play.

-Integración híbrida: Domina la ejecución de múltiples flujos de trabajo de AA en paralelo en producción sin conflictos de recursos.

Resumen

  • LiteRT en los Servicios de Google Play comparte un entorno de ejecución mantenido entre las apps para reducir el tamaño de los APK en aproximadamente 8 MB.
  • Las funciones listas para usar de ML Kit y los modelos personalizados de LiteRT se pueden ejecutar juntos en una sola aplicación en el mismo entorno de ejecución.
  • La API de CompiledModel simplifica la aceleración de GPU y ofrece un rendimiento hasta 1.4 veces más rápido que la inferencia de GPU de TFLite heredada.
  • La disponibilidad de la plataforma se extiende más allá de los teléfonos, a Wear OS 4 o versiones posteriores, y al SO Android Automotive en Android 11 o versiones posteriores.
  • Para adoptar LiteRT en los Servicios de Google Play, se deben actualizar las dependencias de Maven a play-services-litert, llamar a LiteRt.initialize para obtener un entorno y pasarlo a CompiledModel.create.
  • Se recomienda migrar a la API de CompiledModel 2.x porque la versión 1.x está en modo de mantenimiento y la NNAPI dejará de estar disponible.

Habilidades

Recursos

Gemini Notebook

Temas

  • on-device-ai
  • ml-kit
  • litert
  • google-play-services
  • gpu-acceleration
  • aprendizaje automático

Transcripción

Descargar transcripción

Introducción y descripción general de LiteRT

  • Buenas tardes a todos.

  • Estamos por comenzar la charla.

  • Por lo tanto, cuando las personas dicen "IA integrada en el dispositivo" hoy en día, suelen referirse a los LLM.

  • Y hoy, más temprano, vieron varias charlas sobre Gemini Nano que se trataron con ML Kit, Firebase y muchos otros productos de Google.

  • Esta sesión trata sobre la otra mitad: el AA clásico y el modelo que tú traes.

  • Es probable que la hayas usado varias veces hoy sin siquiera saberlo.

  • Piensa en usar cualquiera de tus apps en las que hayas desenfocado el fondo, usado un escáner de código de barras o algún tipo de edición de imágenes.

  • Gran parte de eso se ha basado en el AA clásico y, por lo general, incluso se ejecuta integrado en el dispositivo.

  • Y si alguna vez agregaste alguna de estas funciones a tu propia app o APK, es probable que hayas tenido que elegir entre usar una API lista para usar o traer tu propio modelo.

  • ¿Cuál será el impacto en el tamaño de mi app?

  • Hoy verás que no tienes que elegir entre una solución lista para usar o traer tu propio modelo.

  • De hecho, puedes hacer ambas cosas con un entorno de ejecución optimizado.

  • Me llamo Chintan Parikh.

  • Soy gerente de producto de LiteRT y me acompaña Fergus, líder de ingeniería de los servicios de AA de Android.

  • Hola.

  • Al final, verás cómo puedes compilar una app que ejecute dos modelos en cada fotograma de la cámara a unos 30 fotogramas por segundo.

  • Esta charla tiene cuatro partes.

  • En la primera parte, hablaremos sobre las soluciones de IA integrada en el dispositivo de Google, que se enfocan en el AA clásico, es decir, ML Kit y LiteRT.

  • En segundo lugar, repasaremos las novedades de LiteRT y los Servicios de Play.

  • También se abordará la nueva API de CompiledModel de LiteRT y los dispositivos que admitimos.

  • En tercer lugar, te mostraremos cómo crear una app nueva.

  • Fergus explicará cómo compilar una app con el ML Kit y un modelo personalizado, todo en un solo APK.

  • Por último, te mostraremos cómo actualizar una app existente con el modo de agente.

  • Y también podrías crear una app nueva con la asistencia de este agente.

  • Bien.

  • Primero, comencemos con qué es LiteRT.

  • LiteRT es el entorno de ejecución de inferencia integrado en el dispositivo de Google para tus propios modelos.

  • Usa el mismo formato de archivo .tflite que si ya lo usaste antes con TensorFlow Lite.

  • Se rediseñó para mejorar el rendimiento y también admite varios frameworks.

  • Esto significa que puedes importar modelos de PyTorch, TensorFlow y hasta JAX para poder reducirlos al formato de búfer plano para LiteRT.

  • Desde 2022, TensorFlow Lite en los Servicios de Google Play es el entorno de ejecución integrado en el dispositivo oficial de Android para modelos personalizados.

  • Hoy recibe una actualización importante, y de eso se tratará gran parte de esta charla.

  • La actualización incorporará la API de LiteRT CompiledModel más reciente, que incluye una nueva inferencia de GPU mejorada que será 1.4 veces más rápida y también te permitirá compilar apps más pequeñas con tamaños de APK mucho más reducidos.

  • Entonces, ¿por qué se entrega a través de los Servicios de Play?

  • Hay un par de ventajas, y este es definitivamente un gran punto problemático que veo en muchas de las charlas que escucho, en las que el tamaño de la app y el exceso de APK se están convirtiendo en un verdadero desafío, ¿no?

  • Por lo tanto, obtienes un entorno de ejecución pequeño.

  • El entorno de ejecución no está en tu APK, por lo que dependes de un cliente liviano, y eso hace que tu APK sea aproximadamente 8 MB más pequeño.

  • El segundo beneficio es la eficiencia.

  • Tienes una copia del entorno de ejecución, por lo que el entorno de ejecución de LiteRT se comparte entre todas las apps.

  • Por lo tanto, si tienes muchas apps, cada una podría ahorrarte 8 MB.

  • Eso se acumula muy rápido cuando intentas ahorrar espacio en el disco y tener una app más liviana.

  • En segundo lugar, se mantiene.

  • Google envía las correcciones de errores, aborda los desafíos de los controladores de GPU que no tendrás que hacer y, además, cualquier otra actualización de seguridad se realiza a través de actualizaciones automáticas.

  • Y, como mencioné, la GPU es más rápida, por lo que obtienes una GPU 1.4 veces más rápida, y también entraremos en más detalles al respecto.

  • Y, desde el punto de vista de la cobertura, podemos enviar actualizaciones a dispositivos Android más antiguos.

  • LiteRT en los Servicios de Play es compatible con versiones anteriores hasta Android 7 de 2016.

  • Y, como Fergus también te mostrará, los otros dispositivos nuevos a los que nos expandiremos en las próximas diapositivas.

  • Este es el vehículo de entrega. Ahora hablemos del siguiente paso: el entorno de ejecución.

  • Por lo tanto, LiteRT no es nuevo ni experimental.

  • TensorFlow Lite y LiteRT ya se ejecutan en más de 250,000 apps.

  • Además, se ejecuta en más de 3,800 millones de dispositivos en la actualidad.

  • Por lo tanto, es posible que muchas de las apps que usas, incluso sin saberlo, ejecuten todo esto.

  • Y esto también equivale a más de un billón de inferencias todos los días, ¿verdad?

  • A esa escala, sin duda nos hemos topado con todos los problemas de chipsets extraños, hemos podido solucionar los problemas de ROM o de controladores de GPU, y tenemos una solución alternativa solo para ti.

  • LiteRT también es lo que Google ejecuta en sus apps principales, en todas las apps, plataformas y, incluso, varios dispositivos.

  • Los efectos de YouTube Shorts, la segmentación de fondo de Meet y el Enfoque de fotos son algunos ejemplos en los que los modelos de imágenes pesadas y videos en tiempo real se ejecutan en LiteRT.

  • Esto también es muy importante, ya que es fundamental que los casos de uso sean rápidos y atractivos para los usuarios, ¿verdad?

  • Por lo tanto, este es el mismo entorno de ejecución que reforzamos para estas funciones insignia, y esto es lo que obtienes a través de los Servicios de Play.

Por qué ejecutar la IA integrado en el dispositivo

  • Por lo tanto, también hablemos de por qué usar la IA integrada en el dispositivo.

  • La latencia, la privacidad, el trabajo sin conexión o los costos bajos, si alguno de estos aspectos te importa, ejecútalo sin conexión, ¿verdad?

  • Puede haber aún más motivos, pero estos son algunos de los más evidentes que hemos escuchado para ejecutar integrado en el dispositivo.

  • La ejecución integrado en el dispositivo tampoco siempre es gratuita.

  • Tiene algunos matices y desafíos.

  • Por lo tanto, también repasaremos algunos de estos desafíos y te daremos un camino a seguir, ¿de acuerdo?

  • En cuanto al rendimiento, como viste en algunos de los ejemplos de las apps anteriores, los presupuestos de latencia y memoria siempre son ajustados, ¿verdad?

  • El video y el audio en tiempo real necesitan una eficiencia extrema.

  • Incluso las funciones interactivas simples deben ser rápidas.

  • De lo contrario, perderás la participación de los usuarios.

  • Diversidad de hardware: Existen cientos de SoC con diferentes configuraciones de CPU y GPU.

  • No puedes escribir código para todos estos, ¿verdad?

  • ¿Cómo se resuelve todo eso?

  • Tamaño del APK: El empaquetado de un entorno de ejecución nativo también aumenta el tamaño de cada descarga, lo que puede afectar tus porcentajes de conversiones.

  • Personalización: El entrenamiento, la calidad y el tamaño del modelo serán extremadamente importantes incluso antes de la implementación.

  • Por lo tanto, sí, crear una gran app para dispositivos puede ser difícil.

  • Pero en cada una de estas situaciones, queremos que la plataforma haga el trabajo por ti y no al revés, ¿verdad?

  • La cartera de productos de Google integrados en el dispositivo existe para abordar estos desafíos, y los analizaremos a continuación.

  • Por lo tanto, hoy nos enfocaremos en dos soluciones simples, ¿verdad?

  • Existen dos formas sencillas de agregar IA integrada en el dispositivo a través de los Servicios de Play.

  • La ruta 1 es la ruta llave en mano con el Kit de AA, ¿verdad?

  • Estas son APIs de visión y lenguaje listas para usar, se requiere poca experiencia en AA, se proporcionan muchos modelos y todos se entregan a través de los Servicios de Play.

  • También veremos algunos ejemplos de estos en las próximas diapositivas.

  • La ruta personalizada, que es a través de LiteRT.

  • LiteRT te permite usar tu propio modelo y ejecutarlo en CPU y GPU.

  • El entorno de ejecución también proviene de los Servicios de Play.

  • Por lo tanto, no lo empaquetas en tu APK.

  • No son excluyentes.

  • También pueden ser mejores juntos.

  • Y eso es exactamente lo que crearemos hoy en los próximos minutos.

  • Pero, primero, hablemos de lo que abarca el ML Kit.

  • Esto es lo que incluye el ML Kit de forma predeterminada.

  • Por lo tanto, si ya estás pensando que algunas de estas funciones satisfacen tus necesidades, es un excelente punto de partida y ya tienes una ventaja.

  • Tenemos cobertura para visión, códigos de barras, documentos, texto, poses, muchas de estas funciones, APIs de lenguaje como traducción, respuestas inteligentes y hasta extracción de entidades, ¿verdad?

  • El punto clave es que muchas de estas APIs de visión y lenguaje se ejecutan con LiteRT de forma interna.

  • Por lo tanto, si el ML Kit hace lo que necesitas, puedes comenzar aquí.

  • Y cuando no sea así, tendrás la oportunidad de usar tu propio modelo.

  • Y aquí está el punto clave: ML Kit y tu modelo personalizado no van a ser dos entornos de ejecución, como mencioné.

  • Piensa en ellas como dos puertas de entrada que conducen al mismo LiteRT que se ejecutará en segundo plano.

  • Por lo tanto, LiteRT será el entorno de ejecución que organizará ambas funciones.

  • Por lo tanto, si tu app ya usa Play Store para el ML Kit, adelante.

  • De lo contrario, también revisaremos la ruta de LiteRT.

Novedades de LiteRT

  • Por lo tanto, también hablemos de las novedades de LiteRT.

  • Como mencioné, LiteRT es una evolución de TensorFlow Lite, ¿verdad?

  • Por lo tanto, las mejoras más importantes son que tenemos una GPU más rápida.

  • La GPU más rápida admite OpenCL y OpenGL, y también tiene compatibilidad multiplataforma, incluso para backends de Metal.

  • Por lo tanto, puedes usarlo para varias plataformas según sea necesario.

  • También es más simple.

  • Tenemos un flujo de trabajo unificado para la aceleración de CPU, GPU y NPU.

  • Actualmente, la CPU y la GPU están en los Servicios de Play, mientras que la NPU se incluye a través de LiteRT, y ese es un trabajo en curso.

  • Anteriormente, cada acelerador implicaba una configuración de delegado diferente, ¿verdad?

  • Ahora solo tienes que hacerlo una vez.

  • Por lo tanto, hay una API con resguardo automático a la CPU, y no necesitas realizar configuraciones dedicadas o delegadas.

  • Y puedes tener llamadas de acelerador que pueden administrar esto de manera mucho más simple y con menos código.

  • También es potente, ya que el mismo modelo se ejecuta en varias plataformas, como mencioné.

  • La flexibilidad será fundamental.

  • Por lo tanto, el formato .tflite se mantiene igual.

  • Si ya tenías una app, puedes seguir usando este formato.

  • Si estás creando una app nueva, puedes volver a usar este formato de archivo.

  • También es interesante que admitimos la API de Interpreter, que solía estar en TensorFlow Lite.

  • Por lo tanto, si quieres migrar en fases, la API de Interpreter se incluye como parte del nuevo LiteRT, lo que facilita la migración.

  • Ese es el entorno de ejecución.

  • Hablemos de lo que puedes compilar con esto.

  • Esto es lo que se está creando hoy en día con las apps para Android.

  • Todo, desde efectos de cámara, edición de fotos, escritura inteligente, juegos y avatares, ¿verdad?

  • Muchas de estas apps necesitarán capacidades en tiempo real.

  • La GPU envía fotogramas directamente desde la cámara, por lo que será importante que las cosas sean rápidas y en tiempo real.

  • Algunos de estos modelos de edición de fotos también se están volviendo más pesados.

  • Lo mismo ocurre con las funciones de RA y RV que también viste en algunas de las demostraciones con los lentes, muchas de ellas ejecutan LiteRT de forma interna.

  • Es el mismo entorno de ejecución que ahora está detrás de las funciones insignia de Google y también en los Servicios de Play, por lo que obtienes todo esto sin empaquetar nada en tu APK.

  • Ahora, ¿por qué no creamos una app? Fergus nos mostrará cómo hacerlo.

  • Hagámoslo.

  • Gracias, Chintan.

  • Por lo tanto, voy a hablar un poco sobre las novedades de LiteRT en los Servicios de Google Play.

  • Antes de compilar, una noticia más: todo lo que acabas de ver ahora se ejecuta más allá del teléfono, LiteRT en los Servicios de Play también está disponible en Wear OS y el SO Android Automotive.

  • Por lo tanto, puedes tener modelos integrados en el dispositivo que se ejecuten en tu reloj o en otro dispositivo wearable, o en el auto.

  • Antes, era posible usar una app en el teléfono que fuera complementaria de Wear, pero ahora puedes ejecutarla en el dispositivo wearable, y lo mismo ocurre con Android Automotive.

  • Por lo tanto, tienes la misma API, el mismo modelo .tflite, pero más plataformas.

  • No es necesario realizar una implementación independiente para cada factor de forma, sino que puedes usar la misma implementación para todos estos dispositivos diferentes.

  • Y lo mejor del paradigma de distribución de los Servicios de Play es que podemos adaptarlo para que se ejecute en dispositivos más antiguos.

  • Por lo tanto, para el SO Android Automotive, admitimos versiones anteriores hasta Android 11, lanzado en 2020, y para Wear OS, admitimos Wear OS 4 y versiones posteriores.

  • Bien.

  • Ahora, hablaré sobre dos rutas diferentes: compilar una app nueva y actualizar una app existente.

  • Eso es lo que abordaremos en el resto de la charla.

  • Por lo tanto, comenzaré con una app de ejemplo que combina el uso de ML Kit con un modelo de GPU personalizado que se ejecuta en LiteRT.

  • Y, luego, para actualizar una app existente, habrá tres pequeños cambios: un cambio de Gradle para actualizar las dependencias, un cambio de inicialización para habilitar LiteRT en los Servicios de Play y, luego, cambiar de la API de Interpreter a la API de CompiledModel.

  • Pero primero lo haremos con la app nueva, porque la actualización tiene mucho más sentido una vez que ves a qué te estás actualizando.

Descripción general de la aplicación de ejemplo

  • Por lo tanto, compilar una app nueva

  • Esta es la app que compilaremos.

  • Tendrá una vista de cámara en vivo, en la que te verás con nitidez, y el fondo tendrá un estilo artístico.

  • Por lo tanto, tomaremos el fotograma de la cámara.

  • Transmitiremos las imágenes del fotograma de la cámara a través de la segmentación de selfies del ML Kit.

  • Esa es una de las APIs listas para usar del Kit de AA.

  • Y eso producirá una máscara de primer plano que básicamente indicará cuáles de los píxeles de la imagen corresponden a la persona que aparece en ella.

  • Luego, tomaremos nuestro modelo personalizado, que es como un modelo de tipo transferencia de estilo, y aplicará un estilo a una imagen.

  • Y lo aplicaremos a todo el fotograma de la cámara, pero en realidad solo nos preocupa la parte del fondo, porque al final tomaremos el fotograma original de la cámara, la máscara y el fondo con estilo, y con un poco de lógica simple los combinaremos, de modo que tengamos un fotograma compuesto en el que mantuvimos el sujeto y el fondo tiene el estilo.

  • Por lo tanto, queremos usar APIs listas para usar donde existan y APIs personalizadas donde diferencien nuestra app.

  • Esta es la primera parte en la que invocamos la API de Selfie Segmentation del ML Kit.

    // 1. Configure and create segmenter client
    val segmenter = Segmentation.getClient(
        SelfieSegmenterOptions.Builder()
            .setDetectorMode(
                SelfieSegmenterOptions.STREAM_MODE)
            .build())
    
    // 2. Prepare image & run inference
    fun processFrame(mediaImage: Image) {
      val image = InputImage.fromMediaImage(
          mediaImage, /* rotationDegrees= */ 0)
      segmenter.process(image)
          .addOnSuccessListener { mask -> … }
    }
  • Entonces, esto es como una API normal, ¿verdad?

  • Esto es como el pan de cada día para los desarrolladores de Android.

  • Ya sabes, solo tienes que consultar la documentación de la API o pedirle a Gemini que la cree por ti.

  • Pero, como ves, es bastante sencillo.

  • Cuando creas un cliente, pasas algunas opciones.

  • En este caso, especificamos el modo de transmisión para poder procesar un flujo de fotogramas de video.

  • Luego, se llama al método process y la devolución de llamada de este obtendrá la máscara que se devuelve, calculada por la segmentación de selfies.

  • Y la entrada es la imagen de la cámara.

  • Y todas estas APIs usan tipos de nivel de aplicación, no tensores sin procesar, por lo que realmente estás programando en un nivel muy alto y eso es muy sencillo.

Modelos personalizados en LiteRT

  • Para eso, en la segunda parte, el modelo personalizado, usaremos un modelo de PyTorch.

  • Creo que Chintan obtuvo este de Kaggle o Hugging Face…

  • Así es.

  • Sí, o puedes convertir tus propios archivos.

  • Puedes crear tu propio modelo.

  • Lo siento, volveré.

  • Sí, así es como se ve la pila.

  • Puedes tomar un modelo de PyTorch, convertirlo y cuantizarlo, y luego obtener un modelo de LiteRT.

  • Luego, distribuyes ese archivo con tu app como quieras.

  • Se puede empaquetar como parte de la app como un recurso o se puede descargar por separado.

  • Ambas opciones funcionan.

  • Y eso se ubica sobre el entorno de ejecución de LiteRT en los Servicios de Play.

  • Además, hay kernels de CPU para optimizar en CPU, y ML Drift es el nombre del acelerador de GPU.

  • Sí, como dije, obtienes el modelo de TFLite. Puedes entrenar el modelo tú mismo o buscar un modelo existente, de cualquier manera funciona.

  • La conversión desde PyTorch requiere solo unas pocas líneas de Python.

    import litert_torch
    
    model = my_models.Stylizer().eval()
    
    # Convert with torch.export under the hood
    edge_model = litert_torch.convert(
        model, sample_inputs)
    edge_model.export("stylizer_f32.tflite")
  • Por lo tanto, instalas LiteRT-Torch con pip, llamas a litert_torch.convert, le pasas algunos sample_inputs que pueden ser entradas aleatorias y exportas un archivo de TFLite.

  • Por cierto, LiteRT-Torch es el nuevo nombre de ai-edge-torch, por si ya lo conocías.

  • Y, luego, la cuantización es, de nuevo, muy sencilla.

    # Python
    # previously ai_edge_quantizer
    from litert_quantizer import quantizer, recipe
    
    qt = quantizer.Quantizer("stylizer_f32.tflite")
    
    # int8 weights, float activations
    qt.load_quantization_recipe(
        recipe.dynamic_wi8_afp32())
    
    qt.quantize().export_model("stylizer_int8.tflite")
  • Importas el cuantificador y la receta desde LiteRT Quantizer.

  • Cuando construyes el cuantizador, pasas el modelo original de punto flotante, pasas una receta que es la receta estándar que usamos para la GPU, que usa pesos enteros de 8 bits, pero mantiene las activaciones como punto flotante de 32 bits.

  • Luego, solo debes llamar a quantize y, después, a export_model para guardar el modelo de salida.

  • Y ese será un modelo cuantizado con el que podrás ejecutar y que tendrá pesos mucho más pequeños, y se ejecutará de manera más eficiente.

Aceleración de GPU con la API de CompiledModel

  • Sí, la API de CompiledModel de la GPU es donde realmente se destaca.

  • Como mencionó Chintan, se observa una aceleración significativa en la GPU de TFLite heredada.

  • Las cifras exactas variarán un poco de un modelo a otro, pero 1.4 veces es lo que puedes esperar razonablemente.

  • Es hasta 10 veces más rápida que la inferencia de CPU, por lo que es, ya sabes, la gran ventaja, ¿verdad?

  • Si la mayoría de ustedes usa modelos hoy en día, es probable que los ejecuten en CPU y se pierdan un factor de 10 en el rendimiento que pueden obtener de la GPU.

  • Ese es un incentivo real.

  • ¿Qué hace que sea rápido?

  • Bien, hay muchas cosas que admitimos, por ejemplo, la ejecución asíncrona para que puedas tomar un AHardwareBuffer y pasarlo directamente o un búfer de OpenGL de esa canalización de renderización de la cámara, pasarlo directamente a un búfer de tensor.

  • La optimización de copia cero que admitimos, básicamente, te permite procesar elementos con un presupuesto de baja latencia, como cuando tienes que procesar cada fotograma en cuestión de unas pocas decenas de milisegundos, por lo que incluso copiar un búfer de memoria puede ser una sobrecarga no trivial.

  • Por lo tanto, para esas aplicaciones con requisitos en tiempo real muy altos, puedes usar la optimización de copia cero, que es compatible.

  • Y, luego, como mencionó Chintan, es multiplataforma y admite OpenGL, OpenCL y Metal como backends de GPU.

  • Por último, pero no menos importante, el optimizador de ML Drift es de código abierto.

  • Está disponible con la licencia de Apache.

  • Hace poco, Google lo convirtió en un proyecto de código abierto.

  • Bien, y aquí está el código de la app.

    // Kotlin
    // Build once, off the main thread.
    private val model: CompiledModel =
        CompiledModel.create(
            context.assets,
            "stylizer_int8.tflite",
            // Simple GPU setup!
            CompiledModel.Options(Accelerator.GPU),
            environment
        )
    
    // Reuse buffers across frames.
    private val inputBuffers  = model.createInputBuffers()
    private val outputBuffers = model.createOutputBuffers()
    
    fun stylize(input: FloatArray): FloatArray {
        inputBuffers[0].writeFloat(input)
        model.run(inputBuffers, outputBuffers) // sync
        return outputBuffers[0].readFloat()
    }
  • Como puedes ver, es bastante pequeño y sencillo.

  • Por lo tanto, creas el modelo una vez y, luego, lo reutilizas en cada fotograma.

  • Por lo tanto, CompiledModel.create pasa el archivo .tflite.

  • Solo debes especificar que quieres ejecutar en la GPU y, luego, construir la entrada y el outputBuffers.

  • Luego, en el bucle principal, en el que procesas cada fotograma, llamas a este model.run pasando la entrada y la salida.

  • Después de escribir en inputBuffers, llama a model.run y, luego, lee desde outputBuffers.

  • Bien.

  • Ah, sí, y luego, si solo especificas GPU allí, se ejecutará en la GPU.

  • Si también especificas la CPU y la GPU allí, se intentará ejecutar la GPU.

  • Si la GPU no está disponible por algún motivo, se recurrirá a la CPU.

  • Por lo tanto, en algunos casos, es posible que el resguardo de CPU no sea lo suficientemente eficiente para tu app, y es ahí cuando querrás especificar solo la GPU de esa manera.

  • Por lo general, se recomienda tener un resguardo de CPU.

Usa LiteRT en los Servicios de Google Play

  • Bien.

  • Por lo tanto, la compilamos con LiteRT empaquetado, que aún no usa los Servicios de Play.

  • Por lo tanto, te mostraré cómo usar LiteRT en los Servicios de Play.

  • Por lo tanto, hay tres cambios: el primero es el cambio de dependencia.

    // Easier with CompiledModel API: 3 steps
    
    // 1. app/build.gradle: replace litert with play-services-litert
    - implementation 'com.google.ai.edge.litert:litert:...'
    + implementation 'com.google.android.gms:play-services-litert:17.0.0'  // also pulls in litert-api
  • Solo debes reemplazar, en tu archivo de Gradle o en cualquier otro lugar, cualquier sistema de compilación que uses, en cualquier otro lugar donde especifiques las dependencias del paquete de Maven, eso es lo que vas a cambiar.

  • Y quitas la dependencia litert o cualquiera de las dependencias de paquetes de Maven de TensorFlow Lite anteriores, y las reemplazas por esta play-services-litert.

  • Esto también extrae el paquete litert-api.

  • Ahora, si escribes una capa intermedia que solo quiere depender de LiteRT, pero no le importa si el tiempo de ejecución proviene de la app o de los Servicios de Play, puedes depender de la API de LiteRT y tomar un entorno como parámetro de entrada.

  • Por lo tanto, el segundo paso es el parámetro del entorno.

  • Ahí es donde proporcionas la inserción de dependencias, básicamente, para especificar que estás usando o quieres usar LiteRT de los Servicios de Play.

  • Por lo tanto, debes importar gms.litert.LiteRt y llamar a la función de inicialización, pasando el contexto, que es tu actividad de Android.

    // 2. Initialize the LiteRT Environment from Play services (context = your Activity)
    - val environment = Environment.create(...)
    + import com.google.android.gms.litert.LiteRt
    + val environment = LiteRt.initialize(context).await()
    
    // 3. Pass environment whenever you call CompiledModel.create
    
    // That's it! The rest of your app uses the normal CompiledModel APIs from litert-api.
  • Y eso es asíncrono, por lo que debes llamar a .await o hacer que el resto se base en una devolución de llamada.

  • Por último, una vez que tengas ese entorno, solo debes pasarlo cada vez que llames a CompiledModel.create.

  • Y eso es lo que hará que use el entorno de ejecución de LiteRT de los Servicios de Play.

  • Y eso es todo.

  • Eso significa que el resto de tu app usa exactamente las mismas APIs de LiteRT CompiledModel de la API de LiteRT.

  • El resto del código de inferencia no cambia para usar los Servicios de Play.

  • Y, de hecho, puedes realizar esa migración de forma incremental.

  • No es necesario que lo hagas todo a la vez, puedes migrar un componente por vez.

  • Si tienes una app grande, tiene sentido migrar cada componente que use LiteRT y, luego, puedes migrar uno por uno y probar uno por uno.

  • La única advertencia es que solo obtienes la ventaja del tamaño, el ahorro de espacio solo se produce cuando quitas la última dependencia del entorno de ejecución empaquetado.

  • Y, si lo haces, la otra advertencia es que no debes mezclar objetos entre LiteRT en los Servicios de Play y LiteRT empaquetado.

  • Por lo tanto, si obtienes tensores, modelos compilados o intérpretes de LiteRT en los Servicios de Play, no debes pasarlos a la versión integrada de LiteRT ni viceversa.

  • Pero, de lo contrario, mezclar estas cosas funciona bien.

  • Bien.

  • Así es como se compila una app nueva.

  • Ahora, hablaré sobre cómo actualizar una app existente.

  • Por lo tanto, es posible que tengas una app existente que use la API de Interpreter.

  • Esta es la API de TFLite más antigua que usa el intérprete como la clase principal.

  • Por lo tanto, ese es el código de la izquierda que usa la API de Interpreter y, luego, a la derecha, ves el nuevo código de la API de CompiledModel.

    // Dependencies (Gradle):
    // play-services-tflite-java and/or litert (bundled)
    
    // Init
    TfLite.initialize(context).await()
    
    // Load
    val interpreterOptions =
        InterpreterApi.Options().apply {
          runtime = TfLiteRuntime.FROM_SYSTEM_ONLY
        }
    
    val interpreter =
        InterpreterApi.create(modelFile, interpreterOptions)
    
    // Prepare inputs/outputs
    val inputs = …
    val outputs = …
    
    // Execute
    interpreter.run(inputs, outputs)
    // Dependencies (Gradle):
    // play-services-litert
    
    // Init
    val environment =
      LiteRt.initialize(context).await()
    
    // Load
    val modelOptions = CompiledModel.Options(Accelerator.CPU)
    
    val model =
        CompiledModel.create(modelPath, modelOptions, environment)
    
    // Prepare inputs/outputs
    val inputBuffers = model.createInputBuffers()
    val outputBuffers = model.createOutputBuffers()
    
    // Execute
    model.run(inputBuffers, outputBuffers
  • Por lo tanto, solo debes cambiar TfLite.initialize por LiteRt.initialize, y eso ahora devuelve un entorno.

  • Luego, pasas el entorno a CompiledModel.create.

  • Por lo tanto, es un cambio pequeño, sin crecimiento del APK.

  • En la siguiente diapositiva, te mostraremos cómo hacerlo con GPU, que es solo una opción más.

  • Este es el código adicional que necesitabas para habilitar la GPU.

    // Dependencies (Gradle):
    // play-services-tflite-java and/or litert (bundled)
    
    // Init
    val initOptions = TfLiteInitializationOptions.builder()
        .setEnableGpuDelegateSupport(true).build()
    TfLite.initialize(context, initOptions).await()
    val useGpu =
        TfLiteGpu.isGpuDelegateAvailable(context).await()
    
    // Load
    val interpreterOptions =
        InterpreterApi.Options().apply {
          runtime = TfLiteRuntime.FROM_SYSTEM_ONLY
        }
    if (useGpu) {
        interpreterOptions.addDelegateFactory(
            GpuDelegateFactory());
    }
    val interpreter =
        InterpreterApi.create(modelFile, interpreterOptions)
    
    // Prepare inputs/outputs
    val inputs = …
    val outputs = …
    
    // Execute
    interpreter.run(inputs, outputs)
    // Dependencies (Gradle):
    // play-services-litert
    
    // Init
    val initOptions = LiteRtInitializationOptions.builder()
        .setEnableGpu(true).build()
    val environment = LiteRt.initialize(context, initOptions).await()
    
    // Load
    val modelOptions =
        CompiledModel.Options(Accelerator.CPU, Accelerator.GPU)
    
    val model =
        CompiledModel.create(modelPath, modelOptions, environment)
    
    // Prepare inputs/outputs
    val inputBuffers = model.createInputBuffers()
    val outputBuffers = model.createOutputBuffers()
    
    // Execute
    model.run(inputBuffers, outputBuffers)
  • Como ves, el código de la nueva API para habilitar la GPU es un poco más sim-- sí, más simple que el código anterior.

  • Por lo tanto, la primera llamada a un setEnableGpu en las opciones de inicialización de LiteRT que luego pasas a LiteRt.initialize hará que el código del acelerador de GPU se cargue en tu app.

  • Luego, cuando construyes el modelOptions y lo pasas a CompiledModel.create, especificas qué acelerador se usará para un modelo en particular, si quieres que otro modelo se ejecute solo en la GPU, en la GPU con resguardo de CPU o solo en la CPU.

  • Bien.

  • Sí, como puedes ver, habilitar la GPU es mucho más sencillo con la nueva API.

  • ¿Qué obtienes realmente?

  • Chintan te lo dirá.

  • Bien.

  • Muy bien. Gracias, Fergus.

  • Entonces, hablemos de lo que todo esto nos aporta, ¿verdad?

  • Recuerda que dijimos que íbamos a compilar una app, así que veamos qué compilamos, ¿no?

  • Ese soy yo, de todos modos, y lo que hicimos aquí es que usamos el ML Kit para encontrarme, por lo que la segmentación la realiza una API lista para usar, como el ML Kit.

  • Así que, eso es solo encontrar mi cabeza por ahí.

  • Luego, LiteRT usa un modelo similar a la transferencia de estilo para pintar el fondo.

  • Y los otros beneficios, como mencionamos, son que obtienes aproximadamente 8 MB de ahorro de espacio, ahora tienes un entorno de ejecución que se usa entre todas tus apps, o al menos como el que se comparte aquí, y obtienes actualizaciones automáticas, y también tienes una GPU más rápida que te acerca a los 30 fotogramas por segundo en algo que debe ser en tiempo real para una experiencia del usuario enriquecida.

  • Lo bueno es que no tienes que hacer todo esto de forma manual.

  • También hay una nueva habilidad que acabamos de lanzar en Android: básicamente, publicamos una habilidad de LiteRT para Android que actualiza tu AA integrado en el dispositivo en minutos, ¿verdad?

  • Por lo tanto, podrías hacer un par de cosas con esto: actualizar una app existente, crear una app nueva o actualizar tu app para que use esta nueva integración de los Servicios de Play.

  • Por lo tanto, todo esto está disponible.

  • El vínculo está en la diapositiva, también está en GitHub y aparecerá en nuestra documentación y en nuestro blog.

  • Y sí, eso también debería ser útil para cualquier persona que quiera hacer el cambio pronto.

  • Luego, Fergus nos contará hacia dónde se dirige todo esto.

Hoja de ruta y resumen de LiteRT

  • Por lo tanto, nos comprometemos con la IA integrada en el dispositivo con LiteRT.

  • Seguimos invirtiendo de forma significativa en mejorar la aceleración de GPU y la cobertura de modelos, y en proporcionar actualizaciones periódicas para LiteRT 2.x, tanto para el paquete de código abierto de LiteRT como para el paquete de Maven de LiteRT de los Servicios de Play, que es LiteRT en los Servicios de Play.

  • También seguiremos proporcionando retrocompatibilidad.

  • El entorno de ejecución de los Servicios de Play seguirá admitiendo apps compiladas con SDKs más antiguos.

  • Sí.

  • Sabes que eso es muy importante para nuestros usuarios y para nosotros.

  • En el caso de los SDKs de LiteRT 1.x, estos se encuentran en modo de mantenimiento, por lo que solo se aplican correcciones de seguridad críticas.

  • Y la NNAPI, que dejamos de usar en 2024, desaparecerá y es probable que se quite a partir de 2027.

  • Por lo tanto, si usas NNAPI, cambia a la aceleración de GPU o NPU con LiteRT incluido.

  • Bien.

  • Sí.

  • Por lo tanto, cuanto antes migres a la versión 2.x y a CompiledModel, menos tendrás que hacer más adelante.

  • Por lo tanto, hay tres conclusiones que debes tener en cuenta.

  • Por lo tanto, compila.

  • Comienza con ML Kit y, si ya hace lo que necesitas, genial.

  • De lo contrario, usa LiteRT para tus modelos personalizados.

  • Actualiza a LiteRT en los Servicios de Google Play para ahorrar espacio en el APK y usar el entorno de ejecución compartido.

  • Además, considera usar la API de CompiledModel para una inferencia de GPU más rápida y sencilla.

  • Sí.

  • Todo está documentado en nuestro sitio de documentación de LiteRT en AI Edge, en la URL que se muestra.

  • Entonces, sí.

  • Gracias por acompañarnos. Esperamos con ansias ver lo que crearán.

Código

Fragmentos de código

Fragmento de Kotlin en el minuto 15:09 de "Descripción general de la aplicación de ejemplo"
// 1. Configure and create segmenter client
val segmenter = Segmentation.getClient(
    SelfieSegmenterOptions.Builder()
        .setDetectorMode(
            SelfieSegmenterOptions.STREAM_MODE)
        .build())

// 2. Prepare image & run inference
fun processFrame(mediaImage: Image) {
  val image = InputImage.fromMediaImage(
      mediaImage, /* rotationDegrees= */ 0)
  segmenter.process(image)
      .addOnSuccessListener { mask -> … }
}
Fragmento de Python en el minuto 17:34 de "Modelos personalizados en LiteRT"
import litert_torch

model = my_models.Stylizer().eval()

# Convert with torch.export under the hood
edge_model = litert_torch.convert(
    model, sample_inputs)
edge_model.export("stylizer_f32.tflite")
Fragmento de Python en el minuto 18:04 de "Modelos personalizados en LiteRT"
# Python
# previously ai_edge_quantizer
from litert_quantizer import quantizer, recipe

qt = quantizer.Quantizer("stylizer_f32.tflite")

# int8 weights, float activations
qt.load_quantization_recipe(
    recipe.dynamic_wi8_afp32())

qt.quantize().export_model("stylizer_int8.tflite")
Fragmento de Kotlin en el minuto 21:06 de "Aceleración de GPU con la API de CompiledModel"
// Kotlin
// Build once, off the main thread.
private val model: CompiledModel =
    CompiledModel.create(
        context.assets,
        "stylizer_int8.tflite",
        // Simple GPU setup!
        CompiledModel.Options(Accelerator.GPU),
        environment
    )

// Reuse buffers across frames.
private val inputBuffers  = model.createInputBuffers()
private val outputBuffers = model.createOutputBuffers()

fun stylize(input: FloatArray): FloatArray {
    inputBuffers[0].writeFloat(input)
    model.run(inputBuffers, outputBuffers) // sync
    return outputBuffers[0].readFloat()
}
Fragmento de Groovy en el minuto 22:36 de "Usa LiteRT en los Servicios de Google Play"
// Easier with CompiledModel API: 3 steps

// 1. app/build.gradle: replace litert with play-services-litert
- implementation 'com.google.ai.edge.litert:litert:...'
+ implementation 'com.google.android.gms:play-services-litert:17.0.0'  // also pulls in litert-api
Fragmento de Kotlin en el minuto 23:43 de "Usa LiteRT en los Servicios de Google Play"
// 2. Initialize the LiteRT Environment from Play services (context = your Activity)
- val environment = Environment.create(...)
+ import com.google.android.gms.litert.LiteRt
+ val environment = LiteRt.initialize(context).await()

// 3. Pass environment whenever you call CompiledModel.create

// That's it! The rest of your app uses the normal CompiledModel APIs from litert-api.
Fragmento de Kotlin en el minuto 25:45 de "Usa LiteRT en los Servicios de Google Play"
// Dependencies (Gradle):
// play-services-tflite-java and/or litert (bundled)

// Init
TfLite.initialize(context).await()

// Load
val interpreterOptions =
    InterpreterApi.Options().apply {
      runtime = TfLiteRuntime.FROM_SYSTEM_ONLY
    }

val interpreter =
    InterpreterApi.create(modelFile, interpreterOptions)

// Prepare inputs/outputs
val inputs = …
val outputs = …

// Execute
interpreter.run(inputs, outputs)
Fragmento de Kotlin en el minuto 25:45 de "Usa LiteRT en los Servicios de Google Play"
// Dependencies (Gradle):
// play-services-litert

// Init
val environment =
  LiteRt.initialize(context).await()

// Load
val modelOptions = CompiledModel.Options(Accelerator.CPU)

val model =
    CompiledModel.create(modelPath, modelOptions, environment)

// Prepare inputs/outputs
val inputBuffers = model.createInputBuffers()
val outputBuffers = model.createOutputBuffers()

// Execute
model.run(inputBuffers, outputBuffers
Fragmento de Kotlin en el minuto 26:25 de "Usa LiteRT en los Servicios de Google Play"
// Dependencies (Gradle):
// play-services-tflite-java and/or litert (bundled)

// Init
val initOptions = TfLiteInitializationOptions.builder()
    .setEnableGpuDelegateSupport(true).build()
TfLite.initialize(context, initOptions).await()
val useGpu =
    TfLiteGpu.isGpuDelegateAvailable(context).await()

// Load
val interpreterOptions =
    InterpreterApi.Options().apply {
      runtime = TfLiteRuntime.FROM_SYSTEM_ONLY
    }
if (useGpu) {
    interpreterOptions.addDelegateFactory(
        GpuDelegateFactory());
}
val interpreter =
    InterpreterApi.create(modelFile, interpreterOptions)

// Prepare inputs/outputs
val inputs = …
val outputs = …

// Execute
interpreter.run(inputs, outputs)
Fragmento de Kotlin en el minuto 26:25 de "Usa LiteRT en los Servicios de Google Play"
// Dependencies (Gradle):
// play-services-litert

// Init
val initOptions = LiteRtInitializationOptions.builder()
    .setEnableGpu(true).build()
val environment = LiteRt.initialize(context, initOptions).await()

// Load
val modelOptions =
    CompiledModel.Options(Accelerator.CPU, Accelerator.GPU)

val model =
    CompiledModel.create(modelPath, modelOptions, environment)

// Prepare inputs/outputs
val inputBuffers = model.createInputBuffers()
val outputBuffers = model.createOutputBuffers()

// Execute
model.run(inputBuffers, outputBuffers)