Guía de inferencia de LLM para Android

La API de LLM Inference te permite ejecutar modelos grandes de lenguaje (LLM) completamente en el dispositivo para aplicaciones para Android, que puedes usar para realizar diversas tareas, como generar texto, recuperar información en formato de lenguaje natural y resumir documentos. La tarea proporciona compatibilidad integrada con varias modelos de lenguaje extensos de texto a texto, para que puedas aplicar modelos de IA generativa a tus apps para Android.

La tarea apoya a Gemma 2B, que forma parte de una de modelos abiertos ligeros de vanguardia creados a partir de la misma investigación y la tecnología que se usa para crear los modelos de Gemini. También admite los siguientes modelos externos: Phi-2 Falcon-RW-1B y StableLM-3B junto con todos los modelos exportados a través de AI Edge.

Para obtener más información sobre las capacidades, los modelos y las opciones de configuración para completar esta tarea, consulta la Descripción general.

Ejemplo de código

En esta guía, se hace referencia a un ejemplo de una app de generación de texto básica para Android. Tú Puedes usar la app como punto de partida para tu propia app de Android o hacer referencia a ella. cuando se modifica una app existente. El código de ejemplo se aloja en GitHub:

Descarga el código

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

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

  1. Clona el repositorio de Git con el siguiente comando:
    git clone https://github.com/google-ai-edge/mediapipe-samples
    
  2. De forma opcional, configura tu instancia de Git para que use un método de confirmación de la compra disperso solo los archivos de 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/android
    

Después de crear una versión local del código de ejemplo, puedes importar el proyecto en Android Studio y ejecutar la app. Para obtener instrucciones, consulta la Guía de configuración de Android

Configuración

En esta sección, se describen los pasos clave para configurar tu entorno de desarrollo y proyectos de código específicamente para usar la API de inferencia de LLM. Para obtener información general configurar tu entorno de desarrollo para usar tareas de MediaPipe, como requisitos de la versión de la plataforma, consulta la Guía de configuración de Android

Dependencias

La API de inferencia de LLM usa la biblioteca com.google.mediapipe:tasks-genai. Agregar dependencia al archivo build.gradle de tu app para Android:

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

Modelo

La API de inferencia de LLM de MediaPipe requiere un modelo de lenguaje de texto a texto entrenado compatibles con esta tarea. Después de descargar un modelo, instala el las dependencias y envía el modelo al dispositivo Android. Si usas un modelo aparte de Gemma, tendrás que convertir el modelo a un formato compatible MediaPipe.

Para obtener más información sobre los modelos entrenados disponibles para la API de inferencia de LLM, consulta la tarea Descripción general de la sección Modelos.

Descarga un modelo

Antes de inicializar la API de inferencia de LLM, descarga uno de los modelos compatibles y almacena el archivo dentro del directorio de tu proyecto:

  • Gemma 2B: Parte de una familia de modelos abiertos ligeros y de última generación creados a partir del misma investigación y tecnología que se usó para crear la Modelos de Gemini. Son adecuados para una variedad de de generación de texto, como responder preguntas, resumir y el razonamiento.
  • Phi-2: Parámetro de 2,700 millones Modelo Transformer, el más adecuado para preguntas y respuestas, chat y código de un conjunto de datos tengan un formato común.
  • Falcon-RW-1B: 1,000 millones modelo de solo decodificador causal de parámetros entrenado con 350,000 millones de tokens de RefinedWeb.
  • StableLM-3B: 3 mil millones de parámetros de un modelo de lenguaje solo con decodificador de parámetros previamente entrenados en 1 billón tokens de diversos conjuntos de datos en inglés y código.

También puedes usar modelos asignados y exportados mediante AI Edge Troch.

