Autocompletar

Ver no TensorFlow.org Executar no Google Colab

Introdução

Os modelos de linguagem grandes (LLMs) são uma classe de modelos de aprendizado de máquina treinados para gerar texto com base em grandes conjuntos de dados. Eles podem ser usados ​​para tarefas de processamento de linguagem natural (NLP), incluindo geração de texto, resposta a perguntas e tradução automática. Eles são baseados na arquitetura do Transformer e são treinados em grandes quantidades de dados de texto, muitas vezes envolvendo bilhões de palavras. Mesmo os LLMs de menor escala, como o GPT-2, podem ter um desempenho impressionante. A conversão de modelos do TensorFlow para um modelo mais leve, rápido e de baixo consumo de energia nos permite executar modelos de IA generativos no dispositivo, com benefícios de melhor segurança do usuário porque os dados nunca saem do seu dispositivo.

Este runbook mostra como criar um aplicativo Android com TensorFlow Lite para executar um Keras LLM e fornece sugestões para otimização de modelo usando técnicas de quantização, que de outra forma exigiriam uma quantidade muito maior de memória e maior poder computacional para executar.

Nós abrimos o código de nossa estrutura de aplicativo Android que qualquer TFLite LLMs compatível pode conectar. Aqui estão duas demonstrações:

  • Na Figura 1, usamos um modelo Keras GPT-2 para executar tarefas de conclusão de texto no dispositivo.
  • Na Figura 2, convertemos uma versão do modelo PaLM ajustado por instrução (1,5 bilhão de parâmetros) para TFLite e executamos por meio do tempo de execução do TFLite.

Preenchimento automático com PaLM
Figura 1: Exemplo de execução do modelo Keras GPT-2 (convertido deste Codelab ) no dispositivo para executar a conclusão de texto no Pixel 7. A demonstração mostra a latência real sem aumento de velocidade.

Preenchimento automático com PaLM

Figura 2: Exemplo de execução de uma versão do modelo PaLM com 1,5 bilhão de parâmetros. A demonstração é gravada no Pixel 7 Pro sem aceleração de reprodução.

Guias

Criação de modelo

Para esta demonstração, usaremos o KerasNLP para obter o modelo GPT-2. O KerasNLP é uma biblioteca que contém modelos pré-treinados de última geração para tarefas de processamento de linguagem natural e pode oferecer suporte aos usuários durante todo o ciclo de desenvolvimento. Você pode ver a lista de modelos disponíveis no repositório KerasNLP . Os fluxos de trabalho são construídos a partir de componentes modulares que possuem pesos e arquiteturas predefinidos de última geração quando usados ​​imediatamente e são facilmente personalizáveis ​​quando é necessário mais controle. A criação do modelo GPT-2 pode ser feita com as seguintes etapas:

gpt2_tokenizer = keras_nlp.models.GPT2Tokenizer.from_preset("gpt2_base_en")

gpt2_preprocessor = keras_nlp.models.GPT2CausalLMPreprocessor.from_preset(
    "gpt2_base_en",
    sequence_length=256,
    add_end_token=True,
)

gpt2_lm =
keras_nlp.models.GPT2CausalLM.from_preset(
"gpt2_base_en",
preprocessor=gpt2_preprocessor
)

Um ponto em comum entre essas três linhas de código é o método from_preset() , que instanciará a parte da API Keras a partir de uma arquitetura e/ou pesos predefinidos, carregando, portanto, o modelo pré-treinado. A partir deste trecho de código, você também notará três componentes modulares:

  1. Tokenizer : converte uma entrada de string bruta em IDs de token inteiro adequados para uma camada Keras Embedding. GPT-2 usa o tokenizador de codificação de par de bytes (BPE) especificamente.

  2. Pré-processador : camada para tokenização e empacotamento de entradas a serem alimentadas em um modelo Keras. Aqui, o pré-processador preencherá o tensor de IDs de token para um comprimento especificado (256) após a tokenização.

  3. Backbone : modelo Keras que segue a arquitetura de backbone do transformador SoTA e tem os pesos predefinidos.

Além disso, você pode conferir a implementação completa do modelo GPT-2 no GitHub .

Conversão de modelo

O TensorFlow Lite é uma biblioteca móvel para implantar métodos em dispositivos móveis, microcontroladores e outros dispositivos de ponta. A primeira etapa é converter um modelo Keras em um formato TensorFlow Lite mais compacto usando o conversor TensorFlow Lite e, em seguida, usar o interpretador TensorFlow Lite , altamente otimizado para dispositivos móveis, para executar o modelo convertido.

