LLM-Inferenzleitfaden für Android

Mit der LLM Inference API können Sie Large Language Models (LLMs) für Android-Anwendungen vollständig auf dem Gerät ausführen und damit eine Vielzahl von Aufgaben ausführen, z. B. Text generieren, Informationen in natürlicher Sprache abrufen und Dokumente zusammenfassen. Die Aufgabe bietet integrierte Unterstützung für mehrere Large Language Models (Text-zu-Text), sodass Sie die neuesten generativen KI-Modelle auf dem Gerät auf Ihre Android-Apps anwenden können.

Die Aufgabe unterstützt Gemma 2B, einen Teil einer Familie von einfachen, modernen offenen Modellen, die auf derselben Forschung und Technologie basieren wie die Gemini-Modelle. Außerdem unterstützt es die folgenden externen Modelle: Phi-2, Falcon-RW-1B und StableLM-3B sowie alle Modelle, die über AI Edge exportiert werden.

Weitere Informationen zu den Funktionen, Modellen und Konfigurationsoptionen dieser Aufgabe finden Sie in der Übersicht.

Codebeispiel

Dieser Leitfaden bezieht sich auf ein Beispiel für eine einfache App zur Textgenerierung für Android. Du kannst die App als Ausgangspunkt für deine eigene Android-App verwenden oder beim Ändern einer vorhandenen App darauf zurückgreifen. Der Beispielcode wird auf GitHub gehostet.

Code herunterladen

In der folgenden Anleitung erfahren Sie, wie Sie mit dem git-Befehlszeilentool eine lokale Kopie des Beispielcodes erstellen.

So laden Sie den Beispielcode herunter:

  1. Klonen Sie das Git-Repository mit dem folgenden Befehl:
    git clone https://github.com/google-ai-edge/mediapipe-samples
    
  2. Konfigurieren Sie optional die Git-Instanz für die Verwendung von Sparse Checkout, sodass Sie nur die Dateien für die Beispielanwendung der LLM Inference API haben:
    cd mediapipe
    git sparse-checkout init --cone
    git sparse-checkout set examples/llm_inference/android
    

Nachdem Sie eine lokale Version des Beispielcodes erstellt haben, können Sie das Projekt in Android Studio importieren und die App ausführen. Eine Anleitung finden Sie im Einrichtungsleitfaden für Android.

Einrichtung

In diesem Abschnitt werden die wichtigsten Schritte zum Einrichten Ihrer Entwicklungsumgebung und Codeprojekte speziell für die Verwendung der LLM Inference API beschrieben. Allgemeine Informationen zum Einrichten der Entwicklungsumgebung für die Verwendung von MediaPipe-Aufgaben, einschließlich der Anforderungen an die Plattformversion, finden Sie im Einrichtungsleitfaden für Android.

Abhängigkeiten

Die LLM Inference API verwendet die com.google.mediapipe:tasks-genai-Bibliothek. Füge diese Abhängigkeit in die Datei build.gradle deiner Android-App ein:

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

Modell

Die MediaPipe LLM Inference API erfordert ein trainiertes Text-zu-Text-Sprachmodell, das mit dieser Aufgabe kompatibel ist. Installieren Sie nach dem Herunterladen eines Modells die erforderlichen Abhängigkeiten und übertragen Sie das Modell auf das Android-Gerät. Wenn Sie ein anderes Modell als Gemma verwenden, müssen Sie das Modell in ein Format konvertieren, das mit MediaPipe kompatibel ist.

Weitere Informationen zu verfügbaren trainierten Modellen für die LLM Inference API finden Sie in der Aufgabenübersicht im Abschnitt „Modelle“.

Modell herunterladen

