Delegados de GPU para TensorFlow Lite

O uso de unidades de processamento gráfico (GPUs) para executar seus modelos de aprendizado de máquina (ML) pode melhorar drasticamente o desempenho do seu modelo e a experiência do usuário de seus aplicativos habilitados para ML. O TensorFlow Lite permite o uso de GPUs e outros processadores especializados por meio de drivers de hardware chamados delegados . Habilitar o uso de GPUs com seus aplicativos TensorFlow Lite ML pode oferecer os seguintes benefícios:

  • Velocidade – as GPUs são construídas para alto rendimento de cargas de trabalho massivamente paralelas. Esse design os torna adequados para redes neurais profundas, que consistem em um grande número de operadores, cada um trabalhando em tensores de entrada que podem ser processados ​​em paralelo, o que normalmente resulta em menor latência. Na melhor das hipóteses, executar seu modelo em uma GPU pode ser rápido o suficiente para permitir aplicativos em tempo real que não eram possíveis anteriormente.
  • Eficiência energética – as GPUs realizam cálculos de ML de maneira muito eficiente e otimizada, normalmente consumindo menos energia e gerando menos calor do que a mesma tarefa executada nas CPUs.

Este documento fornece uma visão geral do suporte a GPUs no TensorFlow Lite e alguns usos avançados para processadores GPU. Para obter informações mais específicas sobre a implementação do suporte de GPU em plataformas específicas, consulte os seguintes guias:

Suporte a operações de GPU ML

Existem algumas limitações sobre quais operações, ou ops , do TensorFlow ML podem ser aceleradas pelo delegado de GPU do TensorFlow Lite. O delegado oferece suporte às seguintes operações com precisão flutuante de 16 e 32 bits:

  • ADD
  • AVERAGE_POOL_2D
  • CONCATENATION
  • CONV_2D
  • DEPTHWISE_CONV_2D v1-2
  • EXP
  • FULLY_CONNECTED
  • LOGICAL_AND
  • LOGISTIC
  • LSTM v2 (Basic LSTM only)
  • MAX_POOL_2D
  • MAXIMUM
  • MINIMUM
  • MUL
  • PAD
  • PRELU
  • RELU
  • RELU6
  • RESHAPE
  • RESIZE_BILINEAR v1-3
  • SOFTMAX
  • STRIDED_SLICE
  • SUB
  • TRANSPOSE_CONV

Por padrão, todas as operações são suportadas apenas na versão 1. Habilitar o suporte à quantização habilita as versões apropriadas, por exemplo, ADD v2.

Solução de problemas de suporte de GPU

Se algumas das operações não forem suportadas pelo delegado da GPU, a estrutura executará apenas uma parte do gráfico na GPU e o restante na CPU. Devido ao alto custo da sincronização CPU/GPU, um modo de execução dividido como esse geralmente resulta em desempenho mais lento do que quando toda a rede é executada apenas na CPU. Neste caso, a aplicação gera avisos, como:

WARNING: op code #42 cannot be handled by this delegate.

Não há retorno de chamada para falhas desse tipo, pois não se trata de uma falha real em tempo de execução. Ao testar a execução do seu modelo com o delegado da GPU, você deve estar atento a esses avisos. Um grande número desses avisos pode indicar que seu modelo não é o mais adequado para uso na aceleração de GPU e pode exigir a refatoração do modelo.

Modelos de exemplo

Os modelos de exemplo a seguir foram criados para aproveitar a aceleração de GPU com o TensorFlow Lite e são fornecidos para referência e teste:

Otimizando para GPUs

