Guía de inferencia de LLM para iOS

La API de inferencia de LLM te permite ejecutar modelos grandes de lenguaje (LLM) completamente integrados en el dispositivo para aplicaciones de iOS, los cuales puedes usar a fin de realizar una amplia variedad de tareas, como generar texto, recuperar información en formato de lenguaje natural y resumir documentos. La tarea proporciona compatibilidad integrada con varios modelos grandes de lenguaje de texto a texto, de modo que puedas aplicar los modelos de IA generativa más recientes integrados en el dispositivo a tus apps para iOS.

Puedes ver esta tarea en acción con la demostración de MediaPipe Studio. Para obtener más información sobre las capacidades, los modelos y las opciones de configuración de esta tarea, consulta la Descripción general.

Ejemplo de código

El código de ejemplo de MediaPipe Tasks es una implementación básica de una app de la API de inferencia de LLM para iOS. Puedes usar la app como punto de partida de tu propia app para iOS o consultarla cuando modifiques una app existente. El código de ejemplo de la API de inferencia de LLM se aloja en GitHub.

Descarga el código

En las siguientes instrucciones, se muestra cómo crear una copia local del código de ejemplo con la herramienta de línea de comandos git.

Para descargar el código de ejemplo, haz lo siguiente:

  1. Usa el siguiente comando para clonar el repositorio de Git:

    git clone https://github.com/google-ai-edge/mediapipe-samples
    
  2. De manera opcional, configura tu instancia de Git para que use un proceso de confirmación de compra disperso, de modo que solo tengas los archivos para la app de ejemplo de la API de inferencia de LLM:

    cd mediapipe
    git sparse-checkout init --cone
    git sparse-checkout set examples/llm_inference/ios/
    

Después de crear una versión local del código de ejemplo, puedes instalar la biblioteca de tareas de MediaPipe, abrir el proyecto con Xcode y ejecutar la app. Para obtener instrucciones, consulta la Guía de configuración para iOS.

Configuración

En esta sección, se describen los pasos clave para configurar tu entorno de desarrollo y los proyectos de código a fin de usar la API de inferencia de LLM. Si quieres obtener información general sobre cómo configurar tu entorno de desarrollo para usar tareas de MediaPipe, incluidos los requisitos de la versión de la plataforma, consulta la Guía de configuración para iOS.

Dependencias

La API de inferencia de LLM usa la biblioteca MediaPipeTasksGenai, que se debe instalar con CocoaPods. La biblioteca es compatible con las apps de Swift y Objective-C, y no requiere ninguna configuración adicional específica de un lenguaje.

Si quieres obtener instrucciones para instalar CocoaPods en macOS, consulta la guía de instalación de CocoaPods. Si quieres obtener instrucciones para crear un Podfile con los Pods necesarios para tu app, consulta Usa CocoaPods.

Agrega el Pod MediaPipeTasksGenai a Podfile con el siguiente código:

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

Si la app incluye objetivos de prueba de unidades, consulta la Guía de configuración para iOS y obtén información adicional sobre la configuración de tu Podfile.

Modelo

La tarea de la API de inferencia del LLM de MediaPipe requiere un modelo entrenado que sea compatible con esta tarea. Si deseas obtener más información sobre los modelos entrenados disponibles para la API de inferencia de LLM, consulta la sección Modelos de la descripción general de la tarea.

Descarga un modelo

Descarga un modelo y agrégalo al directorio de tu proyecto con Xcode. Para obtener instrucciones sobre cómo agregar archivos a tu proyecto de Xcode, consulta Administra archivos y carpetas en tu proyecto de Xcode.

Descargar Gemma 2B

Cuando compiles apps para iOS, usa una de las siguientes variantes:

  • gemma-2b-it-cpu-int4: Modelo de 4 bits de Gemma con compatibilidad con CPU.
  • gemma-2b-it-gpu-int4: Modelo de 4 bits de Gemma con compatibilidad con GPU.
  • Modelos asignados de AI Edge Torch que cumplen con los requisitos de memoria de iOS.

Para obtener más información sobre otros modelos, consulta la sección Modelos de descripción general de la tarea.

Crea la tarea

Puedes crear la tarea de la API de inferencia de LLM llamando a uno de sus inicializadores. El inicializador LlmInference(options:) establece valores para las opciones de configuración.

Si no necesitas una API de inferencia de LLM que se inicialice con opciones de configuración personalizadas, puedes usar el inicializador de LlmInference(modelPath:) para crear una API de inferencia de LLM con las opciones predeterminadas. Para obtener más información sobre las opciones de configuración, consulta Descripción general de la configuración.

En el siguiente código, se muestra la compilación y configuración de esta tarea.

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)

Opciones de configuración

Esta tarea incluye las siguientes opciones de configuración para apps para iOS:

Nombre de la opción Descripción Rango de valores Valor predeterminado
modelPath La ruta de acceso en la que se almacena el modelo dentro del directorio del proyecto. PATH N/A
maxTokens La cantidad máxima de tokens (tokens de entrada + tokens de salida) que controla el modelo. Número entero 512
topk La cantidad de tokens que el modelo considera en cada paso de generación. Limita las predicciones a los k tokens más probables principales. Cuando configuras topk, también debes establecer un valor para randomSeed. Número entero 40
temperature La cantidad de aleatoriedad introducida durante la generación. Una temperatura más alta da como resultado más creatividad en el texto generado, mientras que una temperatura más baja produce una generación más predecible. Cuando configuras temperature, también debes establecer un valor para randomSeed. Float 0.8
randomSeed El valor inicial aleatorio usado durante la generación de texto. Número entero 0
loraPath Es la ruta de acceso absoluta al modelo de LoRA local en el dispositivo. Nota: Esto solo es compatible con los modelos de GPU. PATH N/A

prepara los datos

La API de inferencia de LLM funciona con datos de texto. Esta tarea controla el procesamiento previo de la entrada de datos, incluida la asignación de token y el procesamiento previo del tensor.

Todo el procesamiento previo se controla dentro de la función generateResponse(inputText:). No es necesario realizar un procesamiento previo adicional del texto de entrada con anticipación.

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

Ejecuta la tarea

Para ejecutar la API de inferencia de LLM, usa el método generateResponse(inputText:). La API de inferencia de LLM muestra las categorías posibles para el texto de entrada.

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

Para transmitir la respuesta, usa el 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)")
}

Cómo controlar y mostrar los resultados

La API de inferencia de LLM muestra un LlmInferenceResult, que incluye el texto de respuesta generado.

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]

Personalización del modelo de LoRA

La API de inferencia de LLM de Mediapipe se puede configurar para que admita la adaptación de bajo rango (LoRA) en modelos grandes de lenguaje. Mediante modelos de LoRA ajustados, los desarrolladores pueden personalizar el comportamiento de los LLM a través de un proceso de entrenamiento rentable.

La compatibilidad de LoRA con la API de inferencia de LLM funciona con los modelos Gemma-2B y Phi-2 para el backend de la GPU, y las ponderaciones de LoRA se aplican solo a las capas de atención. Esta implementación inicial sirve como una API experimental para desarrollos futuros con planes de admitir más modelos y varios tipos de capas en las próximas actualizaciones.

Prepara modelos de LoRA

Sigue las instrucciones en HuggingFace para entrenar un modelo de LoRA ajustado en tu propio conjunto de datos con los tipos de modelos compatibles: Gemma-2B o Phi-2. Los modelos Gemma-2B y Phi-2 están disponibles en HuggingFace en el formato de cajas fuertes. Dado que la API de inferencia de LLM solo admite LoRA en las capas de atención, especifica únicamente estas capas mientras creas el LoraConfig de la siguiente manera:

# 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 las pruebas, hay modelos de LoRA perfeccionados y de acceso público que se ajustan a la API de inferencia de LLM disponibles en HuggingFace. Por ejemplo, monsterapi/gemma-2b-lora-maths-orca-200k para Gemma-2B y lole25/phi-2-sft-ultrachat-lora para Phi-2.

Después de entrenar con el conjunto de datos preparado y guardar el modelo, obtendrás un archivo adapter_model.safetensors que contiene los pesos del modelo de LoRA ajustados. El archivo Safetensors es el punto de control de la LoRA que se usa en la conversión del modelo.

En el siguiente paso, debes convertir los pesos del modelo en un búfer plano de TensorFlow Lite con el paquete de MediaPipe para Python. El ConversionConfig debe especificar las opciones del modelo base, así como las opciones de LoRA adicionales. Ten en cuenta que, como la API solo admite la inferencia de LoRA con GPU, el backend debe configurarse en '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)

El conversor generará dos archivos de búfer plano de TFLite, uno para el modelo base y otro para el modelo de LoRA.

Inferencia del modelo de LoRA

Se actualizaron las APIs de inferencia de LLM para iOS, Android y la Web para admitir la inferencia de modelos de LoRA. Web admite LoRA dinámica, que puede cambiar diferentes modelos de LoRA durante el tiempo de ejecución. iOS y Android admiten la LoRA estática, que utiliza las mismas ponderaciones de la LoRA durante el ciclo de vida de la tarea.

iOS admite la LoRA estática durante la inicialización. Para cargar un modelo de LoRA, los usuarios deben especificar la ruta de acceso del modelo de LoRA y el 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 ejecutar la inferencia de LLM con LoRA, usa los mismos métodos generateResponse() o generateResponseAsync() que el modelo base.