Delegados do TensorFlow Lite

Introdução

Os delegados permitem a aceleração de hardware dos modelos do TensorFlow Lite aproveitando aceleradores no dispositivo, como GPU e 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 aprendizado de máquina (por exemplo, a matemática matricial envolvida na convolução e nas 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 possui APIs associadas que permitem cálculos personalizados, como OpenCL ou OpenGL ES para GPU móvel e 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 agindo 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 delegados, 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

Plataforma cruzada (Android e iOS)

  • Delegado de GPU - O delegado de GPU pode ser usado tanto no Android quanto no iOS. Ele é otimizado para executar modelos baseados em float de 32 e 16 bits onde uma GPU está disponível. Ele também oferece suporte a modelos quantizados de 8 bits e fornece desempenho de GPU equivalente a suas versões flutuantes. Para obter detalhes sobre o delegado de GPU, consulte TensorFlow Lite em GPU . Para obter tutoriais passo a passo sobre como usar o delegado de GPU com Android e iOS, consulte Tutorial do 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 em 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 do TensorFlow Lite Hexagon para obter mais detalhes.

iOS

  • Delegado Core ML para iPhones e iPads mais recentes – Para iPhones e iPads mais recentes onde o Neural Engine está disponível, você pode usar o delegado Core ML para acelerar a inferência para modelos de ponto flutuante de 32 ou 16 bits. O Neural Engine está disponível em dispositivos móveis Apple com SoC A12 ou superior. Para obter uma visão geral do delegado Core ML e instruções passo a passo, consulte Delegado 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 a um delegado que suporta 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 tais surpresas, a tabela abaixo fornece uma visão geral do suporte aos delegados 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 com reconhecimento de quantização Sim Sim Sim Não

Validando o desempenho

As informações nesta seção funcionam como uma orientação aproximada para selecionar os delegados que poderiam melhorar sua inscrição. Porém, é importante observar que cada delegado possui um conjunto predefinido de operações que suporta e pode executar de forma 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ê realize alguns benchmarking para avaliar a utilidade de um delegado para suas necessidades. Isso também ajuda a justificar o aumento do tamanho binário associado à anexação de um delegado ao tempo de execução do TensorFlow Lite.

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

Ferramentas para avaliação

Latência e consumo 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. Esta 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 está 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 seus equivalentes na CPU. Como resultado, há uma compensação de precisão (geralmente pequena) 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 ligeira melhoria na precisão (por exemplo, <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 para um determinado modelo: baseado em tarefas e independente de tarefas . Todas as ferramentas descritas nesta seção suportam os parâmetros avançados de delegação usados ​​pela ferramenta de benchmarking da seção anterior. Observe que as subseções abaixo se concentram na avaliação do delegado (O delegado tem o mesmo desempenho 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 possui ferramentas para avaliar a correção em duas tarefas baseadas em imagens:

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 imagens 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

O resultado esperado é uma lista das principais métricas 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 Tarefas

Para tarefas em que não existe uma ferramenta de avaliação estabelecida no dispositivo ou se você estiver experimentando 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 estes parâmetros

Para fazer isso, a ferramenta gera dados gaussianos aleatórios e os passa por dois interpretadores TFLite - um executando kernels de CPU de thread único 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 intérprete, 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 a interpretação desses números requer um conhecimento mais profundo do modelo e do 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 do delegado). No entanto, resultados como a 'classe de detecção' dos modelos SSD são um pouco mais difíceis de interpretar. Por exemplo, pode haver 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 este tensor pode ser algo tão alto quanto 20-10 = 10.