As técnicas a seguir podem ajudar você a obter melhor desempenho ao executar modelos em hardware de GPU usando o delegado de GPU do TensorFlow Lite:

  • Operações de remodelação - Algumas operações que são rápidas em uma CPU podem ter um custo alto para a GPU em dispositivos móveis. As operações de remodelação são particularmente caras de executar, incluindo BATCH_TO_SPACE , SPACE_TO_BATCH , SPACE_TO_DEPTH e assim por diante. Você deve examinar atentamente o uso de operações de remodelação e considerar que elas podem ter sido aplicadas apenas para explorar dados ou para iterações iniciais do seu modelo. Removê-los pode melhorar significativamente o desempenho.

  • Canais de dados de imagem - Na GPU, os dados do tensor são divididos em 4 canais e, portanto, um cálculo em um tensor com a forma [B,H,W,5] tem o mesmo desempenho em um tensor de forma [B,H,W,8] , mas significativamente pior que [B,H,W,4] . Se o hardware da câmera que você está usando suporta quadros de imagem em RGBA, alimentar essa entrada de 4 canais é significativamente mais rápido, pois evita uma cópia de memória de RGB de 3 canais para RGBX de 4 canais.

  • Modelos otimizados para dispositivos móveis – Para obter melhor desempenho, considere treinar novamente seu classificador com uma arquitetura de rede otimizada para dispositivos móveis. A otimização para inferência no dispositivo pode reduzir drasticamente a latência e o consumo de energia aproveitando os recursos de hardware móvel.

Suporte avançado para GPU

Você pode usar técnicas avançadas adicionais com processamento de GPU para permitir um desempenho ainda melhor para seus modelos, incluindo quantização e serialização. As seções a seguir descrevem essas técnicas com mais detalhes.

Usando modelos quantizados

Esta seção explica como o delegado GPU acelera modelos quantizados de 8 bits, incluindo o seguinte:

Para otimizar o desempenho, use modelos que tenham tensores de entrada e saída de ponto flutuante.

Como é que isso funciona?

Como o backend da GPU suporta apenas execução de ponto flutuante, executamos modelos quantizados fornecendo uma 'visão de ponto flutuante' do modelo original. Em alto nível, isso envolve as seguintes etapas:

  • Tensores constantes (como pesos/vieses) são desquantizados uma vez na memória da GPU. Esta operação acontece quando o delegado está habilitado para TensorFlow Lite.

  • As entradas e saídas do programa GPU, se quantizadas em 8 bits, são desquantizadas e quantizadas (respectivamente) para cada inferência. Esta operação é feita na CPU usando kernels otimizados do TensorFlow Lite.

  • Simuladores de quantização são inseridos entre as operações para imitar o comportamento quantizado. Essa abordagem é necessária para modelos em que as operações esperam que as ativações sigam os limites aprendidos durante a quantização.

Para obter informações sobre como ativar esse recurso com o delegado da GPU, consulte o seguinte:

Reduzindo o tempo de inicialização com serialização

O recurso de delegação de GPU permite carregar código de kernel pré-compilado e dados de modelo serializados e salvos em disco de execuções anteriores. Essa abordagem evita a recompilação e pode reduzir o tempo de inicialização em até 90%. Essa melhoria é alcançada através da troca de espaço em disco por economia de tempo. Você pode habilitar esse recurso com algumas opções de configuração, conforme mostrado nos exemplos de código a seguir:

C++

    TfLiteGpuDelegateOptionsV2 options = TfLiteGpuDelegateOptionsV2Default();
    options.experimental_flags |= TFLITE_GPU_EXPERIMENTAL_FLAGS_ENABLE_SERIALIZATION;
    options.serialization_dir = kTmpDir;
    options.model_token = kModelToken;

    auto* delegate = TfLiteGpuDelegateV2Create(options);
    if (interpreter->ModifyGraphWithDelegate(delegate) != kTfLiteOk) return false;
      

Java

    GpuDelegate delegate = new GpuDelegate(
      new GpuDelegate.Options().setSerializationParams(
        /* serializationDir= */ serializationDir,
        /* modelToken= */ modelToken));

    Interpreter.Options options = (new Interpreter.Options()).addDelegate(delegate);
      

Ao usar o recurso de serialização, certifique-se de que seu código esteja em conformidade com estas regras de implementação:

  • Armazene os dados de serialização em um diretório que não seja acessível a outros aplicativos. Em dispositivos Android, use getCodeCacheDir() que aponta para um local privado do aplicativo atual.
  • O token do modelo deve ser exclusivo para o dispositivo do modelo específico. Você pode calcular um token de modelo gerando uma impressão digital a partir dos dados do modelo usando bibliotecas como farmhash::Fingerprint64 .