Te recomendamos usar Gemma 2B, que está disponible en Kaggle. Modelos y viene en un formato que ya es compatible con la API de inferencia de LLM. Si usas otro LLM, deberás convertir el modelo en un Formato compatible con MediaPipe. Para obtener más información sobre Gemma 2B, consulta la sitio. Para obtener más información modelos disponibles, consulta la sección Modelos en la descripción general de la tarea.

Convertir el modelo al formato MediaPipe

Conversión de modelo nativo

Si usas un LLM externo (Phi-2, Falcon o StableLM) o uno que no sea de Kaggle de Gemma, usemos los scripts de conversión para darle formato al modelo y son compatibles con MediaPipe.

El proceso de conversión de modelos requiere el paquete MediaPipe PyPI. La conversión está disponible en todos los paquetes de MediaPipe después de 0.10.11.

Instala y, luego, importa las dependencias con el siguiente comando:

$ python3 -m pip install mediapipe

Usa la biblioteca genai.converter para convertir el 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 convertir el modelo LoRA, ConversionConfig debe especificar el modelo base así como otras opciones de LoRA. Ten en cuenta que, como la API solo admite la inferencia de LoRA con GPU, el backend se debe establecer 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 el otro para el modelo LoRA.

Parámetro Descripción Valores aceptados
input_ckpt La ruta de acceso al archivo model.safetensors o pytorch.bin. Ten en cuenta que, a veces, el formato de los protectores de modelos se fragmenta en varios archivos, p.ej., model-00001-of-00003.safetensors y model-00001-of-00003.safetensors Puedes especificar un patrón de archivo, como model*.safetensors. RUTA
ckpt_format El formato de archivo del modelo. {"safetensors", "pytorch"}
model_type El LLM que se está convirtiendo. {"PHI_2", "FALCON_RW_1B", "STABLELM_4E1T_3B", "GEMMA_2B"}
backend Es el procesador (delegado) que se usa para ejecutar el modelo. {"cpu", "gpu"}
output_dir La ruta de acceso al directorio de salida que aloja los archivos de ponderación por capa. RUTA
output_tflite_file La ruta de acceso al archivo de salida. Por ejemplo, “model_cpu.bin” o “model_gpu.bin”. Este archivo solo es compatible con la API de inferencia de LLM y no se puede usar como un archivo `tflite` general. RUTA
vocab_model_file La ruta de acceso al directorio que almacena los elementos tokenizer.json y tokenizer_config.json archivos. Para Gemma, apunta al único archivo tokenizer.model. RUTA
lora_ckpt La ruta de acceso al ckpt de LoRA del archivo de tensores que almacena el peso del adaptador de LoRA. RUTA
lora_rank Un número entero que representa la clasificación de LoRA ckpt. Es obligatorio para convertir las ponderaciones de lora. Si no se proporcionan, el conversor supone que no hay ponderaciones de LoRA. Nota: Solo el backend de GPU es compatible con LoRA. Número entero
lora_output_tflite_file Nombre de archivo de tflite de salida para las ponderaciones de LoRA. RUTA

Conversión de modelos de AI Edge

Si usas un LLM asignado a un modelo de TFLite a través de AI Edge, usa nuestro de paquetes de datos para crear un Paquete de tareas. El proceso de agrupación modelo asignado con metadatos adicionales (p.ej., parámetros del tokenizador) necesarios para ejecutar inferencias de extremo a extremo.

El proceso de agrupación de modelos requiere el paquete MediaPipe PyPI. La conversión está disponible en todos los paquetes de MediaPipe después de 0.10.14.

Instala y, luego, importa las dependencias con el siguiente comando:

$ python3 -m pip install mediapipe

Usa la biblioteca genai.bundler para empaquetar el 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 Descripción Valores aceptados
tflite_model La ruta de acceso al modelo de TFLite exportado de AI Edge. RUTA
tokenizer_model La ruta de acceso al modelo del tokenizador de SentencePiece. RUTA
start_token Token de inicio específico del modelo. El token de inicio debe estar presente en el modelo de tokenizador proporcionado. STRING
stop_tokens Tokens de parada específicos del modelo. Los tokens de parada deben estar presentes en la modelo de tokenizador proporcionado. LISTA [STRING]
output_filename El nombre del archivo de paquete de tareas de salida. RUTA

