Guia de inferência de LLM para iOS

.

A API LLM Inference permite executar modelos de linguagem grandes (LLMs) totalmente no dispositivo para aplicativos iOS, que você pode usar para executar uma ampla gama de tarefas, como 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 iOS.

É possível conferir essa tarefa em ação com o MediaPipe Studio demonstração. Para mais informações sobre recursos, modelos e opções de configuração, desta tarefa, consulte a Visão geral.

Exemplo de código

O código de exemplo do MediaPipe Tasks é uma implementação básica de uma API LLM Inference para iOS. Você pode usar o app como ponto de partida para seu próprio app iOS ou se referir a ele ao modificar um aplicativo existente. O código de exemplo da API LLM Inference é hospedado em 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/ios/
    

Depois de criar uma versão local do código de exemplo, você pode instalar o MediaPipe, abrir o projeto usando Xcode e executar o app. Para instruções, consulte o Guia de configuração do 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 como configurar sua ambiente de desenvolvimento para usar tarefas do MediaPipe, incluindo a 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 o CocoaPods. A biblioteca é compatível com aplicativos Swift e Objective-C e não requer configuração específica do idioma.

Para instruções sobre como instalar o CocoaPods no macOS, consulte a documentação do CocoaPods guia de instalação (em inglês). Para instruções sobre como criar um Podfile com os pods necessários para aplicativo, consulte Usar CocoaPods.

Adicione o pod MediaPipeTasksGenai no 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 do iOS para mais informações sobre a configuração seu Podfile.

Modelo

A tarefa da API Inference do LLM do MediaPipe requer um modelo treinado que seja compatível a essa tarefa. Para mais informações sobre os modelos treinados disponíveis para API LLM Inference, consulte a seção Modelos na 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 para adicionar arquivos ao seu projeto Xcode, consulte Como gerenciar arquivos e pastas no seu arquivo Xcode, projeto.

Fazer 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 do AI Edge Torch que estão em conformidade com os requisitos de memória do iOS.

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

Criar a tarefa

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

Se você não precisa que uma API LLM Inference seja inicializada com a configuração personalizada você pode usar o inicializador LlmInference(modelPath:) para criar um API LLM Inference com as opções padrão. Para mais informações sobre configurações opções, consulte Visão geral da configuração.

O código abaixo 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. 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

Preparar dados

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

Todo o pré-processamento é feito na função generateResponse(inputText:). Não é necessário pré-processar o texto de entrada.

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 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 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 iOS 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.

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 de LLM com a LoRA, use os mesmos métodos generateResponse() ou generateResponseAsync() do modelo base.