Guide d'inférence LLM pour Android

<ph type="x-smartling-placeholder">

L'API LLM Inference vous permet d'exécuter de grands modèles de langage (LLM) entièrement sur l'appareil pour les applications Android, que vous pouvez utiliser pour effectuer un large éventail de tâches, telles que la génération de texte, l'extraction d'informations en langage naturel résumer des documents. Cette tâche intègre la prise en charge de plusieurs de grands modèles de langage texte-vers-texte, ce qui vous permet d'appliquer des modèles d'IA générative à vos applications Android.

La tâche est compatible avec Gemma 2B, qui fait partie d'un de modèles ouverts légers et de pointe, élaborés à partir de la même recherche et la technologie utilisée pour créer les modèles Gemini. Il est également compatible avec les modèles externes suivants: Phi-2 Falcon-RW-1B et StableLM-3B, ainsi que tous les modèles exportés via AI Edge.

Pour en savoir plus sur les fonctionnalités, les modèles et les options de configuration de cette tâche, consultez la section Présentation.

Exemple de code

Ce guide est un exemple d'application basique de génération de texte pour Android. Toi vous pouvez utiliser l'application comme point de départ pour votre propre application Android ou s'y référer. lorsque vous modifiez une application existante. L'exemple de code est hébergé sur GitHub

Télécharger le code

Les instructions suivantes vous expliquent comment créer une copie locale de l'exemple à l'aide de l'outil de ligne de commande git.

Pour télécharger l'exemple de code:

  1. Clonez le dépôt Git à l'aide de la commande suivante:
    git clone https://github.com/google-ai-edge/mediapipe-samples
    
  2. Si vous le souhaitez, vous pouvez configurer votre instance Git pour utiliser le paiement creuse. Seuls les fichiers de l'application exemple de l'API d'inférence LLM:
    cd mediapipe
    git sparse-checkout init --cone
    git sparse-checkout set examples/llm_inference/android
    

Après avoir créé une version locale de l'exemple de code, vous pouvez importer le projet dans Android Studio et exécuter l'application. Pour obtenir des instructions, consultez le Guide de configuration Android

Configuration

Cette section décrit les étapes clés à suivre pour configurer votre environnement de développement projets de code spécifiques pour utiliser l'API LLM Inference. Pour obtenir des informations générales sur configurer votre environnement de développement pour utiliser les tâches MediaPipe, y compris version de la plate-forme requise, consultez le guide de configuration Android

Dépendances

L'API LLM Inference utilise la bibliothèque com.google.mediapipe:tasks-genai. Ajouter au fichier build.gradle de votre application Android:

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

Modèle

L'API d'inférence LLM MediaPipe nécessite un modèle de langage texte-vers-texte entraîné compatibles avec cette tâche. Après avoir téléchargé un modèle, installez les dépendances et transmettre le modèle à l'appareil Android. Si vous utilisez un modèle autre que Gemma, vous devez convertir le modèle dans un format compatible MediaPipe

Pour en savoir plus sur les modèles entraînés disponibles pour l'API d'inférence LLM, consultez la tâche consultez la section Modèles.

Télécharger un modèle

Avant d'initialiser l'API d'inférence LLM, téléchargez l'un des modèles compatibles et Stockez le fichier dans le répertoire de votre projet:

  • Gemma 2B: Cet outil fait partie d'une famille de modèles ouverts, légers et de pointe, construits à partir de les mêmes recherches et technologies utilisées pour créer modèles Gemini. Parfaitement adapté à une grande variété les tâches de génération de texte, y compris les réponses à des questions, la synthèse et le raisonnement.
  • Phi-2: 2,7 milliards de paramètres Modèle Transformer, parfaitement adapté aux questions-réponses, au chat et au code .
  • Falcon-RW-1B: 1 milliard modèle causal décodeur uniquement, entraîné sur 350 milliards de jetons de RefinedWeb :
  • StableLM-3B: 3 milliard de paramètres de modèle de langage décodeur uniquement, pré-entraîné sur 1 000 milliards de divers ensembles de données en anglais et en code.

Vous pouvez également utiliser des modèles mappés et exportés via AI Edge Troch :

Nous vous recommandons d'utiliser Gemma 2B, disponible sur Kaggle modèles et est fourni dans un format déjà compatible avec l'API LLM Inference. Si vous utilisez un autre LLM, vous devez convertir le modèle en Format compatible avec MediaPipe. Pour plus d'informations sur Gemma 2B, consultez le document Gemma site Web. Pour en savoir plus sur les autres modèles disponibles, consultez la section Modèles de présentation des tâches.

Convertir le modèle au format MediaPipe

Conversion par modèle natif

Si vous utilisez un LLM externe (Phi-2, Falcon ou StableLM) ou un modèle autre que Kaggle de Gemma, utilisez nos scripts de conversion pour formater le modèle compatible avec MediaPipe.

