Guide d'inférence LLM pour iOS

L'API LLM Inference vous permet d'exécuter de grands modèles de langage (LLM) entièrement sur l'appareil pour les applications iOS, que vous pouvez utiliser pour effectuer un large éventail de tâches, telles que la génération de texte, la récupération d'informations en langage naturel et la synthèse de documents. Cette tâche est compatible avec plusieurs grands modèles de langage texte-vers-texte, ce qui vous permet d'appliquer les derniers modèles d'IA générative sur l'appareil à vos applications iOS.

Vous pouvez voir cette tâche en action dans la démonstration MediaPipe Studio. Pour en savoir plus sur les fonctionnalités, les modèles et les options de configuration de cette tâche, consultez la présentation.

Exemple de code

L'exemple de code MediaPipe Tasks est une implémentation de base d'une application utilisant l'API LLM Inference pour iOS. Vous pouvez utiliser l'application comme point de départ pour votre propre application iOS, ou vous y référer lorsque vous modifiez une application existante. L'exemple de code de l'API LLM Inference est hébergé sur GitHub.

Télécharger le code

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

Pour télécharger l'exemple de code, procédez comme suit:

  1. Clonez le dépôt git à l'aide de la commande suivante:

    git clone https://github.com/google-ai-edge/mediapipe-samples
    
  2. Vous pouvez éventuellement configurer votre instance Git pour utiliser le paiement creux afin de n'avoir que les fichiers de l'exemple d'application de l'API LLM Inference:

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

Après avoir créé une version locale de l'exemple de code, vous pouvez installer la bibliothèque de tâches MediaPipe, ouvrir le projet à l'aide de Xcode et exécuter l'application. Pour obtenir des instructions, consultez le guide de configuration pour iOS.

Préparation

Cette section décrit les étapes clés de la configuration de votre environnement de développement et de vos projets de code afin d'utiliser l'API LLM Inference. Pour obtenir des informations générales sur la configuration de votre environnement de développement pour l'utilisation des tâches MediaPipe, y compris les exigences de version de la plate-forme, consultez le guide de configuration pour iOS.

Dépendances

L'API LLM Inference utilise la bibliothèque MediaPipeTasksGenai, qui doit être installée à l'aide de CocoaPods. La bibliothèque est compatible avec les applications Swift et Objective-C, et ne nécessite aucune configuration spécifique au langage utilisé.

Pour savoir comment installer CocoaPods sous macOS, consultez le guide d'installation de CocoaPods. Pour savoir comment créer un Podfile avec les pods nécessaires à votre application, consultez la section Utiliser CocoaPods.

Ajoutez le pod MediaPipeTasksGenai dans Podfile à l'aide du code suivant:

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

Si votre application inclut des cibles de tests unitaires, consultez le guide de configuration pour iOS afin d'obtenir des informations supplémentaires sur la configuration de votre Podfile.

Modèle

La tâche de l'API LLM Inference de MediaPipe nécessite un modèle entraîné compatible avec cette tâche. Pour en savoir plus sur les modèles entraînés disponibles pour l'API LLM Inference, consultez la section Modèles de la présentation des tâches.

Télécharger un modèle

Téléchargez un modèle et ajoutez-le au répertoire de votre projet à l'aide de Xcode. Pour savoir comment ajouter des fichiers à votre projet Xcode, consultez la page Gérer les fichiers et les dossiers dans votre projet Xcode.

Télécharger Gemma 2B

Lorsque vous créez des applications iOS, utilisez l'une des variantes suivantes:

  • gemma-2b-it-cpu-int4 : modèle Gemma 4 bits compatible avec les processeurs.
  • gemma-2b-it-gpu-int4 : modèle Gemma 4 bits compatible avec les GPU.
  • Modèles mappés par AI Edge Torch conformes aux exigences de mémoire d'iOS.

Pour en savoir plus sur les autres modèles, consultez la section Modèles de la présentation des tâches.

Créer la tâche

Vous pouvez créer la tâche de l'API LLM Inference en appelant l'un de ses initialiseurs. L'initialiseur LlmInference(options:) définit les valeurs des options de configuration.

