Guia de inferência de LLM para iOS

A API LLM Inference permite executar modelos de linguagem grande (LLMs) totalmente no dispositivo para aplicativos iOS, que podem ser usados para executar uma ampla variedade de tarefas, como gerar texto, recuperar informações em formato de linguagem natural e resumir documentos. A tarefa oferece suporte integrado a vários modelos de linguagem grande de texto para texto para que você possa aplicar os modelos de IA generativa mais recentes no dispositivo aos seus apps iOS.

Confira essa tarefa em ação com a demonstração do MediaPipe Studio. 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

O código de exemplo do MediaPipe Tasks é uma implementação básica de um app da API LLM Inference para iOS. Use o app como ponto de partida para seu próprio app iOS ou consulte-o ao modificar um app existente. O código de exemplo da API LLM Inference está hospedado no GitHub (em inglês).

Fazer o download do código

As instruções a seguir mostram como criar uma cópia local do código de 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. Como opção, configure sua instância git para usar a finalização da compra esparsa 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/ios/
    

Depois de criar uma versão local do código de exemplo, você poderá instalar a biblioteca de tarefas do MediaPipe, abrir o projeto usando o Xcode e executar o app. Para instruções, consulte o Guia de configuração para iOS.

Configuração

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

Dependências

A API LLM Inference usa a biblioteca MediaPipeTasksGenai, que precisa ser instalada usando CocoaPods. A biblioteca é compatível com apps Swift e Objective-C e não requer nenhuma configuração específica da linguagem.

Para instruções sobre como instalar o CocoaPods no macOS, consulte o guia de instalação do CocoaPods. Para instruções sobre como criar um Podfile com os pods necessários para o aplicativo, consulte Como usar o CocoaPods.

Adicione o pod MediaPipeTasksGenai ao Podfile usando o seguinte código:

target 'MyLlmInferenceApp' do
  use_frameworks!
  pod 'MediaPipeTasksGenAI'
  pod 'MediaPipeTasksGenAIC'
end

Se o app incluir destinos de teste de unidade, consulte o Guia de configuração para iOS para mais informações sobre como configurar o Podfile.

Modelo

A tarefa da API MediaPipe LLM Inference requer um modelo treinado compatível com ela. Para mais informações sobre os modelos treinados disponíveis para a API LLM Inference, consulte a seção Modelos de visão geral da tarefa.

Fazer o download de um modelo

Faça o download de um modelo e adicione-o ao diretório do projeto usando o Xcode. Para instruções sobre como adicionar arquivos ao projeto do Xcode, consulte Gerenciar arquivos e pastas no projeto do Xcode.

Faça o download do Gemma 2B

Ao criar apps iOS, use uma das seguintes variantes:

  • gemma-2b-it-cpu-int4: modelo Gemma de 4 bits com compatibilidade com CPU.
  • gemma-2b-it-gpu-int4: modelo Gemma de 4 bits com compatibilidade com GPU.
  • Modelos mapeados pelo AI Edge Torch em conformidade com os requisitos de memória do iOS.

Para mais informações sobre outros modelos, consulte a seção Modelos de visão geral da tarefa.

Criar a tarefa

É possível criar a tarefa da API LLM Inference chamando um dos inicializadores dela. O inicializador LlmInference(options:) define valores para as opções de configuração.

Caso você não precise de uma API LLM Inference inicializada com opções de configuração personalizadas, use o inicializador LlmInference(modelPath:) para criar uma API LLM Inference com as opções padrão. Para mais informações sobre as opções de configuração, consulte Visão geral da configuração.

O código a seguir demonstra como criar e configurar essa tarefa.

import MediaPipeTasksGenai

let modelPath = Bundle.main.path(forResource: "model",
                                      ofType: "bin")

let options = LlmInferenceOptions()
options.baseOptions.modelPath = modelPath
options.maxTokens = 1000
options.topk = 40
options.temperature = 0.8
options.randomSeed = 101

let LlmInference = try LlmInference(options: options)

Opções de configuração

Esta tarefa tem as seguintes opções de configuração para apps iOS:

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. PATH N/A
maxTokens O número máximo de tokens (de entrada + saída) que o modelo gerencia. Número inteiro 512
topk O número de tokens que o modelo considera em cada etapa da geração. Limita as previsões aos k principais tokens mais prováveis. Ao definir topk, você também precisa definir um valor para randomSeed. Número inteiro 40
temperature A quantidade de aleatoriedade gerada 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. Ao definir temperature, você também precisa definir um valor para randomSeed. Ponto flutuante 0,8
randomSeed A semente aleatória usada durante a geração de 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. PATH N/A

preparar os dados

A API LLM Inference funciona com dados de texto. A tarefa lida com o pré-processamento de entrada de dados, incluindo a tokenização e o pré-processamento de tensor.

Todo o pré-processamento é processado na função generateResponse(inputText:). Não é necessário fazer outro pré-processamento do texto de entrada com antecedência.

let inputPrompt = "Compose an email to remind Brett of lunch plans at noon on Saturday."

Executar a tarefa

Para executar a API LLM Inference, use o método generateResponse(inputText:). A API LLM Inference retorna as categorias possíveis para o texto de entrada.

let result = try LlmInference.generateResponse(inputText: inputPrompt)

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

let resultStream =  LlmInference.generateResponseAsync(inputText: inputPrompt)

do {
  for try await partialResult in resultStream {
    print("\(partialResult)")
  }
  print("Done")
}
catch {
  print("Response error: '\(error)")
}

Gerenciar e mostrar resultados

A API LLM Inference 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 do modelo LoRA

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

O suporte da LoRA à API LLM Inference funciona com modelos Gemma-2B e Phi-2 para o back-end da GPU, com pesos de LoRA aplicáveis apenas a 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 em HuggingFace para treinar um modelo LoRA ajustado no seu próprio conjunto de dados com tipos de modelo compatíveis, Gemma-2B ou Phi-2. Os modelos Gemma-2B e Phi-2 estão disponíveis no HuggingFace no formato safetensor. Como a API LLM Inference só oferece suporte a LoRA em camadas de atenção, especifique apenas elas ao criar a 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 publicamente acessíveis 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ê recebe um arquivo adapter_model.safetensors contendo os pesos do modelo LoRA ajustado. O arquivo safetensors é o checkpoint da LoRA usado na conversão do modelo.

Na próxima etapa, você vai precisar converter os pesos do modelo em um Flatbuffer do TensorFlow Lite usando o pacote MediaPipe Python. O ConversionConfig precisa especificar as opções do modelo base e outras opções da LoRA. Como a API só oferece suporte à inferência LoRA com a 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 de flatbuffer TFLite, 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 modelo LoRA. A Web oferece suporte à LoRA dinâmica, que pode alternar diferentes modelos 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 iOS é compatível com a LoRA estática durante a inicialização. Para carregar um modelo LoRA, os usuários especificam o caminho do modelo LoRA e o LLM base.

import MediaPipeTasksGenai

let modelPath = Bundle.main.path(forResource: "model",
                                      ofType: "bin")
let loraPath= Bundle.main.path(forResource: "lora_model",
                                      ofType: "bin")
let options = LlmInferenceOptions()
options.modelPath = modelPath
options.maxTokens = 1000
options.topk = 40
options.temperature = 0.8
options.randomSeed = 101
options.loraPath = loraPath

let LlmInference = try LlmInference(options: options)

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