LLM Inference API を使用すると、Android アプリケーションで大規模言語モデル(LLM)を完全にオンデバイスで実行できます。これにより、テキストの生成、自然言語形式での情報の取得、ドキュメントの要約など、さまざまなタスクを実行できます。このタスクは、複数のテキスト間大規模言語モデルを組み込みでサポートしているため、最新のオンデバイス生成 AI モデルを Android アプリに適用できます。
LLM 推論 API を Android アプリケーションにすばやく追加するには、クイックスタートに沿って操作します。LLM 推論 API を実行する Android アプリケーションの基本的な例については、サンプル アプリケーションをご覧ください。LLM 推論 API の仕組みについて詳しくは、構成オプション、モデル変換、LoRA チューニングの各セクションをご覧ください。
このタスクの動作については、MediaPipe Studio デモをご覧ください。このタスクの機能、モデル、構成オプションの詳細については、概要をご覧ください。
クイックスタート
LLM Inference API を Android アプリケーションに追加する手順は次のとおりです。LLM 推論 API は、Google Pixel 8 や Samsung S23 以降などのハイエンド Android デバイス向けに最適化されており、デバイス エミュレータは確実にサポートされません。
依存関係を追加する
LLM Inference API は com.google.mediapipe:tasks-genai ライブラリを使用します。Android アプリの build.gradle ファイルに次の依存関係を追加します。
dependencies {
    implementation 'com.google.mediapipe:tasks-genai:0.10.27'
}
モデルのダウンロード
Hugging Face から 4 ビット量子化形式で Gemma-3 1B をダウンロードします。使用可能なモデルの詳細については、モデルのドキュメントをご覧ください。
output_path フォルダの内容を Android デバイスにプッシュします。
$ 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.task
Task を初期化する
基本的な構成オプションを使用してタスクを初期化します。
// Set the configuration options for the LLM Inference task
val taskOptions = LlmInferenceOptions.builder()
        .setModelPath('/data/local/tmp/llm/model_version.task')
        .setMaxTopK(64)
        .build()
// Create an instance of the LLM Inference task
llmInference = LlmInference.createFromOptions(context, taskOptions)
タスクを実行する
generateResponse() メソッドを使用してテキスト レスポンスを生成します。これにより、1 つの生成されたレスポンスが生成されます。
val result = llmInference.generateResponse(inputPrompt)
logger.atInfo().log("result: $result")
レスポンスをストリーミングするには、generateResponseAsync() メソッドを使用します。
val options = LlmInference.LlmInferenceOptions.builder()
  ...
  .setResultListener { partialResult, done ->
    logger.atInfo().log("partial result: $partialResult")
  }
  .build()
llmInference.generateResponseAsync(inputPrompt)
サンプル アプリケーション
LLM 推論 API の動作を確認し、包括的なオンデバイス生成 AI 機能について調べるには、Google AI Edge Gallery アプリをご覧ください。
Google AI Edge Gallery は、デベロッパー向けのインタラクティブなプレイグラウンドとして機能するオープンソースの Android アプリケーションです。このショーケースでは、次のことを紹介します。
- LLM Inference API をさまざまなタスクに使用する実践的な例(次を含む)。
- 画像に関する質問: 画像をアップロードして、それについて質問します。説明を取得したり、問題を解決したり、オブジェクトを識別したりできます。
 - プロンプト ラボ: 要約、書き換え、コードの生成、自由形式のプロンプトを使用して、単一ターンの LLM ユースケースを試すことができます。
 - AI チャット: マルチターンの会話を行います。
 
 - Hugging Face LiteRT コミュニティと Google の公式リリース(Gemma 3N など)から、さまざまな LiteRT 最適化モデルを見つけてダウンロードし、テストできる。
 - さまざまなモデルのオンデバイス パフォーマンスのリアルタイム ベンチマーク(最初のトークンまでの時間、デコード速度など)。
 - 独自のカスタム 