Si vous n'avez pas besoin d'une API LLM Inference initialisée avec des options de configuration personnalisées, vous pouvez utiliser l'initialiseur LlmInference(modelPath:) pour créer une API LLM Inference avec les options par défaut. Pour en savoir plus sur les options de configuration, consultez la section Présentation de la configuration.

Le code suivant montre comment créer et configurer cette tâche.

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)

Options de configuration

Cette tâche comporte les options de configuration suivantes pour les applications iOS:

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. PATH 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 que le modèle considère à chaque étape de génération. Limite les prédictions aux k jetons les plus probables. Lorsque vous définissez topk, vous devez également définir une valeur pour randomSeed. Entier 40
temperature Quantité de hasard introduit lors de la génération. Une température plus élevée accroît la créativité dans le texte généré, tandis qu'une température plus basse produit une génération plus prévisible. Lorsque vous définissez temperature, vous devez également définir une valeur pour randomSeed. Nombre à virgule flottante 0,8
randomSeed Valeur initiale aléatoire utilisée lors de la génération de texte. Entier 0
loraPath Chemin absolu vers le modèle LoRA localement sur l'appareil. Remarque: Ceci n'est compatible qu'avec les modèles de GPU. PATH N/A

Préparation des données

L'API LLM Inference fonctionne avec les données textuelles. Cette tâche gère le prétraitement de l'entrée des données, y compris la tokenisation et le prétraitement du Tensor.

L'ensemble du prétraitement est géré dans la fonction generateResponse(inputText:). Aucun prétraitement supplémentaire du texte d'entrée n'est nécessaire au préalable.

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

Exécuter la tâche

Pour exécuter l'API LLM Inference, utilisez la méthode generateResponse(inputText:). L'API LLM Inference renvoie les catégories possibles pour le texte d'entrée.

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

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

let resultStream =  LlmInference.generateResponseAsync(inputText: inputPrompt)

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

Gérer et afficher les résultats

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

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 de Mediapipe peut être configurée pour prendre en charge l'adaptation de rang faible (LoRA) pour les grands modèles de langage. À l'aide de modèles LoRA affinés, les développeurs peuvent personnaliser le comportement des LLM via un processus d'entraînement économique.

La prise en charge de la bibliothèque LoRA de l'API LLM Inference fonctionne pour les modèles Gemma-2B et Phi-2 pour le backend GPU, avec des pondérations LoRA applicables uniquement aux couches d'attention. Cette implémentation initiale sert d'API expérimentale pour les développements futurs. Nous prévoyons de prendre en charge davantage de modèles et différents types de couches dans les prochaines mises à jour.

Préparer des modèles de LoRA

Suivez les instructions sur HuggingFace pour entraîner un modèle LoRA affiné sur votre propre ensemble de données avec les 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 LLM Inference n'est compatible qu'avec les couches d'attention (LLM Inference), vous ne devez spécifier que les couches d'attention lors de la création d'une 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 réglés et affinés accessibles publiquement, qui s'adaptent à l'API LLM Inference disponible 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 l'entraînement sur l'ensemble de données préparé et l'enregistrement du modèle, vous obtenez un fichier adapter_model.safetensors contenant les pondérations du modèle LoRA affinées. Le fichier safetensors correspond au point de contrôle LoRA utilisé dans la conversion du modèle.

À l'étape suivante, vous devez convertir les pondérations du modèle en un Flatbuffer TensorFlow Lite à l'aide du package Python MediaPipe. L'élément ConversionConfig doit spécifier les options du modèle de base ainsi que d'autres options de LoRA. Notez que, 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 affiche deux fichiers de tampon plat TFLite, l'un pour le modèle de base et l'autre pour le modèle LoRA.

Inférence de modèle LoRA

L'API LLM Inference Web, Android et iOS a été mise à jour pour assurer la compatibilité avec l'inférence de modèle LoRA. Le Web prend en charge des modèles de LoRA dynamiques, qui peuvent changer de modèle de LoRA pendant l'exécution. Android et iOS prennent en charge la fonctionnalité LoRA statique, qui utilise les mêmes pondérations LoRA pendant la durée de vie de la tâche.

iOS prend en charge la fonctionnalité LoRA statique pendant l'initialisation. Pour charger un modèle LoRA, les utilisateurs doivent spécifier le chemin d'accès au modèle LoRA ainsi que le LLM de 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)

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