GenAI Summarization API

ML Kit の GenAI Summarization API を使用すると、記事や会話の要約を箇条書きのリストとして自動的に生成できます。これにより、ユーザーは長いテキストを理解しやすくなります。

要約は、データ プライバシーと費用対効果に関する懸念に対処できるため、デバイス上の生成 AI のメリットを活用できます。個人的なチャット、メール、メモ、リマインダーを要約するアプリは、機密情報を扱うことが多く、ユーザーのプライバシー保護のためにデバイス上の処理が重要になります。また、要約タスク(特にコンテキストが長いタスクやアイテムが多いタスク)では、大量の処理能力が必要になる場合があります。デバイスでこのコンテンツを処理すると、サーバー負荷が軽減され、サービング コストが削減されるとともに、ユーザーデータのプライバシーが保護されます。

主な機能

GenAI Summarization API には、次の機能があります。

  • 記事または会話として分類されたテキストを要約します。
  • 1、2、または 3 つの箇条書きで要約を出力します。

使ってみる

ML Kit の要約 API を build.gradle 構成の依存関係として追加します。

implementation("com.google.mlkit:genai-summarization:1.0.0-beta1")

次に、プロジェクトにコードを実装します。

  1. Summarizer オブジェクトを作成します。
  2. ダウンロード可能な場合は、機能をダウンロードします。
  3. 要約リクエストを作成します。
  4. 推論を実行して結果を取得します。

Kotlin

val articleToSummarize = "Announcing a set of on-device GenAI APIs..."

// Define task with required input type, output type, and language
val summarizerOptions = SummarizerOptions.builder(context)
    .setInputType(InputType.ARTICLE)
    .setOutputType(OutputType.ONE_BULLET)
    .setLanguage(Language.ENGLISH)
    .build()
val summarizer = Summarization.getClient(summarizerOptions)

suspend fun prepareAndStartSummarization() {
    // Check feature availability. Status will be one of the following:
    // UNAVAILABLE, DOWNLOADABLE, DOWNLOADING, AVAILABLE
    val featureStatus = summarizer.checkFeatureStatus().await()

    if (featureStatus == FeatureStatus.DOWNLOADABLE) {
        // Download feature if necessary. If downloadFeature is not called,
        // the first inference request will also trigger the feature to be
        // downloaded if it's not already downloaded.
        summarizer.downloadFeature(object : DownloadCallback {
            override fun onDownloadStarted(bytesToDownload: Long) { }

            override fun onDownloadFailed(e: GenAiException) { }

            override fun onDownloadProgress(totalBytesDownloaded: Long) {}

            override fun onDownloadCompleted() {
                startSummarizationRequest(articleToSummarize, summarizer)
            }
        })
    } else if (featureStatus == FeatureStatus.DOWNLOADING) {
        // Inference request will automatically run once feature is
        // downloaded. If Gemini Nano is already downloaded on the device,
        // the feature-specific LoRA adapter model will be downloaded
        // quickly. However, if Gemini Nano is not already downloaded, the
        // download process may take longer.
        startSummarizationRequest(articleToSummarize, summarizer)
    } else if (featureStatus == FeatureStatus.AVAILABLE) {
        startSummarizationRequest(articleToSummarize, summarizer)
    }
}

fun startSummarizationRequest(text: String, summarizer: Summarizer) {
    // Create task request
    val summarizationRequest = SummarizationRequest.builder(text).build()

    // Start summarization request with streaming response
    summarizer.runInference(summarizationRequest) { newText ->
        // Show new text in UI
    }

    // You can also get a non-streaming response from the request
    // val summarizationResult = summarizer.runInference(
    //     summarizationRequest).get().summary
}

// Be sure to release the resource when no longer needed
// For example, on viewModel.onCleared() or activity.onDestroy()
summarizer.close()

Java

String articleToSummarize = "Announcing: a set of on-device GenAI AI APIs.";

// Define task with required input type, output type, and language
SummarizerOptions summarizerOptions = 
    SummarizerOptions.builder(context)
        .setInputType(SummarizerOptions.InputType.ARTICLE)
        .setOutputType(SummarizerOptions.OutputType.ONE_BULLET)
        .setLanguage(SummarizerOptions.Language.ENGLISH)
        .build();
Summarizer summarizer = Summarization.getClient(summarizerOptions);

