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 de 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 driver de hardware chamado delegados . Habilitar o uso de GPUs com seus aplicativos TensorFlow Lite ML pode fornecer os seguintes benefícios:

  • Velocidade - GPUs são construídas para alta taxa de transferência 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. No melhor cenário, executar seu modelo em uma GPU pode ser rápido o suficiente para habilitar aplicativos em tempo real que antes não eram possíveis.
  • Eficiência de energia - 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 de GPU. Para obter informações mais específicas sobre como implementar o suporte a GPU em plataformas específicas, consulte os seguintes guias:

Suporte a operações GPU ML

Existem algumas limitações para quais operações do TensorFlow ML, ou ops , podem ser aceleradas pelo delegado da GPU do TensorFlow Lite. O delegado oferece suporte às seguintes operações em precisão flutuante de 16 bits 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. Ativar o suporte de quantização ativa 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 a parte restante na CPU. Devido ao alto custo da sincronização CPU/GPU, um modo de execução dividida como esse geralmente resulta em desempenho mais lento do que quando toda a rede é executada apenas na CPU. Nesse caso, o aplicativo gera um aviso, como:

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

Não há retorno de chamada para falhas desse tipo, pois não é uma falha de tempo de execução real. Ao testar a execução de seu modelo com o delegado de GPU, você deve estar alerta para 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 da GPU com o TensorFlow Lite e são fornecidos para referência e teste:

Otimizando para GPUs

As técnicas a seguir podem ajudá-lo a obter melhor desempenho ao executar modelos em hardware de GPU usando o delegado de GPU do TensorFlow Lite:

  • Operações de reformulaçã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 reformulação são particularmente caras de executar, incluindo BATCH_TO_SPACE , SPACE_TO_BATCH , SPACE_TO_DEPTH e assim por diante. Você deve examinar de perto o uso de operações de remodelação e considerar que pode ter sido aplicado apenas para explorar dados ou para iterações iniciais de 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] executa aproximadamente o mesmo em um tensor da forma [B,H,W,8] , mas significativamente pior do que [B,H,W,4] . Se o hardware da câmera que você está usando suporta quadros de imagem em RGBA, a alimentação dessa entrada de 4 canais é significativamente mais rápida, 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 o 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 de 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 GPU delegado 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 back-end da GPU suporta apenas a execução de ponto flutuante, executamos modelos quantizados, fornecendo uma 'visão de ponto flutuante' do modelo original. Em um alto nível, isso envolve as seguintes etapas:

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

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

  • Os 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 habilitar esse recurso com o delegado de GPU, consulte o seguinte:

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

O recurso de delegação de GPU permite que você carregue a partir de código de kernel pré-compilado e modele dados 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 é obtida trocando 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 inacessível a outros aplicativos. Em dispositivos Android, use getCodeCacheDir() que aponta para um local privado para o aplicativo atual.
  • O token de modelo deve ser exclusivo para o dispositivo do modelo específico. Você pode calcular um token de modelo gerando uma impressão digital dos dados do modelo usando bibliotecas como farmhash::Fingerprint64 .