GenAI Summarization API

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

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

主な機能

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

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

始める

build.gradle 構成で、ML Kit Summarization 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 Summarization 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 で失敗しました: ホスト ... を解決できません。 ネットワーク接続を維持し、数分待ってから再試行してください。

サンプルコード