.litertlmモデルまたは.taskモデルをインポートしてテストする方法。 
このアプリは、LLM 推論 API の実用的な実装と、オンデバイスの生成 AI の可能性を理解するためのリソースです。ソースコードを確認し、 Google AI Edge Gallery GitHub リポジトリからアプリをダウンロードします。
設定オプション
次の構成オプションを使用して、Android アプリを設定します。
| オプション名 | 説明 | 値の範囲 | デフォルト値 | 
|---|---|---|---|
modelPath | 
      モデルが保存されているプロジェクト ディレクトリ内のパス。 | 経路 | なし | 
maxTokens | 
      モデルが処理するトークン(入力トークン + 出力トークン)の最大数。 | Integer | 512 | 
topK | 
      モデルが生成の各ステップで考慮するトークンの数。予測を最も確率の高い上位 k 個のトークンに制限します。 | Integer | 40 | 
temperature | 
      生成時に導入されるランダム性の量。温度が高いほど、生成されるテキストの創造性が高くなります。温度が低いほど、予測可能な生成が行われます。 | 浮動小数点数 | 0.8 | 
randomSeed | 
      テキスト生成中に使用されるランダム シード。 | Integer | 0 | 
loraPath | 
    デバイス上の LoRA モデルの絶対パス。注: これは GPU モデルとのみ互換性があります。 | 経路 | なし | 
resultListener | 
      結果を非同期で受け取るように結果リスナーを設定します。非同期生成メソッドを使用している場合にのみ適用されます。 | なし | なし | 
errorListener | 
      オプションのエラー リスナーを設定します。 | なし | なし | 
マルチモーダル プロンプト
LLM Inference API Android API は、テキスト、画像、音声の入力を受け付けるモデルを使用したマルチモーダル プロンプトをサポートしています。マルチモーダルを有効にすると、ユーザーはプロンプトに画像とテキスト、音声とテキストの組み合わせを含めることができます。LLM はテキスト レスポンスを返します。
まず、MediaPipe 互換の Gemma 3n のバリアントを使用します。
- Gemma-3n E2B: Gemma-3n ファミリーの有効な 2B モデル。
 - Gemma-3n E4B: Gemma-3n ファミリーの有効な 4B モデル。
 
詳細については、Gemma-3n のドキュメントをご覧ください。
次の手順に沿って、LLM 推論 API の画像入力または音声入力を有効にします。
画像入力
プロンプト内で画像を提供するには、入力画像またはフレームを com.google.mediapipe.framework.image.MPImage オブジェクトに変換してから、LLM 推論 API に渡します。
import com.google.mediapipe.framework.image.BitmapImageBuilder
import com.google.mediapipe.framework.image.MPImage
// Convert the input Bitmap object to an MPImage object to run inference
val mpImage = BitmapImageBuilder(image).build()
LLM 推論 API のビジョン サポートを有効にするには、グラフ オプション内で EnableVisionModality 構成オプションを true に設定します。
LlmInferenceSession.LlmInferenceSessionOptions sessionOptions =
  LlmInferenceSession.LlmInferenceSessionOptions.builder()
    ...
    .setGraphOptions(GraphOptions.builder().setEnableVisionModality(true).build())
    .build();
セッションあたりの画像の最大数を 10 に設定します。
LlmInferenceOptions options = LlmInferenceOptions.builder()
  ...
  .setMaxNumImages(10)
  .build();
以下は、ビジョン入力とテキスト入力を処理するように設定された LLM 推論 API の実装例です。
MPImage image = getImageFromAsset(BURGER_IMAGE);
LlmInferenceSession.LlmInferenceSessionOptions sessionOptions =
  LlmInferenceSession.LlmInferenceSessionOptions.builder()
    .setTopK(10)
    .setTemperature(0.4f)
    .setGraphOptions(GraphOptions.builder().setEnableVisionModality(true).build())
    .build();
try (LlmInference llmInference =
    LlmInference.createFromOptions(ApplicationProvider.getApplicationContext(), options);
  LlmInferenceSession session =
    LlmInferenceSession.createFromOptions(llmInference, sessionOptions)) {
  session.addQueryChunk("Describe the objects in the image.");
  session.addImage(image);
  String result = session.generateResponse();
}
音声入力
LlmInferenceOptions で音声サポートを有効にする
val inferenceOptions = LlmInference.LlmInferenceOptions.builder()
  ...
  .setAudioModelOptions(AudioModelOptions.builder().build())
  .build()
