Guia de inferência de LLM para Android

.

A API LLM Inference permite executar modelos de linguagem grandes (LLMs) totalmente no dispositivo para aplicativos Android, que você pode usar para executar uma ampla gama de tarefas, como gerar texto, recuperar informações na forma de linguagem natural e resumir documentos. A tarefa fornece suporte integrado para vários modelos de linguagem grandes de texto para texto, para que você possa aplicar os modelos mais recentes no dispositivo modelos de IA generativa aos seus apps Android.

A tarefa oferece suporte ao Gemma 2B, parte de um uma família de modelos abertos, leves e de ponta, criados a partir dos mesmos e a tecnologia usada para criar os modelos do Gemini. Ele também é compatível com os seguintes modelos externos: Phi-2, Falcon-RW-1B e StableLM-3B, além de todos os modelos exportados pelo AI Edge.

Para mais informações sobre recursos, modelos e opções de configuração, desta tarefa, consulte a Visão geral.

Exemplo de código

Este guia refere-se a um exemplo de app básico de geração de texto para Android. Você pode usar o app como ponto de partida para seu próprio app Android ou consultá-lo ao modificar um aplicativo existente. O código de exemplo está hospedado GitHub.

Fazer o download do código

As instruções a seguir mostram como criar uma cópia local do exemplo. usando a ferramenta de linha de comando git.

Para fazer o download do código de exemplo:

  1. Clone o repositório git usando o seguinte comando:
    git clone https://github.com/google-ai-edge/mediapipe-samples
    
  2. Opcionalmente, configure sua instância git para usar a finalização esparsa. Assim, você terá apenas os arquivos do app de exemplo da API LLM Inference:
    cd mediapipe
    git sparse-checkout init --cone
    git sparse-checkout set examples/llm_inference/android
    

Depois de criar uma versão local do código de exemplo, você pode importar o projeto no Android Studio e executar o app. Para obter instruções, consulte o Guia de configuração do Android.

Configuração

Esta seção descreve as principais etapas para configurar seu ambiente de desenvolvimento e projetos de código especificamente para usar a API LLM Inference. Para informações gerais a configuração do seu ambiente de desenvolvimento para usar tarefas do MediaPipe, incluindo requisitos de versão da plataforma, consulte o Guia de configuração do Android.

Dependências

A API LLM Inference usa a biblioteca com.google.mediapipe:tasks-genai. Adicionar dependência do arquivo build.gradle do seu app Android:

dependencies {
    implementation 'com.google.mediapipe:tasks-genai:0.10.14'
}

Modelo

A API MediaPipe LLM Inference requer um modelo de linguagem de texto para texto treinado que seja compatíveis com esta tarefa. Depois de fazer o download de um modelo, instale os e as envia ao dispositivo Android. Se você estiver usando um modelo fora do Gemma, você terá que converter o modelo para um formato compatível o MediaPipe.

Para mais informações sobre modelos treinados disponíveis para a API LLM Inference, consulte a tarefa Visão geral da seção Modelos.

Fazer o download de um modelo

Antes de inicializar a API LLM Inference, faça o download de um dos modelos compatíveis e Armazene o arquivo no diretório do seu projeto:

  • Gemma 2B: Parte de uma família de modelos abertos leves e de última geração criados a partir da mesma pesquisa e tecnologia usadas para criar modelos do Gemini. Ideal para vários tipos tarefas de geração de texto, incluindo resposta a perguntas, resumo e raciocínio.
  • Phi-2: 2,7 bilhões de parâmetros modelo de transformador, mais adequado para perguntas, respostas, chat e código .
  • Falcon-RW-1B: 1 bilhão modelo somente decodificador causal do parâmetro treinado em 350 bilhões de tokens de RefinedWeb (link em inglês).
  • StableLM-3B: 3 de bilhões de parâmetros de linguagem apenas decodificadores pré-treinado em 1 trilhão tokens de diversos conjuntos de dados ingleses e de código.

Como alternativa, é possível usar modelos mapeados e exportados por AI Edge Troch (em inglês).

Recomendamos usar o Gemma 2B, disponível no Kaggle modelos e vem em um formato que já seja compatível com a API LLM Inference. Se você usar outro LLM, você terá que converter o modelo em um Formato compatível com MediaPipe. Para saber mais sobre o Gemma 2B, consulte a documentação do Gemma 2B". site. Para mais informações sobre outros modelos disponíveis, consulte a seção de visão geral da tarefa Modelos.