Comece com a função generate() de GPT2CausalLM que realiza a conversão. Envolva a função generate() para criar uma função TensorFlow concreta:

@tf.function
def generate(prompt, max_length):
    """
    Args:
        prompt: input prompt to the LLM in string format
        max_length: the max length of the generated tokens
    """
    return gpt2_lm.generate(prompt, max_length)

concrete_func = generate.get_concrete_function(tf.TensorSpec([], tf.string), 100)

Observe que você também pode usar from_keras_model() do TFLiteConverter para realizar a conversão.

Agora defina uma função auxiliar que executará a inferência com uma entrada e um modelo TFLite. As operações de texto do TensorFlow não são operações integradas no tempo de execução do TFLite, portanto, você precisará adicionar essas operações personalizadas para que o interpretador faça inferência nesse modelo. Essa função auxiliar aceita uma entrada e uma função que realiza a conversão, ou seja, a função generator() definida acima.

def run_inference(input, generate_tflite):
    interp = interpreter.InterpreterWithCustomOps(
        model_content=generate_tflite,
        custom_op_registerers=
            tf_text.tflite_registrar.SELECT_TFTEXT_OPS
    )

    interp.get_signature_list()

    generator = interp.get_signature_runner('serving_default')
    output = generator(prompt=np.array([input]))

Você pode converter o modelo agora:

gpt2_lm.jit_compile = False
converter = tf.lite.TFLiteConverter.from_concrete_functions(
    [concrete_func],
    gpt2_lm)

converter.target_spec.supported_ops = [
    tf.lite.OpsSet.TFLITE_BUILTINS, # enable TFLite ops
    tf.lite.OpsSet.SELECT_TF_OPS, # enable TF ops
]
converter.allow_custom_ops = True
converter.target_spec.experimental_select_user_tf_ops = [
    "UnsortedSegmentJoin",
    "UpperBound"
]
converter._experimental_guarantee_all_funcs_one_use = True
generate_tflite = converter.convert()
run_inference("I'm enjoying a", generate_tflite)

Quantização

O TensorFlow Lite implementou uma técnica de otimização chamada quantização , que pode reduzir o tamanho do modelo e acelerar a inferência. Através do processo de quantização, os floats de 32 bits são mapeados para inteiros menores de 8 bits, reduzindo assim o tamanho do modelo por um fator de 4 para uma execução mais eficiente em hardwares modernos. Existem várias maneiras de fazer quantização no TensorFlow. Você pode visitar as páginas TFLite Model Optimization e TensorFlow Model Optimization Toolkit para obter mais informações. Os tipos de quantização são explicados brevemente abaixo.

Aqui, você usará a quantização de faixa dinâmica pós-treinamento no modelo GPT-2 definindo o sinalizador de otimização do conversor para tf.lite.Optimize.DEFAULT , e o restante do processo de conversão é o mesmo detalhado anteriormente. Testamos que, com essa técnica de quantização, a latência é de cerca de 6,7 segundos no Pixel 7 com comprimento máximo de saída definido como 100.

gpt2_lm.jit_compile = False
converter = tf.lite.TFLiteConverter.from_concrete_functions(
    [concrete_func],
    gpt2_lm)

converter.target_spec.supported_ops = [
    tf.lite.OpsSet.TFLITE_BUILTINS, # enable TFLite ops
    tf.lite.OpsSet.SELECT_TF_OPS, # enable TF ops
]
converter.allow_custom_ops = True
converter.optimizations = [tf.lite.Optimize.DEFAULT]
converter.target_spec.experimental_select_user_tf_ops = [
    "UnsortedSegmentJoin",
    "UpperBound"
]
converter._experimental_guarantee_all_funcs_one_use = True
quant_generate_tflite = converter.convert()
run_inference("I'm enjoying a", quant_generate_tflite)

Alcance Dinâmico

A quantização de faixa dinâmica é o ponto de partida recomendado para otimizar os modelos no dispositivo. Ele pode atingir uma redução de cerca de 4x no tamanho do modelo e é um ponto de partida recomendado, pois fornece uso de memória reduzido e computação mais rápida sem que você precise fornecer um conjunto de dados representativo para calibração. Este tipo de quantização quantiza estaticamente apenas os pesos de ponto flutuante para inteiro de 8 bits no momento da conversão.

FP16

