Delegados do TensorFlow Lite

Os delegados permitem a aceleração de hardware dos modelos do TensorFlow Lite usando aceleradores no dispositivo, como a GPU e o processador de sinal digital (DSP).

Por padrão, o TensorFlow Lite utiliza kernels de CPU otimizados para o conjunto de instruções ARM Neon. No entanto, a CPU é um processador multiuso que não é necessariamente otimizado para a aritmética pesada normalmente encontrada em modelos de machine learning (por exemplo, a matemática de matriz envolvida na convolução e em camadas densas).

Por outro lado, a maioria dos smartphones modernos contém chips que são melhores para lidar com essas operações pesadas. Usá-los para operações de rede neural oferece grandes benefícios em termos de latência e eficiência energética. Por exemplo, as GPUs podem fornecer latência de até 5xaceleração.

Cada um desses aceleradores tem APIs associadas que permitem cálculos personalizados, como OpenCL ou OpenGL ES para GPUs de dispositivos móveis. Normalmente, você teria que escrever muito código personalizado para executar uma rede neural por meio dessas interfaces. As coisas ficam ainda mais complicadas quando você considera que cada acelerador tem seus prós e contras e não pode executar todas as operações em uma rede neural. A API Delegate do TensorFlow Lite resolve esse problema atuando como uma ponte entre o ambiente de execução do TFLite e essas APIs de nível inferior.

ambiente de execução com delegados

Como escolher um delegado

O TensorFlow Lite oferece suporte a vários delegados, cada um otimizado para determinadas plataformas e tipos específicos de modelos. Normalmente, haverá vários delegados aplicáveis ao seu caso de uso, dependendo de dois critérios principais: a plataforma (Android ou iOS?) segmentada e o tipo de modelo (ponto flutuante ou quantizado?) que você está tentando acelerar.

Delegados por plataforma

Multiplataforma (Android e iOS)

  • Delegado de GPU: pode ser usado no Android e no iOS. Ele é otimizado para executar modelos flutuantes de 32 e 16 bits em que uma GPU está disponível. Ele também oferece suporte a modelos quantizados de 8 bits e oferece desempenho de GPU no mesmo nível das versões flutuantes. Para mais detalhes sobre o delegado de GPU, consulte TensorFlow Lite na GPU.

iOS

  • Delegado do Core ML para iPhones e iPads mais recentes: para iPhones e iPads mais recentes em que o Neural Engine está disponível, é possível usar o delegado do Core ML para acelerar a inferência em modelos de ponto flutuante de 32 ou 16 bits. O Neural Engine está disponível para dispositivos móveis Apple com SoC A12 ou superior. Para uma visão geral do delegado do Core ML e instruções detalhadas, consulte delegado de ML do TensorFlow Lite Core.

Delegados por tipo de modelo

Cada acelerador é projetado com uma certa largura de bits de dados em mente. Se você fornecer um modelo de ponto flutuante a um delegado que tenha suporte apenas para operações quantizadas de 8 bits, ele rejeitará todas as operações, e o modelo será executado inteiramente na CPU. Para evitar essas surpresas, veja na tabela abaixo uma visão geral do suporte delegado com base no tipo de modelo:

Tipo de modelo GPU CoreML
Ponto flutuante (32 bits) Sim Sim
Quantização float16 pós-treinamento Sim Sim
Quantização de intervalo dinâmico pós-treinamento Sim Não
Quantização de números inteiros pós-treinamento Sim Não
Treinamento com reconhecimento de quantização Sim Não

Validando o desempenho

As informações nesta seção servem como uma diretriz básica para selecionar os delegados que podem melhorar seu aplicativo. No entanto, é importante observar que cada delegado tem um conjunto predefinido de operações com suporte e pode ter um desempenho diferente dependendo do modelo e do dispositivo. Portanto, é recomendável fazer comparações para avaliar a utilidade de um delegado para suas necessidades. Isso também ajuda a justificar o aumento do tamanho do binário associado à anexação de um delegado ao ambiente de execução do TensorFlow Lite.

O TensorFlow Lite tem ferramentas abrangentes de avaliação de desempenho e precisão que podem ajudar os desenvolvedores a usar delegados no aplicativo. Essas ferramentas serão abordadas na próxima seção.

Ferramentas para avaliação

Latência e consumo de memória

A ferramenta de comparação do TensorFlow Lite pode ser usada com parâmetros adequados para estimar o desempenho do modelo, incluindo latência média de inferência, sobrecarga de inicialização, consumo de memória etc. Essa ferramenta é compatível com várias sinalizações para descobrir a melhor configuração de delegado para seu modelo. Por exemplo, --gpu_backend=gl pode ser especificado com --use_gpu para medir a execução da GPU com o OpenGL. A lista completa de parâmetros delegados compatíveis está definida na documentação detalhada.