void prepareAndStartSummarization()
        throws ExecutionException, InterruptedException {
    // Check feature availability. Status will be one of the following:
    // UNAVAILABLE, DOWNLOADABLE, DOWNLOADING, AVAILABLE
    try {
        int featureStatus = summarizer.checkFeatureStatus().get();
        if (featureStatus == FeatureStatus.DOWNLOADABLE) {
            // Download feature if necessary.
            // If downloadFeature is not called, the first inference request
            // will also trigger the feature to be downloaded if it's not
            // already downloaded.
            summarizer.downloadFeature(new DownloadCallback() {
                @Override
                public void onDownloadCompleted() {
                    startSummarizationRequest(articleToSummarize, summarizer);
                }

                @Override
                public void onDownloadFailed(GenAiException e) { /* handle error */ }

                @Override
                public void onDownloadProgress(long totalBytesDownloaded) {}

                @Override
                public void onDownloadStarted(long bytesDownloaded) {}
            });
        } else if (featureStatus == FeatureStatus.DOWNLOADING) {
            // Inference request will automatically run once feature is
            // downloaded. If Gemini Nano is already downloaded on the
            // device, the feature-specific LoRA adapter model will be
            // downloaded quickly. However, if Gemini Nano is not already
            // downloaded, the download process may take longer.
            startSummarizationRequest(articleToSummarize, summarizer);
        } else if (featureStatus == FeatureStatus.AVAILABLE) {
            startSummarizationRequest(articleToSummarize, summarizer);
        }
    } catch (ExecutionException | InterruptedException e) {
        e.printStackTrace();
    }
}

void startSummarizationRequest(String text, Summarizer summarizer) {
    // Create task request
    SummarizationRequest summarizationRequest =
        SummarizationRequest.builder(text).build();

    // Start summarization request with streaming response
    summarizer.runInference(summarizationRequest, newText -> {
        // Show new text in UI
    });

    // You can also get a non-streaming response from the request
    // ListenableFuture<SummarizationResult> summarizationResult
    //         = summarizer.runInference(summarizationRequest);
    // String summary = summarizationResult.get().getSummary();
}

// Be sure to release the resource when no longer needed
// For example, on viewModel.onCleared() or activity.onDestroy()
summarizer.close();

モデルがさまざまな入力タイプを処理する方法

テキスト入力が InputType.CONVERSATION として指定されている場合、モデルは次の形式の入力を想定しています。

<name>: <message>
<name2>: <message2>
<name>: <message3>
<name3>: <message4>

これにより、会話とやり取りをより深く理解して、より正確な要約を生成できるようになります。

サポートされている機能と制限事項

入力は 4,000 トークン(約 3,000 語)未満にする必要があります。入力が 4, 000 トークンを超える場合は、次のオプションを検討してください。

  • 最初の 4,000 トークンの要約を優先します。テストの結果、通常は長い入力で良い結果が得られます。余分な入力が自動的に切り捨てられるように、setLongInputAutoTruncationEnabled を呼び出して自動切り捨てを有効にすることを検討してください。
  • 入力を 4, 000 トークンのグループに分割し、個別に要約します。
  • より大きな入力に適したクラウド ソリューションを検討してください。

InputType.ARTICLE の場合も、入力は 400 文字以上にする必要があります。記事の長さが 300 語以上の場合、モデルのパフォーマンスが最も高くなります。

GenAI Summarization API は英語、日本語、韓国語をサポートしており、SummarizerOptions.Language で定義されています。

特定の機能構成(SummarizerOptions で指定)の可用性は、特定のデバイスの構成と、デバイスにダウンロードされているモデルによって異なる場合があります。

デベロッパーが目的の API 機能が、リクエストされた SummarizerOptions を持つデバイスでサポートされていることを確認する最も確実な方法は、checkFeatureStatus() メソッドを呼び出すことです。このメソッドは、実行時にデバイスで利用可能な機能の確定ステータスを提供します。

セットアップに関する一般的な問題

ML Kit の生成 AI API は、Android AICore アプリを使用して Gemini Nano にアクセスします。デバイスのセットアップ(リセットを含む)が完了したばかりの場合や、AICore アプリがリセットされたばかりの場合(データの消去、アンインストール、再インストールなど)、AICore アプリが初期化(サーバーから最新の構成のダウンロードなど)を完了するまでに時間がかかることがあります。その結果、ML Kit GenAI API が想定どおりに機能しない可能性があります。セットアップ時に表示される一般的なエラー メッセージとその対処方法は次のとおりです。

エラー メッセージの例 対応方法
AICore がエラータイプ 4-CONNECTION_ERROR とエラーコード 601-BINDING_FAILURE で失敗しました。AICore サービスがバインディングに失敗しました。 これは、デバイスのセットアップ直後に ML Kit GenAI API を使用してアプリをインストールした場合や、アプリのインストール後に AICore がアンインストールされた場合に発生する可能性があります。AICore アプリを更新してからアプリを再インストールすると、問題は解決するはずです。
AICore がエラータイプ 3-PREPARATION_ERROR とエラーコード 606-FEATURE_NOT_FOUND で失敗しました。機能... は使用できません。 これは、AICore が最新の構成のダウンロードを完了していない場合に発生することがあります。ネットワーク接続を維持し、数分間から数時間待ちます。

デバイスのブートローダーがロック解除されている場合も、このエラーが表示されます。この API は、ブートローダーがロック解除されているデバイスをサポートしていません。
AICore がエラータイプ 1-DOWNLOAD_ERROR で失敗し、エラーコード 0-UNKNOWN: Feature ... が失敗し、失敗ステータス 0 とエラー esz: UNAVAILABLE: Unable to resolve host ... が返されました ネットワーク接続を維持し、数分待ってから再試行します。