Laden Sie vor dem Initialisieren der LLM Inference API eines der unterstützten Modelle herunter und speichern Sie die Datei in Ihrem Projektverzeichnis:

  • Gemma 2B: Teil einer Familie von leichten, modernen offenen Modellen, die auf derselben Forschung und Technologie basieren, die auch zum Erstellen der Gemini-Modelle verwendet werden. Eignet sich gut für eine Vielzahl von Aufgaben zur Textgenerierung, einschließlich Fragenbeantwortung, Zusammenfassung und Logik.
  • Phi-2: Transformer-Modell mit 2, 7 Milliarden Parametern, das sich am besten für das Frage-Antwort-, Chat- und Codeformat eignet.
  • Falcon-RW-1B: 1 Milliarde Parametermodell, das nur mit kausalen Decodern arbeitet und mit 350 Mrd. Tokens von RefinedWeb trainiert wurde.
  • StableLM-3B: 3 Milliarden Sprachmodell für Decodierer, das mit 1 Billion Tokens verschiedener Englisch- und Code-Datasets vortrainiert wurde.

Alternativ können Sie Modelle verwenden, die über AI Edge Troch zugeordnet und exportiert wurden.

Wir empfehlen Gemma 2B, das für Kaggle-Modelle verfügbar ist und in einem Format verfügbar ist, das bereits mit der LLM Inference API kompatibel ist. Wenn Sie ein anderes LLM verwenden, müssen Sie das Modell in ein MediaPipe-kompatibles Format konvertieren. Weitere Informationen zu Gemma 2B finden Sie auf der Gemma-Website. Weitere Informationen zu den anderen verfügbaren Modellen finden Sie in der Aufgabenübersicht im Abschnitt „Modelle“.

Modell in das MediaPipe-Format konvertieren

Conversion für natives Modell

Wenn Sie ein externes LLM (Phi-2, Falcon oder StableLM) oder eine Nicht-Kaggle-Version von Gemma verwenden, formatieren Sie das Modell mithilfe unserer Konvertierungsskripts so, dass es mit MediaPipe kompatibel ist.

Für den Modellkonvertierungsprozess ist das MediaPipe-PyPI-Paket erforderlich. Das Konvertierungsskript ist nach dem 0.10.11 in allen MediaPipe-Paketen verfügbar.

Installieren und importieren Sie die Abhängigkeiten mit Folgendem:

$ python3 -m pip install mediapipe

Verwenden Sie die genai.converter-Bibliothek, um das Modell zu konvertieren:

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)

Zum Konvertieren des LoRA-Modells sollten in ConversionConfig die Basismodelloptionen sowie zusätzliche LoRA-Optionen angegeben werden. Da die API nur LoRA-Inferenz mit GPU unterstützt, muss das Back-End auf 'gpu' festgelegt werden.

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)

Der Converter gibt zwei TFLite-Flatbuffer-Dateien aus, eine für das Basismodell und eine für das LoRA-Modell.

Parameter Beschreibung Zulässige Werte
input_ckpt Der Pfad zur Datei model.safetensors oder pytorch.bin. Beachten Sie, dass das Safetensors-Format für das Modell manchmal in mehrere Dateien fragmentiert wird, z.B. model-00001-of-00003.safetensors, model-00001-of-00003.safetensors. Sie können ein Dateimuster wie model*.safetensors angeben. PATH
ckpt_format Das Modelldateiformat. {"safetensors", "pytorch"}
model_type Das LLM, das konvertiert wird. {"PHI_2", "FALCON_RW_1B", "STABLELM_4E1T_3B", "GEMMA_2B"}
backend Der Prozessor (Bevollmächtigte), der zum Ausführen des Modells verwendet wird. {"cpu", "gpu"}
output_dir Der Pfad zum Ausgabeverzeichnis, in dem die Gewichtungsdateien pro Ebene gehostet werden. PATH
output_tflite_file Der Pfad zur Ausgabedatei. Zum Beispiel: "model_cpu.bin" oder "model_gpu.bin". Diese Datei ist nur mit der LLM Inference API kompatibel und kann nicht als allgemeine TFlite-Datei verwendet werden. PATH
vocab_model_file Der Pfad zu dem Verzeichnis, in dem die Dateien tokenizer.json und tokenizer_config.json gespeichert sind. Verweisen Sie bei Gemma auf die einzelne Datei tokenizer.model. PATH
lora_ckpt Der Pfad zur LoRA-ckpt der Safetensors-Datei, in der die Gewichtung des LoRA-Adapters gespeichert ist. PATH
lora_rank Eine Ganzzahl, die den Rang von LoRA ckpt darstellt. Erforderlich für die Umrechnung der Lora-Gewichtungen. Wenn nicht angegeben, geht der Conversion-Wert davon aus, dass keine LoRA-Gewichtungen vorhanden sind. Hinweis: Nur das GPU-Backend unterstützt LoRA. Integer
lora_output_tflite_file Ausgabe des TFlite-Dateinamens für die LoRA-Gewichtungen. PATH