Confira um exemplo de execução para um modelo quantizado com GPU via adb:

adb shell /data/local/tmp/benchmark_model \
  --graph=/data/local/tmp/mobilenet_v1_224_quant.tflite \
  --use_gpu=true

Você pode fazer o download da versão pré-criada dessa ferramenta para Android de arquitetura ARM de 64 bits neste link (mais detalhes).

Precisão e correção

Os delegados geralmente executam cálculos com uma precisão diferente dos dele na CPU. Como resultado, há uma compensação de precisão (geralmente pequena) associada ao uso de um delegado para aceleração de hardware. Isso nem sempre é verdade. Por exemplo, como a GPU usa a precisão de ponto flutuante para executar modelos quantizados, pode haver uma leve melhoria na precisão (por exemplo, menos de 1% de melhoria no top 5 na classificação de imagens ILSVRC).

O TensorFlow Lite tem dois tipos de ferramentas para medir a precisão do comportamento de um delegado em um determinado modelo: Baseado em tarefas e Task-Agnostic. Todas as ferramentas descritas nesta seção são compatíveis com os parâmetros de delegação avançado usados pela ferramenta de comparação da seção anterior. Observe que as subseções abaixo se concentram na avaliação do delegado em vez de na avaliação do modelo (o modelo em si é bom para a tarefa?).

Avaliação baseada em tarefas

O TensorFlow Lite tem ferramentas para avaliar a exatidão em duas tarefas baseadas em imagem:

Os binários pré-criados dessas ferramentas (arquitetura Android com ARM de 64 bits) e a documentação podem ser encontrados aqui:

O exemplo abaixo demonstra a avaliação da classificação de imagens com GPU em um Pixel 4:

adb shell /data/local/tmp/run_eval \
  --model_file=/data/local/tmp/mobilenet_quant_v1_224.tflite \
  --ground_truth_images_path=/data/local/tmp/ilsvrc_images \
  --ground_truth_labels=/data/local/tmp/ilsvrc_validation_labels.txt \
  --model_output_labels=/data/local/tmp/model_output_labels.txt \
  --output_file_path=/data/local/tmp/accuracy_output.txt \
  --num_images=0 # Run on all images. \
  --use_gpu=true

O resultado esperado é uma lista de métricas Top-K de 1 a 10:

Top-1 Accuracy: 0.733333
Top-2 Accuracy: 0.826667
Top-3 Accuracy: 0.856667
Top-4 Accuracy: 0.87
Top-5 Accuracy: 0.89
Top-6 Accuracy: 0.903333
Top-7 Accuracy: 0.906667
Top-8 Accuracy: 0.913333
Top-9 Accuracy: 0.92
Top-10 Accuracy: 0.923333

Avaliação independente de tarefa

Para tarefas em que não há uma ferramenta de avaliação estabelecida no dispositivo ou se você estiver testando modelos personalizados, o TensorFlow Lite tem a ferramenta Inference Diff. (Binário de arquitetura binária ARM para Android de 64 bits aqui)

A comparação de inferências compara a execução do TensorFlow Lite (em termos de latência e desvio do valor de saída) em duas configurações:

  • Inferência de CPU com linha de execução única
  • Inferência definida pelo usuário, definida por estes parâmetros

Para isso, a ferramenta gera dados gaussianos aleatórios e os transmite por dois interpretadores do TFLite: um executando kernels de CPU de linha de execução única e o outro parametrizado pelos argumentos do usuário.

Ele mede a latência de ambos, bem como a diferença absoluta entre os tensores de saída de cada intérprete, por elemento.

Para um modelo com um único tensor de saída, a saída pode ter a seguinte aparência:

Num evaluation runs: 50
Reference run latency: avg=84364.2(us), std_dev=12525(us)
Test run latency: avg=7281.64(us), std_dev=2089(us)
OutputDiff[0]: avg_error=1.96277e-05, std_dev=6.95767e-06

Isso significa que, para o tensor de saída no índice 0, os elementos da saída da CPU são diferentes da saída do delegado por uma média de 1.96e-05.

Interpretar esses números requer um conhecimento mais profundo do modelo e do significado de cada tensor de saída. Se for uma regressão simples que determina algum tipo de pontuação ou incorporação, a diferença precisa ser baixa. Caso contrário, será um erro do delegado. No entanto, saídas como a "classe de detecção" dos modelos SSD são um pouco mais difíceis de interpretar. Por exemplo, isso pode mostrar uma diferença ao usar essa ferramenta, mas isso pode não significar algo realmente errado com o delegado: considere duas classes (falsas): "TV (ID: 10)", "Monitor (ID:20)": se um delegado estiver um pouco fora da verdade e mostrar monitor em vez de TV, a diferença de saída desse tensor pode ser de 20 a 10 =