GenAI Summarization API

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

要約は、データ プライバシーと費用対効果に関する懸念に対処するため、デバイス上の生成 AI のメリットを享受できます。個人チャット、メール、メモ、リマインダーを要約するアプリは、機密情報を扱うことが多いため、ユーザーのプライバシーを保護するうえでオンデバイス処理が重要になります。また、要約タスク、特にコンテキストが長いタスクやアイテムが多いタスクでは、かなりの処理能力が必要になることがあります。このコンテンツをデバイスで処理することで、サーバーの負荷を軽減し、配信コストを削減しながら、ユーザーデータのプライバシーを維持できます。

主な機能

GenAI Summarization API は、次の機能を対象としています。

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

始める

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

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 要約 API は英語、日本語、韓国語をサポートしており、SummarizerOptions.Language で定義されています。

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

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

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

ML Kit GenAI 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)で失敗しました。機能 ... が失敗ステータス 0 とエラー esz(UNAVAILABLE: Unable to resolve host ...)で失敗しました。 ネットワーク接続を維持し、数分待ってから再試行します。