Delegados do TensorFlow Lite

Introdução

Os delegados habilitam a aceleração de hardware dos modelos do TensorFlow Lite aproveitando os 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 multifuncional que não é necessariamente otimizado para a aritmética pesada normalmente encontrada em modelos de Machine Learning (por exemplo, a matemática da matriz envolvida em convolução e camadas densas).

Por outro lado, a maioria dos telefones celulares modernos contém chips que são melhores para lidar com essas operações pesadas. Utilizá-los para operações de rede neural oferece enormes benefícios em termos de latência e eficiência de energia. Por exemplo, as GPUs podem fornecer uma aceleração de até 5x na latência, enquanto o Qualcomm® Hexagon DSP demonstrou reduzir o consumo de energia em até 75% em nossos experimentos.

Cada um desses aceleradores tem APIs associadas que permitem cálculos personalizados, como OpenCL ou OpenGL ES para GPU móvel e o Qualcomm® Hexagon SDK para DSP. 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 tempo de execução do TFLite e essas APIs de nível inferior.

tempo de execução com delegados

Escolhendo um Delegado

O TensorFlow Lite oferece suporte a vários representantes, cada um deles 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?) que você segmenta e o tipo de modelo (ponto flutuante ou quantizado?) que você está tentando acelerar .

Delegados por plataforma

Multiplataforma (Android e iOS)

  • Delegado de GPU - O delegado de GPU pode ser usado no Android e no iOS. Ele é otimizado para executar modelos baseados em float de 32 bits e 16 bits onde uma GPU está disponível. Ele também suporta modelos quantizados de 8 bits e fornece desempenho de GPU no mesmo nível de suas versões flutuantes. Para obter detalhes sobre o delegado da GPU, consulte TensorFlow Lite na GPU . Para obter tutoriais passo a passo sobre como usar o delegado de GPU com Android e iOS, consulte Tutorial de delegado de GPU do TensorFlow Lite .

Android

  • Delegado NNAPI para dispositivos Android mais recentes - O delegado NNAPI pode ser usado para acelerar modelos em dispositivos Android com GPU, DSP e/ou NPU disponíveis. Está disponível no Android 8.1 (API 27+) ou superior. Para obter uma visão geral do delegado NNAPI, instruções passo a passo e práticas recomendadas, consulte Delegado NNAPI do TensorFlow Lite .
  • Delegado Hexagon para dispositivos Android mais antigos - O delegado Hexagon pode ser usado para acelerar modelos em dispositivos Android com Qualcomm Hexagon DSP. Ele pode ser usado em dispositivos que executam versões mais antigas do Android que não suportam NNAPI. Consulte Delegado hexágono do TensorFlow Lite para obter mais detalhes.

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, você pode usar o delegado do Core ML para acelerar a inferência para modelos de ponto flutuante de 32 ou 16 bits. O Neural Engine está disponível para dispositivos móveis da Apple com SoC A12 ou superior. Para obter uma visão geral do delegado do Core ML e instruções passo a passo, consulte Delegado do TensorFlow Lite Core ML .

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 para um delegado que suporte apenas operações quantizadas de 8 bits (como o delegado Hexagon ), ele rejeitará todas as suas operações e o modelo será executado inteiramente na CPU. Para evitar essas surpresas, a tabela abaixo fornece uma visão geral do suporte delegado com base no tipo de modelo:

Tipo de modelo GPU NNAPI Hexágono CoreML
Ponto flutuante (32 bits) Sim Sim Não Sim
Quantização float16 pós-treinamento Sim Não Não Sim
Quantização de faixa dinâmica pós-treinamento Sim Sim Não Não
Quantização inteira pós-treinamento Sim Sim Sim Não
Treinamento de quantização Sim Sim Sim Não

Validando o desempenho

As informações nesta seção funcionam como uma diretriz aproximada para selecionar os delegados que podem melhorar sua inscrição. No entanto, é importante observar que cada delegado tem um conjunto predefinido de operações que suporta e pode executar de maneira diferente dependendo do modelo e do dispositivo; por exemplo, o delegado NNAPI pode optar por usar o Edge-TPU do Google em um telefone Pixel enquanto utiliza um DSP em outro dispositivo. Portanto, geralmente é recomendado que você execute alguns benchmarks para avaliar a utilidade de um delegado para suas necessidades. Isso também ajuda a justificar o aumento de tamanho binário associado à anexação de um delegado ao tempo de execução do TensorFlow Lite.

O TensorFlow Lite possui ferramentas abrangentes de avaliação de desempenho e precisão que podem capacitar os desenvolvedores a confiar no uso de representantes em seus aplicativos. Essas ferramentas são discutidas na próxima seção.

Ferramentas para avaliação

Latência e pegada de memória

A ferramenta de benchmark 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 oferece suporte a vários sinalizadores 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 OpenGL. A lista completa de parâmetros delegados suportados é definida na documentação detalhada .

Aqui está um exemplo executado 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 baixar a versão pré-construída desta ferramenta para Android, arquitetura ARM de 64 bits aqui ( mais detalhes ).

Precisão e correção

Os delegados geralmente realizam cálculos com uma precisão diferente de suas contrapartes da CPU. Como resultado, há uma compensação de precisão (geralmente menor) associada à utilização de um delegado para aceleração de hardware. Observe que isso nem sempre é verdade; por exemplo, como a GPU usa precisão de ponto flutuante para executar modelos quantizados, pode haver uma pequena melhoria na precisão (por exemplo, <1% de melhoria no Top-5 na classificação de imagem ILSVRC).

O TensorFlow Lite tem dois tipos de ferramentas para medir a precisão do comportamento de um delegado para um determinado modelo: baseado em tarefas e independente de tarefas . Todas as ferramentas descritas nesta seção suportam os parâmetros de delegação avançada usados ​​pela ferramenta de benchmarking da seção anterior. Observe que as subseções abaixo se concentram na avaliação do delegado (o delegado executa o mesmo que a CPU?) em vez da 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:

Binários pré-construídos dessas ferramentas (Android, arquitetura ARM de 64 bits), juntamente com a documentação, podem ser encontrados aqui:

O exemplo abaixo demonstra a avaliação de classificação de imagem com NNAPI utilizando Edge-TPU do Google 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_nnapi=true \
  --nnapi_accelerator_name=google-edgetpu

A saída esperada é 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 agnóstica 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 . (Android, binário de arquitetura binária ARM de 64 bits aqui )

O Inference Diff 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 de thread único
  • Inferência definida pelo usuário - definida por esses parâmetros

Para isso, a ferramenta gera dados gaussianos aleatórios e os passa por dois intérpretes TFLite - um executando kernels de CPU single-thread e 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 Interpretador, por elemento.

Para um modelo com um único tensor de saída, a saída pode ser assim:

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

O que isso significa é que para o tensor de saída no índice 0 , os elementos da saída da CPU diferem da saída do delegado em uma média de 1.96e-05 .

Observe que interpretar esses números requer um conhecimento mais profundo do modelo e o que cada tensor de saída significa. Se for uma regressão simples que determina algum tipo de pontuação ou incorporação, a diferença deve ser baixa (caso contrário, é um erro com o delegado). No entanto, saídas como a de 'classe de detecção' dos modelos SSD são um pouco mais difíceis de interpretar. Por exemplo, pode mostrar uma diferença usando esta 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 está um pouco fora da verdade dourada e mostra monitor em vez de TV, a diferença de saída para esse tensor pode ser algo tão alto quanto 20-10 = 10.