Le processus de conversion du modèle nécessite le package PyPI MediaPipe. La conversion est disponible dans tous les packages MediaPipe après 0.10.11.

Installez et importez les dépendances à l'aide de la commande suivante:

$ python3 -m pip install mediapipe

Utilisez la bibliothèque genai.converter pour convertir le modèle:

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)

Pour convertir le modèle LoRA, ConversionConfig doit spécifier le modèle de base ainsi que d'autres options LoRA. Notez que, puisque l'API prend en charge l'inférence LoRA avec GPU, le backend doit être défini sur '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)

Le convertisseur génère deux fichiers TFLite Flatbuffer, un pour le modèle de base. et l'autre pour le modèle LoRA.

Paramètre Description Valeurs acceptées
input_ckpt Chemin d'accès au fichier model.safetensors ou pytorch.bin. Notez que parfois le format des Tensors sécurisés du modèle est segmenté en plusieurs fichiers. Par exemple, model-00001-of-00003.safetensors, model-00001-of-00003.safetensors. Vous pouvez spécifier un format de fichier, tel que model*.safetensors. CHEMIN
ckpt_format Format de fichier du modèle. {"safetensors", "pytorch"}
model_type LLM en cours de conversion. {&quot;PHI_2&quot;, &quot;FALCON_RW_1B&quot;, &quot;STABLELM_4E1T_3B&quot;, &quot;GEMMA_2B&quot;}
backend Processeur (délégué) utilisé pour exécuter le modèle. {&quot;cpu&quot;, &quot;gpu&quot;}
output_dir Chemin d'accès au répertoire de sortie qui héberge les fichiers de pondération par couche. CHEMIN
output_tflite_file Chemin d'accès au fichier de sortie. Par exemple, "model_cpu.bin" ou "model_gpu.bin". Ce fichier n'est compatible qu'avec l'API d'inférence LLM et ne peut pas être utilisé comme fichier "tflite" général. CHEMIN
vocab_model_file Le chemin d'accès au répertoire qui stocke les fichiers tokenizer.json et tokenizer_config.json fichiers. Pour Gemma, pointez vers le seul fichier tokenizer.model. CHEMIN
lora_ckpt Chemin d'accès au fichier LoRA de la valeur Safetensors qui stocke le poids de l'adaptateur LoRA. CHEMIN
lora_rank Nombre entier représentant le rang de la méthode LoRA ckpt. Obligatoire pour convertir les pondérations Lora. Si ce champ n'est pas fourni, le convertisseur suppose qu'il n'y a pas de pondérations LoRA. Remarque: Seul le backend GPU est compatible avec la LoRA. Entier
lora_output_tflite_file Nom de fichier tflite de sortie pour les pondérations LoRA. CHEMIN

Conversion de modèles AI Edge

Si vous utilisez un LLM mappé à un modèle TFLite via AI Edge, utilisez notre d'un script de regroupement pour créer un groupe de tâches. Le processus de regroupement avec des métadonnées supplémentaires (par exemple, paramètres de tokenisation) nécessaires pour exécuter une inférence de bout en bout.

Le processus de regroupement des modèles nécessite le package MediaPipe PyPI. La conversion est disponible dans tous les packages MediaPipe après 0.10.14.

Installez et importez les dépendances à l'aide de la commande suivante:

$ python3 -m pip install mediapipe

Utilisez la bibliothèque genai.bundler pour grouper le modèle:

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)
Paramètre Description Valeurs acceptées
tflite_model Chemin d'accès au modèle TFLite exporté par AI Edge. CHEMIN
tokenizer_model Chemin d'accès au modèle de tokenisation SentencePiece. CHEMIN
start_token Jeton de démarrage spécifique au modèle. Le jeton de début doit être présent dans le modèle de tokenisation fourni. STRING
stop_tokens Modéliser des jetons d'arrêt spécifiques. Les jetons d'arrêt doivent être présents le modèle de tokenisation fourni. LISTE[STRING]
output_filename Nom du fichier du groupe de tâches de sortie. CHEMIN

Transmettre le modèle à l'appareil

Transférer le contenu du dossier output_path vers Android appareil.

$ 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

Créer la tâche

L'API MediaPipe LLM Inference utilise la fonction createFromOptions() pour configurer le tâche. La fonction createFromOptions() accepte les valeurs pour la configuration options. Pour plus d'informations sur les options de configuration, consultez la section Configuration options.

Le code suivant initialise la tâche à l'aide des options de configuration de base:

// 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)

Options de configuration

Utilisez les options de configuration suivantes pour configurer une application Android:

Nom de l'option Description Plage de valeurs Valeur par défaut
modelPath Chemin d'accès au stockage du modèle dans le répertoire du projet. CHEMIN N/A
maxTokens Nombre maximal de jetons (jetons d'entrée + jetons de sortie) traités par le modèle. Entier 512
topK Nombre de jetons pris en compte par le modèle à chaque étape de génération. Limite les prédictions aux k premiers jetons les plus probables. Entier 40
temperature Quantité de caractère aléatoire introduite lors de la génération. Une augmentation favorise la créativité dans le texte généré, tandis qu'un plus la température est basse, plus la génération est prévisible. Float 0,8
randomSeed Source aléatoire utilisée lors de la génération du texte. Entier 0
loraPath Chemin absolu vers le modèle LoRA local sur l'appareil. Remarque: Cette option n'est compatible qu'avec les modèles de GPU. CHEMIN N/A
resultListener Définit l'écouteur de résultats pour qu'il reçoive les résultats de manière asynchrone. Ne s'applique que lorsque vous utilisez la méthode de génération asynchrone. N/A N/A
errorListener Définit un écouteur d'erreurs facultatif. N/A N/A

Préparer les données

L'API LLM Inference accepte les entrées suivantes:

  • prompt (chaîne): question ou requête.
val inputPrompt = "Compose an email to remind Brett of lunch plans at noon on Saturday."

Exécuter la tâche

Utiliser la méthode generateResponse() pour générer une réponse textuelle à l'entrée texte fourni dans la section précédente (inputPrompt). Cela permet de générer un seul générée la réponse.

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

Pour diffuser la réponse, utilisez la méthode generateResponseAsync().

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

llmInference.generateResponseAsync(inputPrompt)

Gérer et afficher les résultats

L'API LLM Inference renvoie un code LlmInferenceResult, qui inclut l'élément généré le texte de la réponse.

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]

Personnalisation du modèle LoRA

L'API d'inférence LLM Mediapipe peut être configurée pour prendre en charge l'adaptation LoRA (Low-Rank Adaptation) pour les grands modèles de langage. À l'aide de modèles LoRA affinés, les développeurs peuvent personnaliser le comportement des LLM grâce à un processus d'entraînement économique.

La compatibilité LoRA de l'API d'inférence LLM fonctionne avec les modèles Gemma-2B et Phi-2 pour le backend du GPU, avec les pondérations LoRA applicables uniquement aux couches d'attention. Ce l'implémentation initiale sert d'API expérimentale pour les développements futurs Nous prévoyons de prendre en charge d'autres modèles et différents types de couches mises à jour.

Préparer les modèles LoRA

Suivez les instructions sur HuggingFace pour entraîner un modèle LoRA affiné sur votre propre ensemble de données avec des types de modèles compatibles, Gemma-2B ou Phi-2. Les modèles Gemma-2B et Phi-2 sont tous deux disponibles sur HuggingFace au format Safetensors. Étant donné que l'API d'inférence LLM n'accepte que la LoRA sur les couches d'attention, vous ne devez spécifier les couches d'attention que lors de la création de l'LoraConfig comme suit:

# 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"],
)

Pour les tests, il existe des modèles LoRA affinés accessibles au public et adaptés à l'API d'inférence LLM disponibles sur HuggingFace. Par exemple, monsterapi/gemma-2b-lora-maths-orca-200k pour Gemma-2B et lole25/phi-2-sft-ultrachat-lora pour Phi-2.

Après avoir entraîné sur l'ensemble de données préparé et enregistré le modèle, vous obtenez un fichier adapter_model.safetensors contenant les pondérations affinées du modèle LoRA. Le fichier Safetensors est le point de contrôle LoRA utilisé lors de la conversion du modèle.

L'étape suivante consiste à convertir les pondérations du modèle en un Flatbuffer TensorFlow Lite à l'aide du package Python MediaPipe. Le ConversionConfig doit spécifier les options du modèle de base ainsi que les options LoRA supplémentaires. Comme l'API n'accepte que l'inférence LoRA avec GPU, le backend doit être défini sur '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)

Le convertisseur génère deux fichiers TFLite Flatbuffer, un pour le modèle de base. et l'autre pour le modèle LoRA.

Inférence de modèle LoRA

L'API d'inférence LLM Web, Android et iOS a été mise à jour pour prendre en charge l'inférence de modèles LoRA. Le Web est compatible avec la technologie LoRA dynamique, qui peut changer de modèle LoRA pendant l'exécution. Android et iOS sont compatibles avec la fonctionnalité LoRA statique, qui utilise les mêmes pondérations LoRA pendant toute la durée de vie de la tâche.

Android est compatible avec la LoRA statique lors de l'initialisation. Pour charger un modèle LoRA, les utilisateurs spécifient le chemin d'accès au modèle LoRA ainsi que le LLM de 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)

Pour exécuter une inférence LLM avec LoRA, utilisez les mêmes méthodes generateResponse() ou generateResponseAsync() que le modèle de base.