Os modelos de ponto flutuante também podem ser otimizados quantizando os pesos para o tipo float16. As vantagens da quantização float16 são reduzir o tamanho do modelo em até a metade (já que todos os pesos se tornam metade de seu tamanho), causando perda mínima de precisão e suportando delegados de GPU que podem operar diretamente nos dados float16 (o que resulta em computação mais rápida do que em float32 dados). Um modelo convertido para pesos float16 ainda pode ser executado na CPU sem modificações adicionais. Os pesos float16 são aumentados para float32 antes da primeira inferência, o que permite uma redução no tamanho do modelo em troca de um impacto mínimo na latência e na precisão.

Quantização inteira completa

A quantização inteira inteira converte os números de ponto flutuante de 32 bits, incluindo pesos e ativações, para os inteiros de 8 bits mais próximos. Esse tipo de quantização resulta em um modelo menor com maior velocidade de inferência, o que é incrivelmente valioso ao usar microcontroladores. Este modo é recomendado quando as ativações são sensíveis à quantização.

Integração de aplicativos Android

Você pode seguir este exemplo do Android para integrar seu modelo TFLite em um aplicativo Android.

Pré-requisitos

Se ainda não o fez, instale o Android Studio , seguindo as instruções do site.

  • Android Studio 2022.2.1 ou superior.
  • Um dispositivo Android ou emulador Android com mais de 4G de memória

Construindo e executando com o Android Studio

  • Abra o Android Studio e, na tela de boas-vindas, selecione Abrir um projeto existente do Android Studio .
  • Na janela Open File or Project que aparece, navegue e selecione o diretório lite/examples/generative_ai/android de onde você clonou o repositório GitHub de amostra do TensorFlow Lite.
  • Você também pode precisar instalar várias plataformas e ferramentas de acordo com as mensagens de erro.
  • Renomeie o modelo .tflite convertido para autocomplete.tflite e copie-o para a pasta app/src/main/assets/ .
  • Selecione o menu Build -> Make Project para criar o aplicativo. (Ctrl+F9, dependendo da sua versão).
  • Clique no menu Executar -> Executar 'aplicativo' . (Shift+F10, dependendo da sua versão)

Como alternativa, você também pode usar o gradle wrapper para construí-lo na linha de comando. Consulte a documentação do Gradle para obter mais informações.

(Opcional) Criando o arquivo .aar

Por padrão, o aplicativo baixa automaticamente os arquivos .aar necessários. Mas se você quiser construir o seu próprio, mude para app/libs/build_aar/ pasta run ./build_aar.sh . Este script extrairá as operações necessárias do TensorFlow Text e criará o aar para os operadores Select TF.

Após a compilação, um novo arquivo tftext_tflite_flex.aar é gerado. Substitua o arquivo .aar na pasta app/libs/ e reconstrua o aplicativo.

Observe que você ainda precisa incluir o aar tensorflow-lite padrão em seu arquivo gradle.

Tamanho da janela de contexto

O aplicativo tem um parâmetro mutável 'tamanho da janela de contexto', que é necessário porque os LLMs hoje geralmente têm um tamanho de contexto fixo que limita quantas palavras/tokens podem ser inseridos no modelo como 'prompt' (observe que 'palavra' não é necessariamente equivalente a 'token' neste caso, devido a diferentes métodos de tokenização). Este número é importante porque:

  • Definindo-o muito pequeno, o modelo não terá contexto suficiente para gerar uma saída significativa
  • Definindo-o muito grande, o modelo não terá espaço suficiente para trabalhar (já que a sequência de saída inclui o prompt)

Você pode experimentá-lo, mas configurá-lo para ~ 50% do comprimento da sequência de saída é um bom começo.

Segurança e IA responsável

Conforme observado no anúncio original do OpenAI GPT-2 , existem ressalvas e limitações notáveis ​​com o modelo GPT-2. Na verdade, os LLMs de hoje geralmente têm alguns desafios bem conhecidos, como alucinações, imparcialidade e preconceito; isso ocorre porque esses modelos são treinados em dados do mundo real, o que os faz refletir problemas do mundo real.

Este codelab foi criado apenas para demonstrar como criar um aplicativo desenvolvido por LLMs com ferramentas do TensorFlow. O modelo produzido neste codelab é apenas para fins educacionais e não se destina ao uso em produção.

O uso de produção LLM requer uma seleção cuidadosa de conjuntos de dados de treinamento e mitigações de segurança abrangentes. Uma dessas funcionalidades oferecidas neste aplicativo Android é o filtro de palavrões, que rejeita entradas de usuário ou saídas de modelo ruins. Se algum idioma impróprio for detectado, o aplicativo rejeitará essa ação. Para saber mais sobre a IA responsável no contexto dos LLMs, assista à sessão técnica Desenvolvimento seguro e responsável com modelos de linguagem generativos no Google I/O 2023 e confira o Kit de ferramentas de IA responsável .