A API LLM Inference permite executar modelos de linguagem grandes (LLMs) totalmente no dispositivo para aplicativos Android, que podem ser usados para realizar uma ampla gama de tarefas, como gerar texto, recuperar informações em linguagem natural e resumir documentos. A tarefa oferece suporte integrado a vários modelos de linguagem grandes de texto para texto. Assim, você pode aplicar os modelos de IA generativa mais recentes no dispositivo aos seus apps Android.
A tarefa oferece suporte ao Gemma-2 2B, a mais recente de uma família de modelos abertos leves e de última geração criados com a mesma pesquisa e tecnologia usadas para criar os modelos Gemini. Ele também oferece suporte aos seguintes modelos: Gemma, Phi-2, Falcon-RW-1B e StableLM-3B, além de todos os modelos exportados pelo AI Edge.
Para mais informações sobre os recursos, modelos e opções de configuração dessa tarefa, consulte a Visão geral.
Exemplo de código
Este guia se refere 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 fazer referência a ele ao modificar um app existente. O código de exemplo está hospedado no GitHub.
Fazer o download do código
As instruções a seguir mostram como criar uma cópia local do exemplo de código usando a ferramenta de linha de comando git.
Para fazer o download do código de exemplo:
- Clone o repositório do Git usando o seguinte comando:
git clone https://github.com/google-ai-edge/mediapipe-samples
- Opcionalmente, configure sua instância do Git para usar o checkout esparso, para que você tenha
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 para o Android Studio e executar o app. Para ver instruções, consulte o Guia de configuração para 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 de inferência de LLM. Para informações gerais sobre como configurar seu ambiente de desenvolvimento para usar as tarefas do MediaPipe, incluindo os requisitos da versão da plataforma, consulte o Guia de configuração para Android.
Dependências
A API LLM Inference usa a biblioteca com.google.mediapipe:tasks-genai
. Adicione esta
dependência ao arquivo build.gradle
do seu app Android:
dependencies {
implementation 'com.google.mediapipe:tasks-genai:0.10.14'
}
Para dispositivos com o Android 12 (nível 31 da API) ou mais recente, adicione a dependência da biblioteca
OpenCL nativa. Para mais informações, consulte a documentação da tag uses-native-library
.
Adicione as seguintes tags uses-native-library
ao arquivo AndroidManifest.xml
:
<uses-native-library android:name="libOpenCL.so" android:required="false"/>
<uses-native-library android:name="libOpenCL-car.so" android:required="false"/>
<uses-native-library android:name="libOpenCL-pixel.so" android:required="false"/>
Modelo
A API MediaPipe LLM Inference requer um modelo de linguagem de conversão de texto em texto treinado que seja compatível com essa tarefa. Depois de fazer o download de um modelo, instale as dependências necessárias e envie o modelo para o dispositivo Android. Se você estiver usando um modelo diferente do Gemma, será necessário converter o modelo para um formato compatível com o MediaPipe.
Para mais informações sobre os modelos treinados disponíveis para a API de inferência LLM, consulte a seção "Modelos" da visão geral da tarefa.
Fazer o download de um modelo
Antes de inicializar a API de inferência de LLM, faça o download de um dos modelos compatíveis e armazene o arquivo no diretório do projeto:
- Gemma-2 2B: a versão mais recente da família de modelos Gemma. Faz parte de uma família de modelos abertos leves e de última geração criados com a mesma pesquisa e tecnologia usada para criar os modelos do Gemini.
- Gemma 2B: faz parte de uma família de modelos abertos leves e de última geração criados com a mesma pesquisa e tecnologia usadas para criar os modelos do Gemini. Adequado para diversas tarefas de geração de texto, incluindo resposta a perguntas, resumo e raciocínio.
- Phi-2: modelo de Transformer de 2, 7 bilhões de parâmetros, mais adequado para o formato pergunta-resposta, chat e código.
- Falcon-RW-1B: modelo de 1 bilhão de parâmetros somente para decodificador treinado com 350 bilhões de tokens do RefinedWeb.
- StableLM-3B: modelo de linguagem com três bilhões de parâmetros somente decodificador, pré-treinado em 1 trilhão de tokens de diversos conjuntos de dados de inglês e código.
Recomendamos usar o Gemma-2 2B, que está disponível nos modelos do Kaggle. Para mais informações sobre os outros modelos disponíveis, consulte a seção Modelos na visão geral da tarefa.
Converter modelo para o formato MediaPipe
Conversão de modelo nativo
Se você estiver usando um LLM externo (Phi-2, Falcon ou StableLM) ou uma versão do Gemma que não seja do Kaggle, use nossos scripts de conversão para formatar o modelo para que ele seja compatível com o MediaPipe.
O processo de conversão do modelo requer o pacote MediaPipe PyPI. O script
de conversão 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 as opções do modelo base e outras opções LoRA. Como a API só é compatível com 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 vai gerar dois arquivos flatbuffer do TFLite, 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 sendo convertido. | {"PHI_2", "FALCON_RW_1B", "STABLELM_4E1T_3B", "GEMMA_2B", "GEMMA_7B", "GEMMA-2_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 é compatível apenas com a API de inferência LLM e não pode ser usado como um arquivo "tflite" geral. | CAMINHO |
vocab_model_file |
O caminho para o diretório que armazena os arquivos tokenizer.json e
tokenizer_config.json . Para o Gemma, aponte para o único arquivo tokenizer.model . |
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 do 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 oferece suporte ao LoRA. | Número inteiro |
lora_output_tflite_file |
Nome do arquivo tflite de saída dos pesos LoRA. | CAMINHO |
Conversão de modelos de IA do Edge
Se você estiver usando um LLM mapeado para um modelo TFLite pelo AI Edge, use nosso script de agrupamento para criar um pacote de tarefas. Esse processo empacota o modelo mapeado com outros metadados (por exemplo, parâmetros de tokenizador) necessários para executar a inferência de ponta a ponta.
O processo de agrupamento de modelos requer o pacote PyPI do MediaPipe. O script
de conversão 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 do TFLite exportado do AI Edge. | CAMINHO |
tokenizer_model |
O caminho para o modelo de tokenizador do SentencePiece. | CAMINHO |
start_token |
Token de início específico do modelo. O token de início precisa estar presente no modelo de tokenizador fornecido. | STRING |
stop_tokens |
Tokens de parada específicos do modelo. Os tokens de parada precisam estar presentes no modelo de tokenizador fornecido. | LISTA[STRING] |
output_filename |
O nome do arquivo do pacote de tarefas de saída. | CAMINHO |
Enviar o modelo para o dispositivo
Envie o conteúdo da pasta output_path para o dispositivo Android.
$ 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 de inferência LLM do MediaPipe usa a função createFromOptions()
para configurar a
tarefa. A função createFromOptions()
aceita valores para as opções de
configuração. Para mais informações sobre as opções de configuração, consulte Opções de
configuração.
O código a seguir inicializa a tarefa usando opções de configuração básicas:
// 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 a seguir 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 k tokens mais prováveis. | Número inteiro | 40 |
temperature |
A quantidade de aleatoriedade introduzida durante a geração. Uma temperatura mais alta resulta em mais criatividade no texto gerado, enquanto uma temperatura mais baixa produz 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 resultado para receber os resultados de forma assíncrona. Aplicável apenas 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 comando.
val inputPrompt = "Compose an email to remind Brett of lunch plans at noon on Saturday."
Executar a tarefa
Use o método generateResponse()
para gerar uma resposta de texto para o texto de entrada
fornecido na seção anterior (inputPrompt
). Isso produz uma única
resposta gerada.
val result = llmInference.generateResponse(inputPrompt)
logger.atInfo().log("result: $result")
Para fazer streaming da resposta, use o método generateResponseAsync()
.
val options = LlmInference.LlmInferenceOptions.builder()
...
.setResultListener { partialResult, done ->
logger.atInfo().log("partial result: $partialResult")
}
.build()
llmInference.generateResponseAsync(inputPrompt)
Processar e mostrar resultados
A API de inferência de LLM retorna um LlmInferenceResult
, que inclui o texto de resposta
gerado.
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 de modelo LoRA
A API de inferência de LLM do Mediapipe pode ser configurada para oferecer suporte à adaptação de baixa classificação (LoRA) para modelos de linguagem grandes. Com modelos LoRA ajustados, os desenvolvedores podem personalizar o comportamento dos LLMs por meio de um processo de treinamento econômico.
O suporte da LoRA à API LLM Inference funciona para modelos Gemma-2B e Phi-2 para o back-end da GPU, com pesos LoRA aplicáveis apenas às camadas de atenção. Essa implementação inicial serve como uma API experimental para desenvolvimentos futuros, com planos de oferecer suporte a mais modelos e vários tipos de camadas nas próximas 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 safetensors. 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 se encaixam na 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ê vai receber um arquivo adapter_model.safetensors
com os pesos do modelo LoRA ajustados. 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 de modelo base e 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 vai gerar dois arquivos flatbuffer do TFLite, um para o modelo base e outro para o modelo LoRA.
Inferência de modelo LoRA
A API de inferência de LLM 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 entre diferentes modelos LoRA durante a execução. Android e iOS são compatíveis com LoRA estático, que usa os mesmos pesos 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 o LoRA, use os mesmos métodos generateResponse()
ou generateResponseAsync()
do modelo base.