Não precisa mais escolher entre a conveniência da IA plug-and-play e a flexibilidade de modelos personalizados. É possível implantar as duas em um único app ultraenxuto, sem adicionar megabytes de bloatware binário.
Nesta sessão, vamos demonstrar como criar essa arquitetura de pilha dupla em um único app Android. Você vai aprender a usar o Kit de ML para tarefas clássicas de ML prontas para uso (como digitalização de documentos) com o LiteRT independente no Google Play Services para suas cargas de trabalho personalizadas de visão computacional ou áudio. Vamos explicar como os dois caminhos de implementação se unem para usar o ambiente de execução moderno do LiteRT, oferecendo ao app um desempenho otimizado com aceleração de hardware em CPUs e GPUs com um download de praticamente zero byte.
Principais aprendizados para desenvolvedores:
-Desempenho sem concessões: os modelos prontos e personalizados são acelerados por hardware automaticamente usando a API CompiledModel unificada.
-Micro-APKs: reduza drasticamente o tamanho do download do app transferindo os ambientes de execução do Kit de ML e do LiteRT para o Google Play Services.
- Integração híbrida: domine a execução de vários fluxos de trabalho de ML lado a lado na produção sem conflitos de recursos.
play-services-litert, chamar LiteRt.initialize para receber um ambiente e transmiti-lo para CompiledModel.create.Transcrição
Boa noite, pessoal.
A palestra vai começar.
Portanto, quando as pessoas dizem "IA no dispositivo" hoje, geralmente se referem aos LLMs.
Hoje, você assistiu a várias palestras sobre o Gemini Nano que abordaram o Kit de ML, o Firebase e muitos outros produtos do Google.
Esta sessão é sobre a outra metade: o ML clássico e o modelo que você traz.
Você provavelmente já usou esse recurso algumas vezes hoje sem nem perceber.
Pense em qualquer um dos seus apps em que você desfocou o plano de fundo, usou um leitor de código de barras ou algum tipo de edição de imagem.
Grande parte disso tem sido no ML clássico e, normalmente, até mesmo no dispositivo.
E se você já adicionou algum desses recursos ao seu app ou APK, provavelmente já se deparou com essa escolha: usar uma API pronta ou trazer seu próprio modelo?
Qual vai ser o impacto no tamanho do meu app?
Hoje, você vai ver que não precisa escolher entre uma solução pronta ou trazer seu próprio modelo.
Na verdade, é possível fazer as duas coisas com um ambiente de execução enxuto.
Meu nome é Chintan Parikh.
Sou gerente de produtos do LiteRT, e comigo está Fergus, líder de engenharia dos serviços de ML do Android.
Olá!
No final, você vai aprender a criar um app que executa dois modelos em cada frame da câmera a cerca de 30 quadros por segundo.
Esta palestra tem quatro partes.
Na primeira parte, vamos falar sobre as soluções de IA no dispositivo do Google com foco em ML clássico, ou seja, o Kit de ML e o LiteRT.
Em seguida, vamos falar sobre as novidades do LiteRT e do Google Play Services.
Isso também vai abranger a nova API CompiledModel do LiteRT e os dispositivos compatíveis.
Três, vamos mostrar como criar um novo app.
Fergus vai explicar como criar um app com o Kit de ML e um modelo personalizado em um único APK.
Por fim, vamos mostrar como fazer upgrade de um app usando o Modo Agente.
Além disso, você pode até mesmo criar um novo app com o suporte desse agente.
Certo.
Primeiro, vamos começar com: o que é o LiteRT?
O LiteRT é o ambiente de execução de inferência no dispositivo do Google para seus próprios modelos.
Ele usa o mesmo formato de arquivo .tflite que você já usou com o TensorFlow Lite.
Ele foi reformulado para melhorar o desempenho e também oferece suporte a vários frameworks.
Isso significa que é possível usar modelos do PyTorch, do TensorFlow e até do JAX para reduzir o formato de buffer simples para o LiteRT.
Desde 2022, o TensorFlow Lite no Google Play Services é o ambiente de execução oficial no dispositivo do Android para modelos personalizados.
Hoje, ele recebe um grande upgrade, e é sobre isso que vamos falar.
O upgrade vai trazer a API LiteRT CompiledModel mais recente, incluindo uma nova inferência de GPU melhorada que será 1, 4 vez mais rápida e também vai permitir que você crie apps menores com tamanhos de APK muito mais enxutos.
Então, por que disponibilizar pelo Google Play Services?
Há algumas vantagens, e esse é um grande problema que estou vendo em muitas conversas, em que o tamanho do app e o excesso de APKs estão se tornando um verdadeiro desafio, certo?
Assim, você tem um ambiente de execução pequeno.
O ambiente de execução não está no APK, então você depende de um cliente leve, o que reduz o tamanho do APK em cerca de 8 MB.
O segundo benefício é a eficiência.
Você tem uma cópia do ambiente de execução, então o ambiente de execução do LiteRT é compartilhado entre todos os apps.
Imagine se você tiver vários apps, cada um deles pode economizar 8 MB.
Isso se acumula muito rápido quando você está tentando economizar espaço em disco e ter um app mais enxuto.
Segundo, ele é mantido.
O Google envia as correções de bugs, resolve os desafios do driver de GPU que você não precisa fazer e todas as outras atualizações de segurança são enviadas por atualizações automáticas.
E, como mencionei, a GPU é mais rápida, então você tem uma GPU 1,4x mais rápida, e vamos entrar em mais detalhes sobre isso também.
E, do ponto de vista da cobertura, podemos enviar para dispositivos Android mais antigos.
O LiteRT no Google Play Services é compatível com o Android 7 de 2016 em diante.
E, como Fergus vai mostrar, os outros novos dispositivos para os quais estamos expandindo nos próximos slides.
Esse é o veículo de entrega. Agora vamos falar sobre a próxima etapa, o ambiente de execução.
Portanto, o LiteRT não é novo nem experimental.
O TensorFlow Lite e o LiteRT já são usados em mais de 250 mil apps.
Ele também é executado em mais de 3,8 bilhões de dispositivos atualmente.
Portanto, muitos dos apps que você usa, talvez sem saber, executam tudo isso.
E isso também equivale a mais de um trilhão de inferências todos os dias, certo?
Nessa escala, certamente já encontramos todos os problemas de chipset, conseguimos resolver problemas de ROM ou de driver de GPU e temos uma solução alternativa para você.
O LiteRT também é usado pelo Google nos principais apps, plataformas e até mesmo em vários dispositivos.
Os efeitos do YouTube Shorts, a segmentação de plano de fundo do Meet e o recurso Remoção do desfoque da foto são alguns exemplos em que o vídeo em tempo real e os modelos de imagem pesados são executados no LiteRT.
Isso também é extremamente importante, já que tornar os casos de uso rápidos e envolventes para os usuários é fundamental, certo?
Esse é o mesmo ambiente de execução que reforçamos para esses recursos principais, e é isso que você recebe pelo Google Play Services.
Vamos falar também sobre por que usar no dispositivo.
Latência, privacidade, trabalho off-line ou custos baixos. Se algum desses fatores for importante para você, execute off-line, certo?
Pode haver ainda mais motivos, mas esses são alguns dos mais óbvios que ouvimos para executar no dispositivo.
A execução no dispositivo também nem sempre é sem custo financeiro.
Ele tem algumas nuances e desafios.
Por isso, também vamos analisar alguns desses desafios e mostrar um caminho a seguir, certo?
Então, desempenho: como você viu, certo, alguns dos exemplos dos apps anteriores, os orçamentos de latência e memória são sempre apertados, certo?
O vídeo e o áudio em tempo real precisam de extrema eficiência.
Até mesmo recursos interativos simples precisam ser rápidos.
Caso contrário, você vai perder o engajamento do usuário.
Diversidade de hardware: existem centenas de SoCs com diferentes configurações de CPU e GPU.
Não dá para escrever código para todos eles, certo?
Como resolver isso?
Tamanho do APK: agrupar um ambiente de execução nativo também aumenta o tamanho de cada download, o que pode afetar suas taxas de conversão.
Personalização: o treinamento, a qualidade e o tamanho do modelo são extremamente importantes antes mesmo da implantação.
Sim, criar um ótimo app no dispositivo pode ser difícil.
Mas em todas essas situações, queremos que a plataforma faça o trabalho por você, e não o contrário, certo?
O portfólio de soluções no dispositivo do Google existe para lidar com esses desafios, e vamos falar sobre isso a seguir.
Por isso, vamos nos concentrar em duas soluções simples hoje, certo?
Há duas maneiras fáceis de adicionar IA no dispositivo usando o Google Play Services.
O caminho 1 é o caminho pronto para uso com o Kit de ML, certo?
São APIs de visão e linguagem prontas para uso, que exigem pouca experiência em ML, com vários modelos fornecidos e entregues pelo Google Play Services.
Vamos mostrar alguns exemplos nos próximos slides.
O caminho personalizado, que é feito pelo LiteRT.
Com o LiteRT, é possível usar seu próprio modelo e executá-lo na CPU ou GPU.
O ambiente de execução também vem do Google Play Services.
Portanto, ele não é incluído no APK.
Não é uma escolha entre um ou outro.
Eles também podem ser melhores juntos.
E é exatamente isso que vamos criar hoje nos próximos minutos.
Mas, primeiro, vamos falar sobre o que o Kit de ML abrange.
Confira o que o Kit de ML oferece por padrão.
Se você já acha que alguns desses recursos atendem às suas necessidades, esse é um ótimo ponto de partida, e você já está um passo à frente.
Temos cobertura para visão, códigos de barras, documentos, texto, pose, muitos desses recursos, APIs de linguagem como tradução, respostas inteligentes e até extração de entidades, certo?
O ponto principal é que muitas dessas APIs de visão e linguagem são executadas com o LiteRT em segundo plano.
Se o Kit de ML faz o que você precisa, comece por aqui.
E quando não tiver, você poderá usar seu próprio modelo.
E aqui está o ponto principal: o Kit de ML e seu modelo personalizado não serão dois ambientes de execução, como mencionei.
Pense nelas como duas portas de entrada que levam ao mesmo LiteRT que vai ser executado em segundo plano.
Portanto, o LiteRT será o ambiente de execução que vai orquestrar esses dois recursos.
Portanto, se o app já usa a Google Play Store, use o Kit de ML.
Caso contrário, também vamos analisar o caminho do LiteRT.
Então, vamos falar sobre as novidades do LiteRT.
Como mencionei, o LiteRT é uma evolução do TensorFlow Lite, certo?
As maiores melhorias são uma GPU mais rápida.
A GPU mais rápida é compatível com OpenCL, OpenGL e também tem suporte multiplataforma, até mesmo para back-ends Metal.
Portanto, você pode usar esse recurso em várias plataformas, conforme necessário.
Também é mais simples.
Temos um fluxo de trabalho unificado para aceleração de CPU, GPU e NPU.
A CPU e a GPU estão atualmente no Google Play Services, enquanto a NPU é agrupada pelo LiteRT, e isso está em andamento.
Antes, cada acelerador significava uma configuração de delegado diferente, certo?
Agora você só precisa fazer isso uma vez.
Portanto, há uma API com fallback automático para a CPU, e você não precisa fazer configurações dedicadas e delegadas.
E você pode ter chamadas de acelerador que gerenciam isso de forma muito mais simples e com menos código.
Ele também é eficiente, já que o mesmo modelo é executado em várias plataformas, como mencionei.
A flexibilidade será fundamental.
Portanto, o formato .tflite permanece o mesmo.
Se você já tinha um app, ainda pode usar esse formato.
Se você estiver criando um novo app, poderá usar esse formato de arquivo novamente.
Também é interessante que oferecemos suporte à API Interpreter, que costumava estar no TensorFlow Lite.
Se você quiser migrar em fases, a API Interpreter está incluída, também faz parte do novo LiteRT, o que facilita a migração.
Esse é o ambiente de execução.
Vamos falar sobre o que você pode criar com isso.
Confira o que os apps Android estão criando hoje.
Tudo, desde efeitos de câmera, edição de fotos, digitação inteligente, jogos e avatares, certo?
Muitos desses apps vão precisar de recursos em tempo real.
A GPU está enviando frames diretamente da câmera, então é importante que as coisas sejam rápidas e em tempo real.
Alguns desses modelos de edição de fotos também estão ficando mais pesados.
E o mesmo vale para os recursos de RA/RV que você também viu em algumas das demonstrações com os óculos. Muitos deles executam o LiteRT em segundo plano.
É o mesmo ambiente de execução que está por trás dos principais recursos do Google e também no Google Play Services. Assim, você tem tudo isso sem precisar agrupar nada no APK.
Agora, vamos criar um app, e o Fergus vai mostrar como fazer isso.
Vamos fazer isso.
Obrigado, Chintan.
Então, vou falar um pouco sobre as novidades do LiteRT no Google Play Services.
Antes de criarmos, mais uma novidade: tudo o que você acabou de ver agora funciona além do smartphone. O LiteRT no Google Play Services também está disponível no Wear OS e no Android Automotive OS.
Assim, você pode ter modelos no dispositivo em execução no seu relógio ou em outro dispositivo wearable, ou no próprio carro.
Antes, era possível usar um app no smartphone que funcionava como um app complementar para o Wear, mas agora ele pode ser executado no próprio dispositivo wearable, assim como no Android Automotive.
Assim, você tem a mesma API, o mesmo modelo .tflite, mas mais plataformas.
Não é necessário fazer uma implementação separada para cada formato. Você pode usar a mesma implementação para todos esses dispositivos diferentes.
E o melhor do paradigma de distribuição do Google Play Services é que podemos fazer o backport para que ele seja executado em dispositivos mais antigos.
Para o Android Automotive OS, oferecemos suporte desde o Android 11, lançado em 2020. Para o Wear OS, oferecemos suporte a partir do Wear OS 4.
Ok.
Agora, vou falar sobre dois caminhos diferentes: criar um novo app e atualizar um app atual.
Isso vai cobrir o restante da palestra.
Então, vou começar com um app de exemplo que combina o uso do Kit de ML com um modelo de GPU personalizado em execução no LiteRT.
Para fazer upgrade de um app, serão necessárias três pequenas mudanças: uma no Gradle para atualizar as dependências, uma de inicialização para ativar o LiteRT no Google Play Services e, por fim, a mudança da API Interpreter para a API CompiledModel.
Mas vamos fazer isso primeiro no novo app, porque o upgrade faz muito mais sentido depois que você vê o que está atualizando.
Então, criar um novo app.
Este é o app que vamos criar.
Ele vai ter uma visualização de câmera ao vivo, em que você fica em destaque, e o plano de fundo vai receber um estilo artístico.
Então, vamos pegar o frame da câmera.
As imagens do frame da câmera serão transmitidas pela segmentação de selfie do Kit de ML.
Essa é uma das APIs prontas do Kit de ML.
Isso vai produzir uma máscara de primeiro plano que basicamente vai dizer quais pixels na imagem correspondem à pessoa na imagem.
Em seguida, vamos usar nosso modelo personalizado, que é como um modelo de transferência de estilo, para aplicar um estilo a uma imagem.
Vamos aplicar isso a todo o frame da câmera, mas só nos preocupamos com o fundo, porque, no final, vamos pegar o frame original da câmera, a máscara e o fundo estilizado e, com uma lógica simples, combinar tudo isso para ter um frame composto em que mantemos o objeto e o fundo tem o estilo.
Por isso, queremos usar APIs prontas quando disponíveis e APIs personalizadas quando elas diferenciam nosso app.
Essa é a primeira parte, em que invocamos a API de segmentação de selfie do Kit de ML.
// 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 -> … }
}Então, é como uma API comum, certo?
Isso é o básico para desenvolvedores Android.
Você só precisa consultar a documentação da API ou pedir ao Gemini para criar para você.
Mas, sabe, é bem simples.
Ao criar um cliente, você transmite algumas opções.
Nesse caso, estamos especificando o modo de streaming para processar um stream de frames de vídeo.
Em seguida, você chama esse método de processo, e o callback dele vai receber a máscara retornada, calculada pela segmentação de selfie.
A entrada é a imagem da câmera.
Todas essas APIs usam tipos de nível de aplicativo, não tensores brutos. Assim, você programa em um nível muito alto, o que é bem simples.
Para a segunda parte, o modelo personalizado, vamos usar um modelo do PyTorch.
Acho que o Chintan pegou isso de um lugar como o Kaggle ou o Hugging Face…
Certo.
Sim, ou você pode converter o seu, sabe.
Você pode criar seu próprio modelo.
Desculpe, voltando.
Sim, essa é a aparência da pilha.
Você pega um modelo do PyTorch, converte e quantiza ele e, em seguida, recebe um modelo do LiteRT.
Em seguida, distribua-o com seu app, como preferir.
Ele pode ser incluído como parte do app como um recurso ou pode ser baixado separadamente.
As duas formas funcionam.
E isso fica sobre o ambiente de execução do LiteRT no Google Play Services.
Além disso, há kernels de CPU para otimização na CPU, e ML Drift é o nome do acelerador de GPU.
Sim, como eu disse, você recebe o modelo do TFLite. É possível treinar o modelo por conta própria ou encontrar um modelo atual. As duas opções funcionam.
A conversão do PyTorch requer apenas algumas linhas 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")Então, você instala o LiteRT-Torch com pip, chama litert_torch.convert, transmite alguns sample_inputs que podem ser entradas aleatórias e exporta um arquivo TFLite.
A propósito, LiteRT-Torch é o novo nome de ai-edge-torch, se você já conhece esse recurso.
A quantização também é muito simples.
# 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")Importe o quantizador e a receita do LiteRT Quantizer.
Ao construir o quantizador, você transmite o modelo original usando pontos flutuantes e uma receita, que é a receita padrão que recomendamos para GPU, que usa pesos inteiros de 8 bits, mas mantém as ativações como ponto flutuante de 32 bits.
Em seguida, basta chamar quantize e export_model para salvar o modelo de saída.
Esse será um modelo quantizado que você poderá executar, com pesos muito menores e uma execução mais eficiente.
Sim, a API CompiledModel da GPU é onde isso realmente se destaca.
Como o Chintan mencionou, há uma aceleração significativa na GPU legada do TFLite.
Os números exatos variam um pouco de acordo com o modelo, mas 1,4 vez é o que você pode esperar.
Até 10 vezes mais rápido do que a inferência de CPU, então essa é a grande vantagem, certo?
Se você é como a maioria das pessoas que usam modelos hoje, provavelmente os executa em CPU e perde um fator de 10 em desempenho que poderia conseguir com a GPU.
Isso é um incentivo real.
O que o torna rápido?
Há várias coisas que oferecemos, por exemplo, execução assíncrona, para que você possa pegar um AHardwareBuffer e transmiti-lo diretamente ou um buffer OpenGL desse pipeline de renderização da câmera e transmiti-lo diretamente para um buffer de tensor.
A otimização de cópia zero que oferecemos permite que, ao processar dados com um orçamento de baixa latência, como quando você precisa processar cada frame em questão de algumas dezenas de milissegundos, até mesmo a simples cópia de um buffer de memória pode ser uma sobrecarga não trivial.
Portanto, para aplicativos com requisitos de tempo real muito altos, é recomendável usar a otimização de cópia zero, que é compatível.
E, como o Chintan mencionou, é multiplataforma, com suporte para OpenGL, OpenCL e Metal como back-ends de GPU.
Por último, mas não menos importante, o otimizador de desvio de ML é de código aberto.
Ele está disponível sob a licença Apache.
Recentemente, o Google disponibilizou o código aberto dele.
Certo, e aqui está o código do 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 você pode ver, ele é bem pequeno e simples.
Assim, você cria o modelo uma vez e o reutiliza em todos os frames.
Então, CompiledModel.create transmite o arquivo .tflite.
Basta especificar que você quer executar na GPU e, em seguida, criar a entrada e o outputBuffers.
Em seguida, no loop principal, em que você está processando cada frame, chame esse model.run transmitindo a entrada e a saída.
Depois de gravar no inputBuffers, chame model.run e leia o outputBuffers.
Ok.
Ah, sim, e se você especificar GPU, ele será executado na GPU.
Se você também especificar CPU e GPU, ele vai tentar executar a GPU.
Se a GPU não estiver disponível por algum motivo, ela vai voltar para a CPU.
Portanto, em alguns casos, o substituto da CPU pode não ser eficiente o suficiente para seu app. É aí que você deve especificar a GPU dessa forma.
O mais comum é ter um substituto de CPU.
Ok.
Então, criamos o app com o LiteRT integrado, que ainda não usa o Google Play Services.
Vou mostrar como usar o LiteRT no Google Play Services.
Há três mudanças: a primeira é a mudança de dependência.
// 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-apiBasta substituir, no arquivo do Gradle ou em qualquer outro lugar, seja qual for o sistema de build que você estiver usando, onde quer que você especifique as dependências do pacote Maven, é isso que você vai mudar.
Remova a dependência litert ou qualquer uma das dependências mais antigas do pacote Maven do TensorFlow Lite e substitua-as por play-services-litert.
Isso também extrai o pacote litert-api.
Se você estiver escrevendo uma camada intermediária que depende do LiteRT, mas não se importa se o ambiente de execução vem do app ou do Google Play Services, basta depender da API LiteRT e usar um ambiente como parâmetro de entrada.
A segunda etapa é o parâmetro de ambiente.
É aí que você fornece a injeção de dependência, essencialmente, para especificar que está usando, que quer usar o LiteRT do Google Play Services.
Portanto, você importa o gms.litert.LiteRt e chama a função de inicialização, transmitindo o contexto, que é sua atividade do 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.Como é uma operação assíncrona, você precisa chamar .await ou fazer com que o restante seja baseado em um callback.
Por fim, depois de ter esse ambiente, basta transmiti-lo sempre que chamar CompiledModel.create.
Isso vai fazer com que ele use o ambiente de execução do LiteRT do Google Play Services.
E é isso.
Isso significa que o restante do app usa as mesmas APIs CompiledModel da API LiteRT.
O restante do código de inferência não muda para usar o Google Play Services.
E é possível fazer essa migração de forma incremental.
Não é necessário fazer tudo de uma vez. É possível migrar um componente por vez.
Se você tem um app grande, faz sentido migrar cada componente que usa o LiteRT e, em seguida, migrar um por um, testando um por um.
A única ressalva é que você só ganha em tamanho, ou seja, a economia de espaço só acontece quando você remove a última dependência do ambiente de execução do pacote.
Se você estiver, a outra ressalva é que não deve misturar objetos entre o LiteRT no Google Play Services e o LiteRT em pacote.
Portanto, se você estiver recebendo tensores, modelos compilados ou interpretadores do LiteRT no Google Play Services, não os transmita para o LiteRT integrado ou vice-versa.
Mas, fora isso, misturar essas coisas funciona muito bem.
Ok.
Isso foi para criar um novo app.
Agora, vou falar sobre como fazer upgrade de um app.
Portanto, talvez você tenha um app que usa a API Interpreter.
Essa é a API TFLite mais antiga, que usa o interpretador como a classe principal.
Esse é o código à esquerda que usa a API Interpreter e, à direita, o novo código da API 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, outputBuffersEntão, você só está mudando TfLite.initialize para LiteRt.initialize, e isso agora retorna um ambiente.
Em seguida, transmita o ambiente para CompiledModel.create.
Essa é uma mudança pequena, sem aumento do APK.
No próximo slide, vamos mostrar como fazer isso com a GPU, que é apenas mais uma opção.
Esse é o código extra necessário para ativar a 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 você pode ver, o código na nova API para ativar a GPU é um pouco mais sim-- sim, mais simples do que o código anterior.
Portanto, a primeira chamada para um setEnableGpu nas opções de inicialização do LiteRT que você transmite para LiteRt.initialize fará com que o código do acelerador de GPU seja carregado no app.
Em seguida, ao criar o modelOptions e transmiti-lo para CompiledModel.create, você especifica qual acelerador será usado para um modelo específico, se quer que outro modelo seja executado apenas na GPU, na GPU com substituição de CPU ou apenas na CPU.
Certo.
Sim, como você pode ver, ativar a GPU é muito mais simples com a nova API.
Então, o que você realmente ganha?
Chintan vai explicar.
Certo.
Certo, obrigado, Fergus.
Então, vamos falar sobre o que tudo isso nos traz, certo?
Lembra que dissemos que íamos criar um app? Vamos ver o que realmente criamos, certo?
Enfim, esse sou eu, e o que fizemos aqui foi usar o Kit de ML para me encontrar. Portanto, a segmentação está sendo feita por uma API pronta para uso, como o Kit de ML.
Então, isso é só para encontrar minha cabeça ali.
Em seguida, o LiteRT usa um modelo semelhante à transferência de estilo para pintar o plano de fundo.
E os outros benefícios, como mencionamos, são que você economiza aproximadamente 8 MB de espaço, tem um ambiente de execução que é usado entre todos os seus apps ou, pelo menos, como o que é compartilhado aqui, recebe atualizações automáticas e também tem uma GPU mais rápida que chega a quase 30 quadros por segundo em algo que precisa ser em tempo real para uma experiência do usuário avançada.
O bom é que você não precisa fazer tudo isso manualmente.
Também lançamos uma nova habilidade no Android: a LiteRT, que atualiza o ML no dispositivo em minutos.
Com isso, você pode fazer algumas coisas: atualizar um app, criar um novo ou atualizar seu app para usar essa nova integração do Google Play Services.
Então, tudo isso está disponível.
O link está no slide, no GitHub e também vai aparecer na nossa documentação e no nosso blog.
E sim, isso também deve ser útil para quem quer fazer a mudança em breve.
Então, Fergus vai nos dizer para onde isso vai em seguida.
Por isso, estamos comprometidos com a IA no dispositivo com o LiteRT.
Continuamos investindo significativamente na melhoria da aceleração de GPU e na cobertura de modelos, além de fornecer atualizações regulares para o LiteRT 2.x, tanto para o LiteRT de código aberto quanto para o pacote Maven do LiteRT no Google Play Services.
E também vamos continuar oferecendo compatibilidade com versões anteriores.
O ambiente de execução do Google Play Services vai continuar oferecendo suporte a apps criados com SDKs mais antigos.
Sim.
Isso é muito importante para nossos usuários e para nós.
Os SDKs do LiteRT 1.x estão em modo de manutenção, então só recebem correções de segurança críticas.
A NNAPI, que foi descontinuada em 2024, será removida, provavelmente a partir de 2027.
Portanto, se você usa a NNAPI, mude para a aceleração de GPU ou NPU com o LiteRT integrado.
Ok.
Sim.
Portanto, quanto antes você migrar para a versão 2.x e o CompiledModel, menos trabalho terá depois.
Então, três coisas para lembrar.
Então, crie.
Comece com o Kit de ML. Se ele já fizer o que você precisa, ótimo.
Caso contrário, use o LiteRT para seus modelos personalizados.
Faça upgrade para o LiteRT no Google Play Services para economizar espaço no APK e usar o ambiente de execução compartilhado.
Considere usar a API CompiledModel para uma inferência de GPU mais rápida e simples.
Sim.
Tudo está documentado no site de documentação do LiteRT no AI Edge, no URL indicado.
Então, sim.
Agradecemos sua participação e estamos ansiosos para ver o que vocês vão criar.
// 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 -> … }
}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")# 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")// 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()
}// 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// 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.// 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// 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)