AI Edge-Modellkonvertierung

Wenn Sie ein LLM verwenden, das einem TFLite-Modell über AI Edge zugeordnet ist, verwenden Sie unser Bündelungsskript, um ein Task Bundle zu erstellen. Bei der Bündelung wird das zugeordnete Modell mit zusätzlichen Metadaten verpackt (z.B. Tokenizer-Parameter) erforderlich sind, um End-to-End-Inferenzen auszuführen.

Für den Modellbündelungsprozess ist das MediaPipe-PyPI-Paket erforderlich. Das Konvertierungsskript ist nach dem 0.10.14 in allen MediaPipe-Paketen verfügbar.

Installieren und importieren Sie die Abhängigkeiten mit Folgendem:

$ python3 -m pip install mediapipe

Verwende die genai.bundler-Bibliothek, um das Modell zu bündeln:

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)
Parameter Beschreibung Zulässige Werte
tflite_model Der Pfad zum exportierten AI Edge-TFLite-Modell. PATH
tokenizer_model Der Pfad zum SentencePiece-Tokenizer-Modell. PATH
start_token Modellspezifisches Starttoken. Das Starttoken muss im angegebenen Tokenizer-Modell vorhanden sein. STRING
stop_tokens Modellspezifische Stopptokens. Die Stopptokens müssen im angegebenen Tokenizer-Modell vorhanden sein. LISTE[STRING]
output_filename Der Name der Ausgabe-Task-Bundle-Datei. PATH

Modell auf Gerät übertragen

Übertragen Sie den Inhalt des Ordners output_path auf das Android-Gerät.

$ 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

Aufgabe erstellen

Die MediaPipe LLM Inference API verwendet die Funktion createFromOptions(), um die Aufgabe einzurichten. Die Funktion createFromOptions() akzeptiert Werte für die Konfigurationsoptionen. Weitere Informationen zu Konfigurationsoptionen finden Sie unter Konfigurationsoptionen.

Mit dem folgenden Code wird die Aufgabe mit grundlegenden Konfigurationsoptionen initialisiert:

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

Konfigurationsoptionen

Verwenden Sie die folgenden Konfigurationsoptionen, um eine Android-App einzurichten:

Option Beschreibung Wertebereich Standardwert
modelPath Der Pfad zum Speicherort des Modells im Projektverzeichnis. PATH
maxTokens Die maximale Anzahl von Tokens (Eingabe- und Ausgabetokens), die das Modell verarbeitet. Integer 512
topK Die Anzahl der Tokens, die das Modell bei jedem Generierungsschritt berücksichtigt. Beschränkt die Vorhersagen auf die k wahrscheinlichsten Tokens. Beim Festlegen von topK müssen Sie auch einen Wert für randomSeed festlegen. Integer 40
temperature Das Ausmaß der Zufälligkeit, die während der Generierung eingeführt wird. Eine höhere Temperatur ermöglicht mehr Kreativität im generierten Text, während eine niedrigere Temperatur eine vorhersehbarere Generierung des Textes ermöglicht. Beim Festlegen von temperature müssen Sie auch einen Wert für randomSeed festlegen. Gleitkommazahl 0,8
randomSeed Der zufällige Startwert, der bei der Textgenerierung verwendet wird. Integer 0
loraPath Der absolute Pfad zum LoRA-Modell lokal auf dem Gerät. Hinweis: Dies ist nur mit GPU-Modellen kompatibel. PATH
resultListener Legt den Ergebnis-Listener fest, um die Ergebnisse asynchron zu empfangen. Gilt nur bei Verwendung der asynchronen Generierungsmethode.
errorListener Legt einen optionalen Fehler-Listener fest.

Daten vorbereiten

Die LLM Inference API akzeptiert die folgenden Eingaben:

  • prompt (String): eine Frage oder ein Prompt.
