GenAI Summarization API

באמצעות GenAI Summarization API של ML Kit, אפשר ליצור באופן אוטומטי סיכומים של מאמרים ושיחות כרשימת נקודות. כך המשתמשים יכולים להבין טוב יותר טקסטים ארוכים.

סיכומים נהנים מהיתרונות של בינה מלאכותית גנרטיבית במכשיר, כי היא פותרת את הבעיות שקשורות לפרטיות הנתונים וליעילות העלויות. אפליקציות שמסכמות שיחות אישיות, אימיילים, הערות ותזכורות לעיתים קרובות מטפלות במידע רגיש, ולכן חשוב שהעיבוד יתבצע במכשיר כדי לשמור על פרטיות המשתמשים. בנוסף, משימות סיכום, במיוחד משימות עם הקשרים ארוכים או עם הרבה פריטים, עשויות לדרוש כוח עיבוד משמעותי. עיבוד התוכן הזה במכשיר מפחית את העומס על השרת ומוריד את עלויות ההצגה, תוך שמירה על פרטיות נתוני המשתמשים.

יכולות עיקריות

ה-API של GenAI Summarization מכסה את היכולות הבאות:

  • סיכום טקסט, מסווג כמאמר או כשיחה.
  • סיכום הפלט בנקודה אחת, בשתי נקודות או בשלוש נקודות.

שנתחיל?

מוסיפים את ML Kit summarization 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 מילים.

ה-API של GenAI Summarization תומך באנגלית, ביפנית ובקוריאנית, והוא מוגדר בקובץ SummarizerOptions.Language.

הזמינות של הגדרת התכונה הספציפית (שצוינה על ידי SummarizerOptions) עשויה להשתנות בהתאם לתצורה של המכשיר הספציפי ולדגמים שהורדתם למכשיר.

הדרך הבטוחה ביותר למפתחים לוודא שתכונה מסוימת של ה-API נתמכת במכשיר עם SummarizerOptions המבוקש היא לבצע קריאה ל-method‏ checkFeatureStatus(). השיטה הזו מספקת את הסטטוס המוחלט של זמינות התכונה במכשיר בזמן הריצה.

בעיות נפוצות בהגדרה

ממשקי ה-API של ML Kit GenAI מסתמכים על אפליקציית Android AICore כדי לגשת ל-Gemini Nano. כשמכשיר מוגדר זה עתה (כולל איפוס), או שאפליקציית AICore אופסה זה עתה (למשל, ניקוי הנתונים, הסרה והתקנה מחדש), יכול להיות שלא יהיה לאפליקציית AICore מספיק זמן לסיים את האיפוס (כולל הורדת ההגדרות האחרונות מהשרת). כתוצאה מכך, יכול להיות ש-ML Kit GenAI APIs לא יפעלו כמצופה. ריכזנו כאן את הודעות השגיאה הנפוצות במהלך ההגדרה ואת הדרכים לטיפול בהן:

דוגמה להודעת שגיאה איך מטפלים
AICore נכשל עם סוג השגיאה 4-CONNECTION_ERROR וקוד השגיאה 601-BINDING_FAILURE: שירות AICore נכשל בקישור. זה יכול לקרות אם מתקינים את האפליקציה באמצעות ממשקי ה-API של ML Kit GenAI מיד אחרי הגדרת המכשיר, או אם מסירים את AICore אחרי התקנת האפליקציה. כדי לפתור את הבעיה, צריך לעדכן את אפליקציית AICore ולאחר מכן להתקין מחדש את האפליקציה.
AICore נכשל עם שגיאת מסוג 3-PREPARATION_ERROR וקוד השגיאה 606-FEATURE_NOT_FOUND: התכונה ... לא זמינה. המצב הזה יכול לקרות אם AICore לא סיים להוריד את ההגדרות האחרונות. שומרים על חיבור לרשת ומחכים כמה דקות עד כמה שעות.

שימו לב: אם נעילת האתחול של המכשיר לא נעולה, תופיע גם השגיאה הזו – ממשק ה-API הזה לא תומך במכשירים עם נעילת אתחול לא נעולה.
AICore נכשל עם סוג השגיאה 1-DOWNLOAD_ERROR וקוד השגיאה 0-UNKNOWN: Feature ... failed with failure status 0 and error esz: UNAVAILABLE: Unable to resolve host ... שומרים על החיבור לרשת, ממתינים כמה דקות ומנסים שוב.