Converter modelo para o formato MediaPipe

Conversão de modelo nativo

Se você estiver usando um LLM externo (Phi-2, Falcon ou StableLM) ou um que não seja Kaggle versão do Gemma, use nossos scripts de conversão para formatar o modelo para ser compatível com MediaPipe.

O processo de conversão de modelos requer o pacote MediaPipe PyPI. A conversão o script está disponível em todos os pacotes MediaPipe após 0.10.11.

Instale e importe as dependências com o seguinte:

$ python3 -m pip install mediapipe

Use a biblioteca genai.converter para converter o modelo:

import mediapipe as mp
from mediapipe.tasks.python.genai import converter

config = converter.ConversionConfig(
  input_ckpt=INPUT_CKPT,
  ckpt_format=CKPT_FORMAT,
  model_type=MODEL_TYPE,
  backend=BACKEND,
  output_dir=OUTPUT_DIR,
  combine_file_only=False,
  vocab_model_file=VOCAB_MODEL_FILE,
  output_tflite_file=OUTPUT_TFLITE_FILE,
)

converter.convert_checkpoint(config)

Para converter o modelo LoRA, o ConversionConfig precisa especificar o modelo base bem como opções adicionais de LoRA. Como a API só tem um oferece suporte à inferência LoRA com GPU, o back-end precisa ser definido como 'gpu'.

import mediapipe as mp
from mediapipe.tasks.python.genai import converter

config = converter.ConversionConfig(
  # Other params related to base model
  ...
  # Must use gpu backend for LoRA conversion
  backend='gpu',
  # LoRA related params
  lora_ckpt=LORA_CKPT,
  lora_rank=LORA_RANK,
  lora_output_tflite_file=LORA_OUTPUT_TFLITE_FILE,
)

converter.convert_checkpoint(config)

O conversor gerará dois arquivos TFLite flatbuffer, um para o modelo base e outro para o modelo LoRA.

Parâmetro Descrição Valores aceitos
input_ckpt O caminho para o arquivo model.safetensors ou pytorch.bin. Às vezes, o formato dos safetensors do modelo é fragmentado em vários arquivos, por exemplo, model-00001-of-00003.safetensors (model-00001-of-00003.safetensors). É possível especificar um padrão de arquivo, como model*.safetensors. CAMINHO
ckpt_format O formato do arquivo do modelo. {"safetensors", "pytorch"}
model_type O LLM que está sendo convertido. {"PHI_2", "FALCON_RW_1B", "STABLELM_4E1T_3B", "GEMMA_2B"}
backend O processador (delegado) usado para executar o modelo. {"cpu", "gpu"}
output_dir O caminho para o diretório de saída que hospeda os arquivos de peso por camada. CAMINHO
output_tflite_file O caminho para o arquivo de saída. Por exemplo, "model_cpu.bin" ou "model_gpu.bin". Esse arquivo só é compatível com a API LLM Inference e não pode ser usado como um arquivo "tflite" geral. CAMINHO
vocab_model_file O caminho para o diretório que armazena os valores de tokenizer.json e tokenizer_config.json arquivos. No Gemma, aponte para o arquivo tokenizer.model único. CAMINHO
lora_ckpt O caminho para o arquivo de safetensors LoRA que armazena o peso do adaptador LoRA. CAMINHO
lora_rank Um número inteiro que representa a classificação do ckpt LoRA. Obrigatório para converter os pesos lora. Se não for fornecido, o conversor presumirá que não há pesos LoRA. Observação: somente o back-end da GPU é compatível com o LoRA. Número inteiro
lora_output_tflite_file Nome do arquivo tflite de saída dos pesos LoRA. CAMINHO

Conversão de modelo do AI Edge

Se você estiver usando um LLM mapeado para um modelo TFLite pela AI Edge, use nossa de agrupamento para criar um pacote de tarefas. Esse processo empacota os modelo mapeado com outros metadados (por exemplo, parâmetros do tokenizador) necessários para executar inferência completa.

O processo de empacotamento de modelos requer o pacote MediaPipe PyPI. A conversão o script está disponível em todos os pacotes MediaPipe após 0.10.14.

Instale e importe as dependências com o seguinte:

$ python3 -m pip install mediapipe

Use a biblioteca genai.bundler para agrupar o modelo:

import mediapipe as mp
from mediapipe.tasks.python.genai import bundler

config = bundler.BundleConfig(
    tflite_model=TFLITE_MODEL,
    tokenizer_model=TOKENIZER_MODEL,
    start_token=START_TOKEN,
    stop_tokens=STOP_TOKENS,
    output_filename=OUTPUT_FILENAME,
    enable_bytes_to_unicode_mapping=ENABLE_BYTES_TO_UNICODE_MAPPING,
)
bundler.create_bundle(config)
Parâmetro Descrição Valores aceitos
tflite_model O caminho para o modelo TFLite exportado do AI Edge. CAMINHO
tokenizer_model O caminho para o modelo de tokenizador do SentencePiece. CAMINHO
start_token Token inicial específico do modelo. O token inicial precisa estar presente no modelo de tokenizador fornecido. STRING
stop_tokens Tokens de parada específicos do modelo. Os tokens de parada devem estar presentes no modelo de tokenizador fornecido. LISTA[STRING]
output_filename O nome do arquivo de pacote de tarefas de saída. CAMINHO

Enviar o modelo para o dispositivo

Enviar o conteúdo da pasta output_path para o Android dispositivo.

$ adb shell rm -r /data/local/tmp/llm/ # Remove any previously loaded models
$ adb shell mkdir -p /data/local/tmp/llm/
$ adb push output_path /data/local/tmp/llm/model_version.bin

Criar a tarefa

A API MediaPipe LLM Inference usa a função createFromOptions() para configurar a tarefa. A função createFromOptions() aceita valores para a configuração. . Para mais informações sobre as opções de configuração, consulte Configuração .

O código a seguir inicializa a tarefa usando opções básicas de configuração:

// Set the configuration options for the LLM Inference task
val options = LlmInferenceOptions.builder()
        .setModelPATH('/data/local/.../')
        .setMaxTokens(1000)
        .setTopK(40)
        .setTemperature(0.8)
        .setRandomSeed(101)
        .build()

// Create an instance of the LLM Inference task
llmInference = LlmInference.createFromOptions(context, options)

Opções de configuração

Use as opções de configuração abaixo para configurar um app Android:

Nome da opção Descrição Intervalo de valor Valor padrão
modelPath O caminho para onde o modelo está armazenado no diretório do projeto. CAMINHO N/A
maxTokens O número máximo de tokens (de entrada e de saída) processados pelo modelo. Número inteiro 512
topK O número de tokens que o modelo considera em cada etapa de geração. Limita as previsões aos tokens mais prováveis do Top-K. Número inteiro 40
temperature A quantidade de aleatoriedade introduzida durante a geração. Uma maior a temperatura resulta em mais criatividade no texto gerado, enquanto temperaturas mais baixas produzem uma geração mais previsível. Ponto flutuante 0,8
randomSeed A sugestão aleatória usada durante a geração do texto. Número inteiro 0
loraPath O caminho absoluto para o modelo LoRA localmente no dispositivo. Observação: isso só é compatível com modelos de GPU. CAMINHO N/A
resultListener Define o listener de resultados para receber os resultados de forma assíncrona. Aplicável somente ao usar o método de geração assíncrona. N/A N/A
errorListener Define um listener de erro opcional. N/A N/A

Preparar dados

A API LLM Inference aceita as seguintes entradas:

  • prompt (string): uma pergunta ou um comando.
val inputPrompt = "Compose an email to remind Brett of lunch plans at noon on Saturday."

Executar a tarefa

Usar o método generateResponse() para gerar uma resposta de texto para a entrada fornecido na seção anterior (inputPrompt). Isso produz um único a resposta gerada.

val result = llmInference.generateResponse(inputPrompt)
logger.atInfo().log("result: $result")

Para transmitir a resposta, use o método generateResponseAsync().

val options = LlmInference.LlmInferenceOptions.builder()
  ...
  .setResultListener { partialResult, done ->
    logger.atInfo().log("partial result: $partialResult")
  }
  .build()

llmInference.generateResponseAsync(inputPrompt)

Gerenciar e exibir resultados

A API LLM Inference retorna um LlmInferenceResult, que inclui o o texto da resposta.

Here's a draft you can use:

Subject: Lunch on Saturday Reminder

Hi Brett,

Just a quick reminder about our lunch plans this Saturday at noon.
Let me know if that still works for you.

Looking forward to it!

Best,
[Your Name]

Personalização do modelo LoRA

A API de inferência de LLM do Mediapipe pode ser configurada para oferecer suporte à adaptação de baixa classificação (LoRA, na sigla em inglês) para modelos de linguagem grandes. Com os modelos LoRA ajustados, os desenvolvedores podem personalizar o comportamento dos LLMs por meio de um processo de treinamento econômico.

O suporte do LoRA à API LLM Inference funciona com os modelos Gemma-2B e Phi-2 para back-end da GPU, com pesos LoRA aplicáveis apenas às camadas de atenção. Isso implementação inicial serve como uma API experimental para desenvolvimentos futuros e planejamos oferecer suporte a mais modelos e vários tipos de camadas nos próximos atualizações.

Preparar modelos LoRA

Siga as instruções do HuggingFace para treinar um modelo LoRA ajustado em seu próprio conjunto de dados com os tipos de modelo com suporte, Gemma-2B ou Phi-2. Os modelos Gemma-2B e Phi-2 estão disponíveis no HuggingFace no formato de seguros. Como a API LLM Inference oferece suporte apenas a LoRA em camadas de atenção, especifique apenas essas camadas ao criar o LoraConfig da seguinte maneira:

# For Gemma-2B
from peft import LoraConfig
config = LoraConfig(
    r=LORA_RANK,
    target_modules=["q_proj", "v_proj", "k_proj", "o_proj"],
)

# For Phi-2
config = LoraConfig(
    r=LORA_RANK,
    target_modules=["q_proj", "v_proj", "k_proj", "dense"],
)

Para testes, há modelos LoRA ajustados e acessíveis publicamente que combinam com a API LLM Inference disponível no HuggingFace. Por exemplo, monsterapi/gemma-2b-lora-maths-orca-200k para Gemma-2B e lole25/phi-2-sft-ultrachat-lora para Phi-2.

Depois de treinar no conjunto de dados preparado e salvar o modelo, você recebe um arquivo adapter_model.safetensors contendo os pesos do modelo LoRA ajustado. O arquivo safetensors é o checkpoint LoRA usado na conversão do modelo.

Na próxima etapa, você precisa converter os pesos do modelo em um TensorFlow Lite Flatbuffer usando o pacote MediaPipe Python. O ConversionConfig precisa especificar as opções do modelo base, bem como outras opções de LoRA. Como a API só oferece suporte à inferência LoRA com GPU, o back-end precisa ser definido como 'gpu'.

import mediapipe as mp
from mediapipe.tasks.python.genai import converter

config = converter.ConversionConfig(
  # Other params related to base model
  ...
  # Must use gpu backend for LoRA conversion
  backend='gpu',
  # LoRA related params
  lora_ckpt=LORA_CKPT,
  lora_rank=LORA_RANK,
  lora_output_tflite_file=LORA_OUTPUT_TFLITE_FILE,
)

converter.convert_checkpoint(config)

O conversor gerará dois arquivos TFLite flatbuffer, um para o modelo base e outro para o modelo LoRA.

Inferência de modelo LoRA

A API LLM Inference para Web, Android e iOS foi atualizada para oferecer suporte à inferência de modelos LoRA. A Web oferece suporte à LoRA dinâmica, que pode alternar diferentes modelos de LoRA durante o tempo de execução. O Android e o iOS são compatíveis com a LoRA estática, que usa os mesmos pesos da LoRA durante o ciclo de vida da tarefa.

O Android oferece suporte à LoRA estática durante a inicialização. Para carregar um modelo LoRA, os usuários especificam o caminho desse modelo, bem como o LLM básico.

// Set the configuration options for the LLM Inference task
val options = LlmInferenceOptions.builder()
        .setModelPath('<path to base model>')
        .setMaxTokens(1000)
        .setTopK(40)
        .setTemperature(0.8)
        .setRandomSeed(101)
        .setLoraPath('<path to LoRA model>')
        .build()

// Create an instance of the LLM Inference task
llmInference = LlmInference.createFromOptions(context, options)

Para executar a inferência de LLM com a LoRA, use os mesmos métodos generateResponse() ou generateResponseAsync() do modelo base.