Envía el modelo al dispositivo

Envía el contenido de la carpeta output_path a 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

Crea la tarea

La API de inferencia de MediaPipe LLM usa la función createFromOptions() para configurar la tarea. La función createFromOptions() acepta valores para la configuración opciones de estado. Para obtener más información sobre las opciones de configuración, consulta Configuración de la aplicación.

En el siguiente código, se inicializa la tarea mediante opciones de configuración 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)

Opciones de configuración

Utiliza las siguientes opciones de configuración para configurar una app para Android:

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. RUTA 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 tokens más probables de k superior. Número entero 40
temperature La cantidad de aleatorización que se introdujo durante la generación. Un valor superior temperatura da como resultado más creatividad en el texto generado, mientras que un una temperatura menor produce una generación más predecible. Número de punto flotante 0.8
randomSeed El valor inicial aleatorio que se usó durante la generación de texto. Número entero 0
loraPath La ruta de acceso absoluta al modelo LoRA a nivel local en el dispositivo. Nota: Esta función solo es compatible con los modelos de GPU. RUTA N/A
resultListener Configura el objeto de escucha de resultados para recibir los resultados de manera asíncrona. Solo es aplicable cuando se usa el método de generación asíncrona. N/A N/A
errorListener Configura un objeto de escucha de errores opcional. N/A N/A

Preparar los datos

La API de inferencia de LLM acepta las siguientes entradas:

  • prompt (cadena): Es una pregunta o instrucción.
val inputPrompt = "Compose an email to remind Brett of lunch plans at noon on Saturday."

Ejecuta la tarea

Usa el método generateResponse() para generar una respuesta de texto a la entrada. texto proporcionado en la sección anterior (inputPrompt). Esto produce un solo respuesta generada.

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

Para transmitir la respuesta, usa el método generateResponseAsync().

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

llmInference.generateResponseAsync(inputPrompt)

Cómo controlar y mostrar resultados

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

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 LoRA

La API de inferencia de LLM de Mediapipe se puede configurar para admitir una adaptación de clasificación baja (LoRA) para modelos grandes de lenguaje. Con modelos de LoRA ajustados, los desarrolladores pueden personalizar el comportamiento de los LLM con un proceso de entrenamiento rentable

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

Prepara modelos de LoRA

Sigue las instrucciones de HuggingFace para entrenar un modelo LoRA ajustado en tu propio conjunto de datos con 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 tensores. Dado que la API de inferencia de LLM solo admite LoRA en las capas de atención, solo especifica capas de atención mientras creas el objeto 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, existen modelos de LoRA ajustados 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 LoRA ajustado. El archivo de tensores es el punto de control de LoRA que se usa en la conversión del modelo.

El siguiente paso es convertir los pesos del modelo en un búfer plano de TensorFlow Lite con el paquete MediaPipe de Python. El elemento ConversionConfig debe especificar las opciones del modelo base y las opciones adicionales de LoRA. Ten en cuenta que, como la API solo admite inferencias LoRA con GPU, el backend debe establecerse 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 el otro para el modelo LoRA.

Inferencia del modelo LoRA

Se actualizó la API de LLM Inference para la Web, iOS y Android para admitir la inferencia del modelo LoRA. La 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 usa los mismos pesos de LoRA durante el ciclo de vida de la tarea.

Android admite LoRA estática durante la inicialización. Para cargar un modelo LoRA, los usuarios especifican la ruta del modelo LoRA, así como el LLM base.

// 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 ejecutar la inferencia de LLM con LoRA, usa los mismos métodos generateResponse() o generateResponseAsync() que el modelo base.