Path: blob/master/site/pt-br/lite/models/convert/operation_fusion.md
25118 views
Combinação de operações do TensorFlow
Visão geral
Esta etapa descreve o design e as etapas necessárias para converter operações compostas no TensorFlow em fused operations (operações combinadas) no TensorFlow Lite. Essa infraestrutura tem uma finalidade geral e oferece suporte à conversão de qualquer operação composta no TensorFlow em uma operação combinada correspondente no TensorFlow Lite.
Um exemplo de uso dessa infraestrutura é a combinação de operações de RNN do TensorFlow no TensorFlow Lite, conforme detalhado aqui.
O que são operações combinadas
As operações do TensorFlow podem ser primitivas, como tf.add, ou podem ser compostas a partir de outras operações primitivas, como tf.einsum. Uma operação primitiva é exibida como um único nó no grafo do TensorFlow, enquanto uma operação composta é uma coleção de nós no grafo do TensorFlow. Executar uma operação composta é equivalente a executar cada uma de suas operações primitivas.
Uma operação combinada corresponde a uma única operação que agrupa toda a computação realizada por cada operação primitiva dentro da operação composta correspondente.
Vantagens das operações combinadas
As operações combinadas existem para maximizar o desempenho das implementações de kernel subjacentes por meio da otimização das computações gerais e da redução do volume de memória. Isso traz muitas vantagens, especialmente para cargas de trabalho de inferência de baixa latência e para plataformas móveis com restrição de recursos.
As operações combinadas também oferecem uma interface de alto nível para definir transformações complexas, como quantização, que seriam impraticáveis ou muito difíceis de fazer em um nível mais granular.
O TensorFlow Lite tem diversas instâncias de operações combinadas pelos motivos indicados acima. Geralmente, essas operações combinadas correspondem a operações compostas no programa fonte do TensorFlow. Exemplos de operações compostas no TensorFlow que são implementadas como uma única operação combinada no TensorFlow Lite incluem diversas operações de RNN, como LSTM de sequência unidirecional ou bidirecional, convolução (conv2d, bias add, relu), totalmente conectadas (matmul, bias add, relu) e muitas outras. No TensorFlow Lite, a quantização de LSTM só é implementada nas operações de LSTM combinadas, no momento.
Desafios das operações combinadas
Converter operações compostas do TensorFlow em operações combinadas do TensorFlow Lite é um problema difícil, pois:
As operações compostas são representadas no grafo do TensorFlow como um conjunto de operações primitivas sem uma fronteira bem definida. Pode ser desafiador identificar (por exemplo, pela correspondência de padrões) o subgrafo correspondente a uma operação composta.
Pode haver mais de uma implementação do TensorFlow usando uma operação combinada do TensorFlow Lite. Por exemplo: existem diversas implementações de LSTM no TensorFlow (Keras, Babelfish/lingvo, etc.), e cada uma delas é composta por diferentes operações primitivas, mas todas podem ser convertidas na mesma operação de LSTM combinada no TensorFlow Lite.
Portanto, a conversão de operações combinadas se mostrou bastante desafiadora.
Como converter uma operação composta em uma operação personalizada do TF Lite (recomendado)
Encapsule a operação composta em uma tf.function
Em diversos casos, uma parte do modelo pode ser mapeada em uma única operação no TF Lite, o que pode ajudar com o desempenho ao criar uma implementação otimizada de operações específicas. Para poder criar uma operação combinada no TF Lite, identifique a parte do grafo que representa uma operação combinada e encapsule-a em uma tf.function
com o atributo "experimental_implements" para uma tf.function
, que tem o atributo tfl_fusable_op
com valor true
. Se a operação personalizada aceitar atributos, passe-os como parte do mesmo "experimental_implements".
Exemplo:
Você não precisa definir allow_custom_ops
no conversor, pois o atributo tfl_fusable_op
já pressupõe isso.
Implemente a operação personalizada e registre no interpretador do TFLite
Implemente a operação combinada como uma operação personalizada do TF Lite – confira as instruções.
O nome para registrar a operação deve ser similar ao nome especificado no atributo name
na assinatura implements.
Veja um exemplo dessa operação:
Como converter uma operação composta em uma combinada (avançado)
Veja abaixo a arquitetura geral para converter operações compostas do TensorFlow em operações combinadas do TensorFlow Lite.
Encapsule a operação composta em uma tf.function
No código-fonte do modelo do TensorFlow, identifique e abstraia a operação personalizada em uma tf.function
com a anotação de função experimental_implements. Confira um exemplo de pesquisa de embedding. A função define a interface, e seus argumentos devem ser usados para implementar a lógica de conversão.
Escreva o código de conversão
O código de conversão é escrito para cada interface da função com a anotação implements
. Confira um exemplo de combinação para pesquisa de embedding. Conceitualmente, o código de conversão substitui a implementação composta dessa interface pela combinada.
Na etapa prepare-composite-functions "preparar funções compostas", adicione seu código de conversão.
Em casos mais avançados, é possível implementar transformações complexas dos operandos da operação composta para derivar os operandos da operação combinada. Confira o código de conversão de LSTM do Keras como exemplo.
Converta para o TensorFlow Lite
Use a API TFLiteConverter.from_saved_model para converter para o TensorFlow Lite.
Nos bastidores
Agora vamos descrever os detalhes de alto nível do design geral da conversão em operações combinadas no TensorFlow Lite.
Como compor operações no TensorFlow
Ao usar tf.function
com o atributo de função experimental_implements, os usuários podem compor explicitamente novas operações usando as operações primitivas do TensorFlow e especificar a interface que a operação composta relevante implementa. Isso é muito útil, pois:
Fornece uma fronteira bem definida para a operação composta no grafo do TensorFlow subjacente.
Especifica explicitamente a interface que essa operação implementa. Os argumentos de
tf.function
correspondem aos argumentos dessa interface.
Para fins de exemplo, vamos considerar uma operação composta definida para implementar pesquisa de embedding. Ela é mapeada para uma operação combinada no TensorFlow Lite.
Ao fazer os modelos usarem operações compostas via tf.function
conforme ilustrado acima, é possível criar uma estrutura geral para identificar e converter essas operações em operações combinadas do TensorFlow Lite.
Como estender o conversor do TensorFlow Lite
O conversor do TensorFlow Lite lançado anteriormente neste ano só oferecia suporte à importação de modelos do TensorFlow como um grafo com todas as variáveis substituídas por seus valores constantes correspondentes, o que não funciona para a combinação de operações, já que esses grafos têm todas as funções embutidas para que as variáveis possam ser transformadas em constantes.
Para poder usar tf.function
com o recurso experimental_implements
durante o processo de conversão, as funções precisam ser preservadas até as etapas posteriores do processo de conversão.
Dessa forma, implementamos um novo workflow de importação e conversão de modelos do TensorFlow no conversor para oferecer suporte à combinação de operações compostas. Especificamente, os novos recursos adicionados são:
Importação de SavedModels do TensorFlow na MLIR
Dessa forma, podemos fazer a combinação de operações usando as funções que representam as operações compostas antes de as funções serem embutidas e de as variáveis serem congeladas.
Como implementar a combinação de operações
Vamos avaliar a etapa de combinação de operações com maiores detalhes. Essa etapa faz o seguinte:
Percorre em um loop todas as funções no módulo MLIR.
Se uma função tiver o atributo tf._implements – com base no valor do atributo, chama o utilitário de combinação de operações apropriado.
O utilitário de combinação de operações trabalha com os operandos e atributos da função (que servem como a interface para a conversão) e substitui o corpo da função por um corpo de função equivalente que contém a operação combinada.
Em diversos casos, o corpo substituído conterá operações diferentes da operação combinada, que correspondem a algumas transformações estáticas dos operandos da função para obter os operandos da operação combinada. Como essas computações podem sofrer constant-folding, não estariam presentes no Flatbuffer exportado, em que somente a operação combinada existiria.
Aqui está o trecho de código da etapa, mostrando o workflow principal:
Aqui está o trecho de código mostrando o mapeamento dessa operação composta para uma operação combinada no TensorFlow Lite usando a função como uma interface de conversão.