sessionOptions で音声サポートを有効にする
    val sessionOptions =  LlmInferenceSessionOptions.builder()
      ...
      .setGraphOptions(GraphOptions.builder().setEnableAudioModality(true).build())
      .build()
推論中に音声データを送信します。注: 音声は .wav 形式のモノラル チャンネルである必要があります
val audioData: ByteArray = ...
inferenceEngine.llmInferenceSession.addAudio(audioData)
以下は、音声入力とテキスト入力を処理するように設定された LLM 推論 API の実装例です。
val audioData: ByteArray = ...
val inferenceOptions = LlmInference.LlmInferenceOptions.builder()
  ...
  .setAudioModelOptions(AudioModelOptions.builder().build())
  .build()
val sessionOptions =  LlmInferenceSessionOptions.builder()
  ...
  .setGraphOptions(GraphOptions.builder().setEnableAudioModality(true).build())
  .build()
LlmInference.createFromOptions(context, inferenceOptions).use { llmInference ->
  LlmInferenceSession.createFromOptions(llmInference, sessionOptions).use { session ->
    session.addQueryChunk("Transcribe the following speech segment:")
    session.addAudio(audioData)
    val result = session.generateResponse()
  }
}
LoRA のカスタマイズ
LLM Inference API は、PEFT(パラメータ エフィシエント ファインチューニング)ライブラリを使用した LoRA(Low-Rank Adaptation)チューニングをサポートしています。LoRA チューニングは、費用対効果の高いトレーニング プロセスを通じて LLM の動作をカスタマイズします。モデル全体を再トレーニングするのではなく、新しいトレーニング データに基づいてトレーニング可能な重みの小さなセットを作成します。
LLM Inference API は、Gemma-2 2B、Gemma 2B、Phi-2 モデルのアテンション レイヤに LoRA 重みを追加することをサポートしています。モデルを safetensors 形式でダウンロードします。
LoRA 重みを作成するには、ベースモデルが safetensors 形式である必要があります。LoRA トレーニングの後、モデルを FlatBuffers 形式に変換して MediaPipe で実行できます。
LoRA 重みを準備する
PEFT の LoRA メソッドガイドを使用して、独自のデータセットでファインチューニングされた LoRA モデルをトレーニングします。
LLM 推論 API はアテンション レイヤでの LoRA のみをサポートしているため、LoraConfig でアテンション レイヤのみを指定します。
# For Gemma
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"],
)
準備したデータセットでトレーニングを行い、モデルを保存すると、ファインチューニングされた LoRA モデルの重みが adapter_model.safetensors で使用できるようになります。safetensors ファイルは、モデル変換中に使用される LoRA チェックポイントです。
モデル変換
MediaPipe Python パッケージを使用して、モデルの重みを Flatbuffer 形式に変換します。ConversionConfig には、ベースモデル オプションと追加の LoRA オプションを指定します。
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_FILE,
)
converter.convert_checkpoint(config)
コンバータは、ベースモデル用と LoRA モデル用の 2 つの Flatbuffer ファイルを生成します。
LoRA モデルの推論
Android は、初期化中に静的 LoRA をサポートします。LoRA モデルを読み込むには、LoRA モデルのパスとベース LLM を指定します。
// Set the configuration options for the LLM Inference task
val options = LlmInferenceOptions.builder()
        .setModelPath(BASE_MODEL_PATH)
        .setMaxTokens(1000)
        .setTopK(40)
        .setTemperature(0.8)
        .setRandomSeed(101)
        .setLoraPath(LORA_MODEL_PATH)
        .build()
// Create an instance of the LLM Inference task
llmInference = LlmInference.createFromOptions(context, options)
LoRA で LLM 推論を実行するには、ベースモデルと同じ generateResponse() または generateResponseAsync() メソッドを使用します。