val inputPrompt = "Compose an email to remind Brett of lunch plans at noon on Saturday."

Task ausführen

Verwenden Sie die Methode generateResponse(), um eine Textantwort auf den im vorherigen Abschnitt (inputPrompt) angegebenen Eingabetext zu generieren. Dadurch wird eine einzelne generierte Antwort erzeugt.

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

Verwenden Sie zum Streamen der Antwort die Methode generateResponseAsync().

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

llmInference.generateResponseAsync(inputPrompt)

Ergebnisse verarbeiten und anzeigen

Die LLM Inference API gibt einen LlmInferenceResult zurück, der den generierten Antworttext enthält.

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]

LoRA-Modellanpassung

Die Mediapipe LLM Inference API kann so konfiguriert werden, dass sie Low-Rank Adaptation (LoRA) für Large Language Models unterstützt. Mit fein abgestimmten LoRA-Modellen können Entwickler das Verhalten von LLMs durch einen kostengünstigen Trainingsprozess anpassen.

Die LoRA-Unterstützung der LLM Inference API funktioniert für Gemma-2B- und Phi-2-Modelle für das GPU-Back-End, wobei die LoRA-Gewichtungen nur für Aufmerksamkeitsebenen gelten. Diese anfängliche Implementierung dient als experimentelle API für zukünftige Entwicklungen mit Plänen zur Unterstützung weiterer Modelle und verschiedener Ebenentypen in den kommenden Updates.

LoRA-Modelle vorbereiten

Folgen Sie der Anleitung für HuggingFace, um ein abgestimmtes LoRA-Modell in Ihrem eigenen Dataset mit den unterstützten Modelltypen Gemma-2B oder Phi-2 zu trainieren. Die Modelle Gemma-2B und Phi-2 sind in HuggingFace im Safetensors-Format verfügbar. Da die LLM Inference API LoRA nur auf Aufmerksamkeitsebenen unterstützt, geben Sie beim Erstellen des LoraConfig nur Aufmerksamkeitsebenen an:

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

Für Tests gibt es öffentlich zugängliche, abgestimmte LoRA-Modelle, die auf die LLM Inference API abgestimmt sind, die auf HuggingFace verfügbar sind. Beispiel: monsterapi/gemma-2b-lora-maths-orca-200k für Gemma-2B und lole25/phi-2-sft-ultrachat-lora für Phi-2.

Nachdem Sie mit dem vorbereiteten Dataset trainiert und das Modell gespeichert haben, erhalten Sie eine adapter_model.safetensors-Datei mit den abgestimmten LoRA-Modellgewichtungen. Die Safetensors-Datei ist der LoRA-Prüfpunkt, der bei der Modellkonvertierung verwendet wird.

Im nächsten Schritt müssen Sie die Modellgewichtungen mithilfe des Python-Pakets „MediaPipe“ in einen TensorFlow Lite-Flatbuffer konvertieren. In ConversionConfig sollten die Basismodelloptionen sowie zusätzliche LoRA-Optionen angegeben werden. Da die API nur LoRA-Inferenzen mit GPU unterstützt, muss das Back-End auf 'gpu' festgelegt werden.

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)

Der Converter gibt zwei TFLite-Flatbuffer-Dateien aus, eine für das Basismodell und eine für das LoRA-Modell.

Inferenz des LoRA-Modells

Die Web, Android und iOS LLM Inference API wurde aktualisiert, um die Inferenz des LoRA-Modells zu unterstützen. Das Web unterstützt dynamische LoRA-Modelle, die während der Laufzeit zwischen verschiedenen LoRA-Modellen wechseln können. Android und iOS unterstützen die statische LORA, die während der Lebensdauer der Aufgabe dieselben LoRA-Gewichtungen verwendet.

Android unterstützt die statische LoRA während der Initialisierung. Zum Laden eines LORA-Modells geben Nutzer den LoRA-Modellpfad sowie das Basis-LLM an.

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

Verwenden Sie dieselben Methoden generateResponse() oder generateResponseAsync() wie für das Basismodell, um LLM-Inferenzen mit LoRA auszuführen.