קבלת הטמעות מולטי-מודאליות

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

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

לתרחישי שימוש בהטמעה של טקסט בלבד, מומלץ להשתמש במקום זאת ב-API להטמעת טקסט ב-Gemini Enterprise Agent Platform. לדוגמה, יכול להיות ש-API להטמעת טקסט יהיה טוב יותר לחיפוש סמנטי מבוסס-טקסט, לקיבוץ, לניתוח מסמכים ארוכים ולתרחישי שימוש אחרים של אחזור טקסט או מענה לשאלות. מידע נוסף זמין במאמר בנושא קבלת הטמעות טקסט.

מודלים נתמכים

אפשר לקבל הטמעות מולטימודאליות באמצעות המודלים הבאים:

  • gemini-embedding-2

  • multimodalembedding@001

שיטות מומלצות

כשמשתמשים במודל ההטמעה המולטי-מודאלי, חשוב להביא בחשבון את היבטי הקלט הבאים:

  • טקסט בתמונות – המודל יכול להבחין בין טקסט בתמונות, בדומה לזיהוי תווים אופטי (OCR). אם אתם צריכים להבדיל בין תיאור של תוכן התמונה לבין הטקסט בתוך התמונה, כדאי להשתמש בהנדסת פרומפטים כדי לציין את תוכן היעד. לדוגמה: במקום רק 'חתול', צריך לציין 'תמונה של חתול' או 'הטקסט 'חתול'', בהתאם לתרחיש השימוש.




    הטקסט 'חתול'

    המילה 'חתול' מוצגת בגופן מודגש.
    המילה 'חתול' מוצגת בגופן גדול ומודגש.




    תמונה של חתול

    חתול יושב על רצפת עץ.
    קרדיט על התמונה: Manja Vitolic ב-Unsplash.
  • הטמעה של דמיון – מכפלה סקלרית של הטמעות היא לא הסתברות מכוילת. מכפלה סקלרית היא מדד דמיון, והתפלגות הציונים שלה עשויה להיות שונה בתרחישי שימוש שונים. לכן, לא מומלץ להשתמש בסף ערך קבוע כדי למדוד את האיכות. במקום זאת, אפשר להשתמש בגישות של דירוג לאחזור, או בפונקציית סיגמואיד לסיווג.

שימוש ב-gemini-embedding-2

מודל gemini-embedding-2 מקבל קלט משולב של תמונות, טקסט, מסמכים, אודיו ווידאו.

הגדרת הוראות למשימות כדי לשפר את הביצועים

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

בטבלאות הבאות מוצגות דוגמאות לפורמט של שאילתות ומסמכים לתרחישי שימוש סימטריים ואסימטריים באמצעות מודל gemini-embedding-2.

תרחישי שימוש באחזור (פורמט אסימטרי)

תרחיש שימוש מבנה השאילתה מבנה המסמך
שאילתת חיפוש task: search result | query: {content} title: {title} | text: {content}

אם אין שם, משתמשים ב-title: none.
מענה לשאלות task: question answering | query: {content} title: {title} | text: {content}
בדיקת עובדות task: fact checking | query: {content} title: {title} | text: {content}
אחזור קוד task: code retrieval | query: {content} title: {title} | text: {content}

תרחישים לדוגמה של קלט יחיד (פורמט סימטרי)

תרחיש שימוש מבנה הקלט
סיווג task: classification | query: {content}
סידור באשכולות task: clustering | query: {content}
דמיון סמנטי task: sentence similarity | query: {content}

אל תשתמשו בזה לחיפוש או לאחזור. היא מיועדת לדמיון סמנטי בין טקסטים.

דוגמה לשימוש ב-Python

Python

# Generate embedding for a search query
def prepare_query(query):
    return f"task: search result | query: {query}"

# Generate embedding for a search document
def prepare_document(content, title=None):
    if title is None:
        title = "none"
    return f"title: {title} | text: {content}"

# Generate embedding for classification
def prepare_classification_input(content):
    return f"task: classification | query: {content}"
      

שימוש ב-API

מגבלות API

כשמשתמשים במודל gemini-embedding-2, חלות המגבלות הבאות.

הגבלה ערך ותיאור
נתוני טקסט, תמונות, מסמכים, סרטונים ואודיו
מגבלת טוקנים של קלט ‫8,192 טוקנים

קלט שאורכו יותר מ-8,192 טוקנים נחתך באופן שקט. כל המודאליות חולקות את חלון ההקשר הכולל של 8,192 טוקנים. אסימונים נספרים באופן הבא לפי אופן השימוש:
  • אודיו: 25 טוקנים לשנייה
  • סרטון: 66 טוקנים לכל פריים
  • תמונה: 258 טוקנים לכל תמונה
  • מסמך (PDF): מוצג כתמונה, ולכן 258 טוקנים לכל דף. אם זיהוי התווים האופטי (OCR) מופעל, המערכת מחלצת עוד טוקנים של טקסט.
ממדי הפלט ‫3,072 (ברירת מחדל, אפשר להגדיר באמצעות הפרמטר output_dimensionality)
מגבלות על תמונות ‫6 תמונות לכל בקשה
פורמטים של תמונות ‫JPEG, ‏ PNG, ‏ WebP, ‏ BMP, ‏ HEIC, ‏ HEIF, ‏ AVIF
מידות התמונה מקסימום ‎16,384 x 16,384 פיקסלים לכל תמונה
מגבלות על מסמכים קובץ אחד לכל בקשה, עד 6 עמודים

כדי לקבל את האיכות הכי טובה, מומלץ לשלוח עמוד אחד לכל קובץ PDF.
פורמטים של מסמכים PDF
נתוני וידאו ואודיו
מגבלות על סרטונים סרטון אחד לכל בקשה, עד 120 פריימים

המגבלה של 120 שניות מבוססת על הגדרת ברירת המחדל של 1 FPS. המשך משתנה כשמגדירים קצב פריימים שונה: משך = 120 / קצב פריימים.
כברירת מחדל, חילוץ אודיו מושבת בסרטון. כשהאפשרות לחילוץ טראק אודיו מופעלת, משך הזמן כפוף למשך האודיו המקסימלי של 180 שניות, ומשך נכס הווידאו הכולל מוגבל גם על ידי מגבלת האודיו וגם על ידי חלון ההקשר של הטוקן (8,192 טוקנים).
פורמטים של סרטונים מאגר: MOV, ‏ MP4. קודק: AV1, ‏ H264, ‏ H265, ‏ VP9.
מגבלות אודיו ‫180 שניות לכל בקשה

התמיכה באודיו מותאמת לדיבור. יכול להיות שצלילים ומוזיקה מהסביבה לא יושמעו באיכות הכי גבוהה.
פורמטים של אודיו MP3, ‏ WAV

משך נכס הווידאו עם חילוץ האודיו

מכיוון שכל המודלים חולקים את חלון ההקשר של 8,192 טוקנים, משך נכס הווידאו המקסימלי משתנה כשמפעילים את audio_track_extraction:

מודליות כמות הטוקנים
אודיו ‫25 טוקנים בשנייה
פריים ‫66 טוקנים לכל פריים
חותמות זמן ‫10 טוקנים בשנייה (שני חותמות זמן בשנייה בפורמט mm:ss)
FPS נקבע לפי הגדרת ה-FPS (ברירת המחדל היא 1)

משך נכס הווידאו הכולל מוגבל גם בגלל התמיכה באודיו באורך של עד 180 שניות וגם בגלל חלון ההקשר של 8,192 טוקנים.

חישוב לדוגמה:

אם מעבדים סרטון עם קצב דגימה שמוגדר כברירת מחדל של 1 FPS ומפעילים חילוץ אודיו:

  • קצב הצריכה: כל שנייה של וידאו צורכת 66 טוקנים (פריים אחד) + 25 טוקנים (שנייה אחת של אודיו) + 10 טוקנים (חותמות זמן) = 101 טוקנים.
  • משך הזמן המקסימלי: עם מגבלת 8,192 טוקנים, משך הזמן המקסימלי הוא בערך 8,192 חלקי 101, כלומר כ-81 שניות.

אם הקלט חורג מחלון ההקשר, החלק שחורג ממנו ייחתך ללא הודעה.

יצירת הטמעות מולטי-מודאליות

REST

PROJECT_ID="YOUR_PROJECT_ID"
LOCATION="us"

curl -X POST \
  -H "Authorization: Bearer $(gcloud auth print-access-token)" \
  -H "Content-Type: application/json" \
  "https://aiplatform.${LOCATION}.rep.googleapis.com/v1/projects/${PROJECT_ID}/locations/${LOCATION}/publishers/google/models/gemini-embedding-2:embedContent" \
  -d '{
  "content": {
    "parts": [
      {
        "text": "Whats this"
      },
      {
        "file_data": {
          "mime_type": "video/mp4",
          "file_uri": "gs://cloud-samples-data/generative-ai/video/pixel8.mp4"
        }
      }
    ]
  }
}'
      

Python

from google import genai
from google.genai import types

# Initialize the client.
client = genai.Client(vertexai=True, project="YOUR_PROJECT_ID", location="us")

content = types.Content(
    parts=[
        types.Part.from_text(text="Audio AI"),
        types.Part.from_uri(
            file_uri="gs://cloud-samples-data/generative-ai/audio/Chirp-3-Docs-Dive.mp3",
            mime_type="audio/mpeg",
        ),
    ],
)

response = client.models.embed_content(
    model="gemini-embedding-2",
    contents=[content]
)

print(response.embeddings[0].values)
      

מיקומים

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

מכסות

כדי לבדוק את מגבלת המכסה של gemini-embedding-2, אפשר לעיין במאמר בנושא מכסות ומגבלות מערכת בפלטפורמת הסוכנים.

מידות

כשמשתמשים במודל gemini-embedding-2, אפשר לציין מימדים נמוכים יותר באמצעות הפרמטר output_dimensionality ב-EmbedContentConfig.

בדוגמה הבאה מוחזר וקטור 128-ממדי. ב-gemini-embedding-2, הטמעות הפלט כבר מנורמלות לפי L2 למאפיינים שאינם ברירת מחדל (בניגוד ל-gemini-embedding-001).

Python

import numpy as np
from google import genai
from google.genai import types

# Initialize the client.
client = genai.Client(vertexai=True, project="YOUR_PROJECT_ID", location="us")

content = types.Content(
    parts=[
        types.Part.from_uri(
            file_uri="gs://cloud-samples-data/generative-ai/audio/Chirp-3-Docs-Dive.mp3",
            mime_type="audio/mpeg",
        ),
    ],
)

response = client.models.embed_content(
    model="gemini-embedding-2",
    contents=[content],
    config=types.EmbedContentConfig(output_dimensionality=128),
)

embedding_values_np = np.array(response.embeddings[0].values)

print(f"Embedding length: {len(embedding_values_np)}")
print(f"Norm of embedding: {np.linalg.norm(embedding_values_np):.6f}") # Should be very close to 1
      

פרמטרים

קצב דגימת הווידאו שמוגדר כברירת מחדל הוא פרים אחד לשנייה (FPS). אפשר להוסיף פרמטרים נוספים באמצעות video_metadata:

Python

from google import genai
from google.genai import types

# Initialize the client.
client = genai.Client(vertexai=True, project="YOUR_PROJECT_ID", location="us")

content = types.Content(
    parts=[
        types.Part(
            file_data=types.FileData(
                file_uri="gs://cloud-samples-data/generative-ai/video/pixel8.mp4",
                mime_type="video/mp4",
            ),
            video_metadata=types.VideoMetadata(
                fps=0.5,
                start_offset="10s",
                end_offset="20s",
            ),
        ),
    ]
)

response = client.models.embed_content(
    model="gemini-embedding-2",
    contents=[content]
)

print(response.embeddings[0].values)
      

יש אפשרויות נוספות בEmbedContentConfig.

אפשרות סוג תיאור
output_dimensionality int הפחתת המימד של הטמעת הפלט.
document_ocr bool מפעילים OCR לקלט מסמכים.
audio_track_extraction bool חילוץ אודיו מקלט וידאו.

שימוש ב-multimodalembedding@001

ההגבלות הבאות חלות כשמשתמשים במודל multimodalembedding@001 להטמעות של טקסט ותמונות:

הגבלה ערך ותיאור
נתוני טקסט ותמונה
המספר המקסימלי של בקשות API לדקה לכל פרויקט ‫120-600 בהתאם לאזור
אורך הטקסט המקסימלי ‫32 אסימונים (כ-32 מילים)

אורך הטקסט המקסימלי הוא 32 אסימונים (כ-32 מילים). אם הקלט חורג מ-32 טוקנים, המודל מקצר את הקלט באופן פנימי לאורך הזה.
שפה אנגלית
פורמטים של תמונות BMP, ‏ GIF, ‏ JPG, ‏ PNG
גודל התמונה תמונות בקידוד Base64: ‏ 20MB (כשמבצעים המרה ל-PNG)
תמונות ב-Cloud Storage: ‏ 20MB (פורמט הקובץ המקורי)

הגודל המקסימלי של תמונה שמתקבלת הוא 20MB. כדי למנוע עלייה בחביון ברשת, כדאי להשתמש בתמונות קטנות יותר. בנוסף, המודל משנה את גודל התמונות לרזולוציה של 512x512 פיקסלים. לכן, אין צורך לספק תמונות ברזולוציה גבוהה יותר.
נתוני וידאו
תמיכה באודיו לא רלוונטי – המודל לא מתייחס לתוכן אודיו כשהוא יוצר הטמעות של סרטונים
פורמטים של סרטונים ‫AVI,‏ FLV,‏ MKV,‏ MOV,‏ MP4,‏ MPEG,‏ MPG,‏ WEBM ו-WMV
אורך מקסימלי של סרטון (Cloud Storage) אין מגבלה. עם זאת, אפשר לנתח רק 2 דקות של תוכן בכל פעם.

לפני שמתחילים

  1. נכנסים לחשבון Google Cloud . אנחנו ממליצים למשתמשים חדשים ב- Google Cloud ליצור חשבון כדי שיוכלו להעריך את הביצועים של המוצרים שלנו בתרחישים מהעולם האמיתי. לקוחות חדשים מקבלים בחינם גם קרדיט בשווי 300$ להרצה, לבדיקה ולפריסה של עומסי העבודה.
  2. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Roles required to select or create a project

    • Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
    • Create a project: To create a project, you need the Project Creator role (roles/resourcemanager.projectCreator), which contains the resourcemanager.projects.create permission. Learn how to grant roles.

    Go to project selector

  3. Verify that billing is enabled for your Google Cloud project.

  4. Enable the Gemini Enterprise Agent Platform API, if it is not already enabled.

    Roles required to enable APIs

    To enable APIs, you need the serviceusage.services.enable permission. If you created the project, then you likely already have this permission through the Owner role (roles/owner). Otherwise, you can get this permission through the Service Usage Admin role (roles/serviceusage.serviceUsageAdmin). Learn how to grant roles.

    Enable the API

  5. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Roles required to select or create a project

    • Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
    • Create a project: To create a project, you need the Project Creator role (roles/resourcemanager.projectCreator), which contains the resourcemanager.projects.create permission. Learn how to grant roles.

    Go to project selector

  6. Verify that billing is enabled for your Google Cloud project.

  7. Enable the Gemini Enterprise Agent Platform API, if it is not already enabled.

    Roles required to enable APIs

    To enable APIs, you need the serviceusage.services.enable permission. If you created the project, then you likely already have this permission through the Owner role (roles/owner). Otherwise, you can get this permission through the Service Usage Admin role (roles/serviceusage.serviceUsageAdmin). Learn how to grant roles.

    Enable the API

  8. מגדירים אימות לסביבה.

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

    Java

    כדי להשתמש בדוגמאות של Java שבדף הזה בסביבת פיתוח מקומית, מתקינים ומפעילים את ה-CLI של gcloud, ואז מגדירים את Application Default Credentials באמצעות פרטי הכניסה של המשתמש.

    1. התקינו את ה-CLI של Google Cloud.

    2. אם אתם משתמשים בספק זהויות חיצוני (IdP), קודם אתם צריכים להיכנס ל-CLI של gcloud באמצעות המאגר המאוחד לניהול זהויות.

    3. אחרי שתאתחלו את ה-CLI של gcloud, עדכנו אותו והתקינו את הרכיבים הנדרשים:

      gcloud components update
      gcloud components install beta
    4. אם אתם משתמשים במעטפת מקומית, צריך ליצור פרטי כניסה לאימות מקומי עבור חשבון המשתמש:

      gcloud auth application-default login

      אם אתם משתמשים ב-Cloud Shell, אתם לא צריכים לעשות את זה.

      אם מוחזרת שגיאת אימות ואתם משתמשים בספק זהויות חיצוני (IdP), ודאו ש נכנסתם ל-CLI של gcloud באמצעות המאגר המאוחד לניהול זהויות.

    למידע נוסף, ראו הגדרת ADC לסביבת פיתוח מקומית במאמרי העזרה בנושא אימות Google Cloud .

    Node.js

    כדי להשתמש בדוגמאות של Node.js שבדף הזה בסביבת פיתוח מקומית, מתקינים ומפעילים את ה-CLI של gcloud, ואז מגדירים את Application Default Credentials באמצעות פרטי הכניסה של המשתמש.

    1. התקינו את ה-CLI של Google Cloud.

    2. אם אתם משתמשים בספק זהויות חיצוני (IdP), קודם אתם צריכים להיכנס ל-CLI של gcloud באמצעות המאגר המאוחד לניהול זהויות.

    3. אחרי שתאתחלו את ה-CLI של gcloud, עדכנו אותו והתקינו את הרכיבים הנדרשים:

      gcloud components update
      gcloud components install beta
    4. אם אתם משתמשים במעטפת מקומית, צריך ליצור פרטי כניסה לאימות מקומי עבור חשבון המשתמש:

      gcloud auth application-default login

      אם אתם משתמשים ב-Cloud Shell, אתם לא צריכים לעשות את זה.

      אם מוחזרת שגיאת אימות ואתם משתמשים בספק זהויות חיצוני (IdP), ודאו ש נכנסתם ל-CLI של gcloud באמצעות המאגר המאוחד לניהול זהויות.

    למידע נוסף, ראו הגדרת ADC לסביבת פיתוח מקומית במאמרי העזרה בנושא אימות Google Cloud .

    Python

    כדי להשתמש בסביבת פיתוח מקומית בדוגמאות של Python שבדף הזה, מתקינים ומפעילים את ה-CLI של gcloud, ואז מגדירים את Application Default Credentials באמצעות פרטי הכניסה של המשתמש.

    1. התקינו את ה-CLI של Google Cloud.

    2. אם אתם משתמשים בספק זהויות חיצוני (IdP), קודם אתם צריכים להיכנס ל-CLI של gcloud באמצעות המאגר המאוחד לניהול זהויות.

    3. אחרי שתאתחלו את ה-CLI של gcloud, עדכנו אותו והתקינו את הרכיבים הנדרשים:

      gcloud components update
      gcloud components install beta
    4. אם אתם משתמשים במעטפת מקומית, צריך ליצור פרטי כניסה לאימות מקומי עבור חשבון המשתמש:

      gcloud auth application-default login

      אם אתם משתמשים ב-Cloud Shell, אתם לא צריכים לעשות את זה.

      אם מוחזרת שגיאת אימות ואתם משתמשים בספק זהויות חיצוני (IdP), ודאו ש נכנסתם ל-CLI של gcloud באמצעות המאגר המאוחד לניהול זהויות.

    למידע נוסף, ראו הגדרת ADC לסביבת פיתוח מקומית במאמרי העזרה בנושא אימות Google Cloud .

    REST

    כדי להשתמש בסביבת פיתוח מקומית בדוגמאות של API בארכיטקטורת REST שבדף הזה, צריך להשתמש בפרטי הכניסה שאתם נותנים ל-CLI של gcloud.

    1. התקינו את ה-CLI של Google Cloud.

    2. אם אתם משתמשים בספק זהויות חיצוני (IdP), קודם אתם צריכים להיכנס ל-CLI של gcloud באמצעות המאגר המאוחד לניהול זהויות.

    3. אחרי שתאתחלו את ה-CLI של gcloud, עדכנו אותו והתקינו את הרכיבים הנדרשים:

      gcloud components update
      gcloud components install beta

    מידע נוסף מופיע במאמר אימות לשימוש ב-REST במסמכי האימות של Google Cloud .

  9. כדי להשתמש ב-Python SDK, פועלים לפי ההוראות במאמר התקנת Agent Platform SDK ל-Python. מידע נוסף מופיע במאמרי העזרה של Agent Platform SDK for Python API.
  10. זה שינוי אופציונלי. כאן אפשר לראות את המחירים של התכונה הזו. התמחור של הטמעות תלוי בסוג הנתונים שאתם שולחים (למשל תמונה או טקסט), וגם במצב שבו אתם משתמשים עבור סוגי נתונים מסוימים (למשל Video Plus,‏ Video Standard או Video Essential).

מיקומים

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

הודעות שגיאה

בקטע הזה מתוארות הודעות שגיאה נפוצות שאתם עשויים להיתקל בהן.

שגיאה שקשורה לחריגה מהמכסה

google.api_core.exceptions.ResourceExhausted: 429 Quota exceeded for
aiplatform.googleapis.com/online_prediction_requests_per_base_model with base
model: multimodalembedding. Please submit a quota increase request.

אם זו הפעם הראשונה שאתם מקבלים את השגיאה הזו, אתם יכולים להשתמש ב Google Cloud מסוף כדי לבקש התאמה של המכסה בפרויקט. כדאי להשתמש במסננים הבאים לפני שמבקשים את ההתאמה:

  • Service ID: aiplatform.googleapis.com
  • metric: aiplatform.googleapis.com/online_prediction_requests_per_base_model
  • base_model:multimodalembedding

לפתיחת הדף Quotas

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

ציון הטמעות עם ממדים נמוכים יותר

בהתאם למודל שבו משתמשים, בקשת הטמעה מחזירה וקטור float של 1,408 או 3,072. אתם יכולים לציין הטמעה של ממדים נמוכים יותר לנתוני טקסט ותמונה כדי לבצע אופטימיזציה של זמן האחזור והאחסון, או של האיכות. הטמעות עם ממדים נמוכים יותר מצמצמות את הצורך באחסון ומספקות חביון נמוך יותר למשימות הטמעה עתידיות (כמו חיפוש או המלצה). הטמעות בממדים גבוהים יותר מציעות דיוק גבוה יותר במשימות האלה, אבל הן דורשות יותר נפח אחסון וזמן אחזור גבוה יותר.

בטבלה הבאה מוצגים מאפיינים ברמה נמוכה יותר שזמינים כברירת מחדל לכל מודל:

דגם מידות ברירת מחדל (הגבוהות ביותר) מאפיינים נתמכים (טווח) מידות מומלצות יותר
gemini-embedding-2 3072 ‫128 עד 3,072 ‫128, 768 או 1536
multimodalembedding@001 1408 ‫128 עד 1,408 ‫128, 256 או 512

אפשר להשתמש בדוגמאות הבאות כדי ליצור הטמעות עם ממדים נמוכים יותר:

REST

אפשר לגשת למאפיינים ברמה נמוכה יותר על ידי הוספת השדה parameters.dimension. הפרמטר מקבל כל אחד מערכי המאפיינים שזמינים למודל. לדוגמה, אפשר לציין 128, 256, 512 או 1408 כשמשתמשים במודל multimodalembedding@001. התשובה כוללת את ההטמעה של המאפיין שצוין.

לפני שמשתמשים בנתוני הבקשה, צריך להחליף את הנתונים הבאים:

  • ‫PROJECT_ID: Google Cloud מזהה הפרויקט.
  • ‫IMAGE_URI: ה-URI של Cloud Storage של תמונת היעד שאליה רוצים לקבל הטמעות. לדוגמה: gs://my-bucket/embeddings/supermarket-img.png.

    אפשר גם לספק את התמונה כמחרוזת של בייטים בקידוד Base64:

          [...]
          "image": {
            "bytesBase64Encoded": "B64_ENCODED_IMAGE"
          }
          [...]
          
  • ‫TEXT: טקסט היעד ליצירת הטמעות. לדוגמה, a cat.
  • ‫EMBEDDING_DIMENSION: מספר המאפיינים של ההטמעה. ערכים נמוכים יותר יאפשרו לכם ליהנות משיפור בביצועים של משימות עתידיות, אבל ערכים גבוהים יותר יאפשרו לכם ליהנות מדיוק גבוה יותר. הערכים האפשריים: 128,‏ 256,‏ 512 ו-1408 (ברירת מחדל).

ה-method של ה-HTTP וכתובת ה-URL:

POST https://LOCATION-aiplatform.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/publishers/google/models/multimodalembedding@001:predict

גוף בקשת JSON:

{
  "instances": [
    {
      "image": {
        "gcsUri": "IMAGE_URI"
      },
      "text": "TEXT"
    }
  ],
  "parameters": {
    "dimension": EMBEDDING_DIMENSION
  }
}

כדי לשלוח את הבקשה עליכם לבחור אחת מהאפשרויות הבאות:

curl

שומרים את גוף הבקשה בקובץ בשם request.json ומריצים את הפקודה הבאה:

curl -X POST \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-Type: application/json; charset=utf-8" \
-d @request.json \
"https://LOCATION-aiplatform.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/publishers/google/models/multimodalembedding@001:predict"

PowerShell

שומרים את גוף הבקשה בקובץ בשם request.json ומריצים את הפקודה הבאה:

$cred = gcloud auth print-access-token
$headers = @{ "Authorization" = "Bearer $cred" }

Invoke-WebRequest `
-Method POST `
-Headers $headers `
-ContentType: "application/json; charset=utf-8" `
-InFile request.json `
-Uri "https://LOCATION-aiplatform.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/publishers/google/models/multimodalembedding@001:predict" | Select-Object -Expand Content
ההטמעה שהמודל מחזיר היא וקטור של מספרים ממשיים (float) עם המימד שציינתם. התשובות לדוגמה הבאות קוצרו כדי לחסוך במקום.

128 מאפיינים:

{
  "predictions": [
    {
      "imageEmbedding": [
        0.0279239565,
        [...128 dimension vector...]
        0.00403284049
      ],
      "textEmbedding": [
        0.202921599,
        [...128 dimension vector...]
        -0.0365431122
      ]
    }
  ],
  "deployedModelId": "DEPLOYED_MODEL_ID"
}

256 מאפיינים:

{
  "predictions": [
    {
      "imageEmbedding": [
        0.248620048,
        [...256 dimension vector...]
        -0.0646447465
      ],
      "textEmbedding": [
        0.0757875815,
        [...256 dimension vector...]
        -0.02749932
      ]
    }
  ],
  "deployedModelId": "DEPLOYED_MODEL_ID"
}

512 מאפיינים:

{
  "predictions": [
    {
      "imageEmbedding": [
        -0.0523675755,
        [...512 dimension vector...]
        -0.0444030389
      ],
      "textEmbedding": [
        -0.0592851527,
        [...512 dimension vector...]
        0.0350437127
      ]
    }
  ],
  "deployedModelId": "DEPLOYED_MODEL_ID"
}

Python

import os

from google import genai

# TODO (Developer) Set environment variables
PROJECT_ID = os.getenv("GOOGLE_CLOUD_PROJECT")
LOCATION_ID = "global"

# Supported dimensions: 128, 256, 512, 1408 (or up to 3072 for gemini-embedding-2)
EMBEDDING_DIMENSION = 128
IMAGE_URI = "gs://cloud-samples-data/vertex-ai/llm/prompts/landmark1.png"
EMBEDDING_MODEL = "gemini-embedding-2"
CONTEXTUAL_TEXT = "Colosseum"


def generate_embeddings_with_lower_dimension() -> genai.types.EmbedContentResponse:
    """Generates multimodal embeddings (image + text) with custom lower dimensionality

    using the modern google-genai SDK.
    """

    client = genai.Client(
        vertexai=True,
        project=PROJECT_ID,
        location=LOCATION_ID,
    )

    image_part = genai.types.Part.from_uri(
        file_uri=IMAGE_URI,
        mime_type="image/png",
    )

    text_part = genai.types.Part.from_text(text=CONTEXTUAL_TEXT)

    contents = genai.types.Content(parts=[image_part, text_part])

    config = genai.types.EmbedContentConfig(output_dimensionality=EMBEDDING_DIMENSION)

    response = client.models.embed_content(
        model=EMBEDDING_MODEL,
        contents=[contents],
        config=config,
    )

    if response.embeddings:

        embeddings = response.embeddings[0].values

        print(f"Embeddings (dim={len(embeddings)}): {embeddings[:3]}...\n")

    print(response)

    return response

המשך

import (
	"context"
	"encoding/json"
	"fmt"
	"io"

	aiplatform "cloud.google.com/go/aiplatform/apiv1beta1"
	aiplatformpb "cloud.google.com/go/aiplatform/apiv1beta1/aiplatformpb"
	"google.golang.org/api/option"
	"google.golang.org/protobuf/encoding/protojson"
	"google.golang.org/protobuf/types/known/structpb"
)

// generateWithLowerDimension shows how to generate lower-dimensional embeddings for text and image inputs.
func generateWithLowerDimension(w io.Writer, project, location string) error {
	// location = "us-central1"
	ctx := context.Background()
	apiEndpoint := fmt.Sprintf("%s-aiplatform.googleapis.com:443", location)
	client, err := aiplatform.NewPredictionClient(ctx, option.WithEndpoint(apiEndpoint))
	if err != nil {
		return fmt.Errorf("failed to construct API client: %w", err)
	}
	defer client.Close()

	model := "multimodalembedding@001"
	endpoint := fmt.Sprintf("projects/%s/locations/%s/publishers/google/models/%s", project, location, model)

	// This is the input to the model's prediction call. For schema, see:
	// https://cloud.google.com/vertex-ai/generative-ai/docs/model-reference/multimodal-embeddings-api#request_body
	instance, err := structpb.NewValue(map[string]any{
		"image": map[string]any{
			// Image input can be provided either as a Google Cloud Storage URI or as
			// base64-encoded bytes using the "bytesBase64Encoded" field.
			"gcsUri": "gs://cloud-samples-data/vertex-ai/llm/prompts/landmark1.png",
		},
		"text": "Colosseum",
	})
	if err != nil {
		return fmt.Errorf("failed to construct request payload: %w", err)
	}

	// TODO(developer): Try different dimenions: 128, 256, 512, 1408
	outputDimensionality := 128
	params, err := structpb.NewValue(map[string]any{
		"dimension": outputDimensionality,
	})
	if err != nil {
		return fmt.Errorf("failed to construct request params: %w", err)
	}

	req := &aiplatformpb.PredictRequest{
		Endpoint: endpoint,
		// The model supports only 1 instance per request.
		Instances:  []*structpb.Value{instance},
		Parameters: params,
	}

	resp, err := client.Predict(ctx, req)
	if err != nil {
		return fmt.Errorf("failed to generate embeddings: %w", err)
	}

	instanceEmbeddingsJson, err := protojson.Marshal(resp.GetPredictions()[0])
	if err != nil {
		return fmt.Errorf("failed to convert protobuf value to JSON: %w", err)
	}
	// For response schema, see:
	// https://cloud.google.com/vertex-ai/generative-ai/docs/model-reference/multimodal-embeddings-api#response-body
	var instanceEmbeddings struct {
		ImageEmbeddings []float32 `json:"imageEmbedding"`
		TextEmbeddings  []float32 `json:"textEmbedding"`
	}
	if err := json.Unmarshal(instanceEmbeddingsJson, &instanceEmbeddings); err != nil {
		return fmt.Errorf("failed to unmarshal JSON: %w", err)
	}

	imageEmbedding := instanceEmbeddings.ImageEmbeddings
	textEmbedding := instanceEmbeddings.TextEmbeddings

	fmt.Fprintf(w, "Text embedding (length=%d): %v\n", len(textEmbedding), textEmbedding)
	fmt.Fprintf(w, "Image embedding (length=%d): %v\n", len(imageEmbedding), imageEmbedding)
	// Example response:
	// Text Embedding (length=128): [0.27469793 -0.14625867 0.022280363 ... ]
	// Image Embedding (length=128): [0.06225733 -0.040650766 0.02604402 ... ]

	return nil
}

קבלת הטמעות של תמונות וטקסט (multimodalembedding@001)

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

קבלת הטמעות של טקסט ותמונות

REST

לפני שמשתמשים בנתוני הבקשה, צריך להחליף את הנתונים הבאים:

  • ‫PROJECT_ID: מזהה הפרויקט ב- Google Cloud.
  • ‫TEXT: טקסט היעד ליצירת הטמעות. לדוגמה, a cat.
  • ‫B64_ENCODED_IMG: תמונת היעד שרוצים לקבל הטבעות בשבילה. התמונה צריכה להיות מחרוזת בייטים בקידוד base64.

ה-method של ה-HTTP וכתובת ה-URL:

POST https://LOCATION-aiplatform.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/publishers/google/models/multimodalembedding@001:predict

גוף בקשת JSON:

{
  "instances": [
    {
      "text": "TEXT",
      "image": {
        "bytesBase64Encoded": "B64_ENCODED_IMG"
      }
    }
  ]
}

כדי לשלוח את הבקשה עליכם לבחור אחת מהאפשרויות הבאות:

curl

שומרים את גוף הבקשה בקובץ בשם request.json ומריצים את הפקודה הבאה:

curl -X POST \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-Type: application/json; charset=utf-8" \
-d @request.json \
"https://LOCATION-aiplatform.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/publishers/google/models/multimodalembedding@001:predict"

PowerShell

שומרים את גוף הבקשה בקובץ בשם request.json ומריצים את הפקודה הבאה:

$cred = gcloud auth print-access-token
$headers = @{ "Authorization" = "Bearer $cred" }

Invoke-WebRequest `
-Method POST `
-Headers $headers `
-ContentType: "application/json; charset=utf-8" `
-InFile request.json `
-Uri "https://LOCATION-aiplatform.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/publishers/google/models/multimodalembedding@001:predict" | Select-Object -Expand Content
ההטמעה שהמודל מחזיר היא וקטור של 1,408 מספרים ממשיים. התגובה לדוגמה הבאה קוצרה כדי לחסוך במקום.
{
  "predictions": [
    {
      "textEmbedding": [
        0.010477379,
        -0.00399621,
        0.00576670747,
        [...]
        -0.00823613815,
        -0.0169572588,
        -0.00472954148
      ],
      "imageEmbedding": [
        0.00262696808,
        -0.00198890246,
        0.0152047109,
        -0.0103145819,
        [...]
        0.0324628279,
        0.0284924973,
        0.011650892,
        -0.00452344026
      ]
    }
  ],
  "deployedModelId": "DEPLOYED_MODEL_ID"
}

Python

לפני שמנסים את הדוגמה הזו, צריך לפעול לפי Pythonההוראות להגדרה במאמר מדריך למתחילים של Agent Platform באמצעות ספריות לקוח.

כדי לבצע אימות ב-Agent Platform, צריך להגדיר את Application Default Credentials. מידע נוסף זמין במאמר הגדרת אימות לסביבת פיתוח מקומית.

from google import genai
from google.genai import types


def embed_content() -> types.EmbedContentResponse:
    client = genai.Client()

    content = types.Content(
        parts=[
            types.Part.from_uri(
                file_uri="gs://cloud-samples-data/vertex-ai/llm/prompts/landmark1.png",
                mime_type="image/png",
            ),
            types.Part.from_text(text="Colosseum"),
        ],
    )

    response = client.models.embed_content(
        model="gemini-embedding-2",
        contents=[content],
        config=types.EmbedContentConfig(
            output_dimensionality=1408,
        ),
    )
    print(response)
    # Example response:
    # embeddings=[ContentEmbedding(values=[-0.0123147098, 0.0727171078, ...])]
    return response

Node.js

לפני שמנסים את הדוגמה הזו, צריך לפעול לפי Node.jsההוראות להגדרה במאמר מדריך למתחילים של Agent Platform באמצעות ספריות לקוח.

כדי לבצע אימות ב-Agent Platform, צריך להגדיר את Application Default Credentials. מידע נוסף זמין במאמר הגדרת אימות לסביבת פיתוח מקומית.

/**
 * TODO(developer): Uncomment these variables before running the sample.\
 * (Not necessary if passing values as arguments)
 */
// const project = 'YOUR_PROJECT_ID';
// const location = 'YOUR_PROJECT_LOCATION';
// const baseImagePath = 'YOUR_BASE_IMAGE_PATH';
// const textPrompt = 'YOUR_TEXT_PROMPT';
const aiplatform = require('@google-cloud/aiplatform');

// Imports the Google Cloud Prediction service client
const {PredictionServiceClient} = aiplatform.v1;

// Import the helper module for converting arbitrary protobuf.Value objects.
const {helpers} = aiplatform;

// Specifies the location of the api endpoint
const clientOptions = {
  apiEndpoint: 'us-central1-aiplatform.googleapis.com',
};
const publisher = 'google';
const model = 'multimodalembedding@001';

// Instantiates a client
const predictionServiceClient = new PredictionServiceClient(clientOptions);

async function predictImageFromImageAndText() {
  // Configure the parent resource
  const endpoint = `projects/${project}/locations/${location}/publishers/${publisher}/models/${model}`;

  const fs = require('fs');
  const imageFile = fs.readFileSync(baseImagePath);

  // Convert the image data to a Buffer and base64 encode it.
  const encodedImage = Buffer.from(imageFile).toString('base64');

  const prompt = {
    text: textPrompt,
    image: {
      bytesBase64Encoded: encodedImage,
    },
  };
  const instanceValue = helpers.toValue(prompt);
  const instances = [instanceValue];

  const parameter = {
    sampleCount: 1,
  };
  const parameters = helpers.toValue(parameter);

  const request = {
    endpoint,
    instances,
    parameters,
  };

  // Predict request
  const [response] = await predictionServiceClient.predict(request);
  console.log('Get image embedding response');
  const predictions = response.predictions;
  console.log('\tPredictions :');
  for (const prediction of predictions) {
    console.log(`\t\tPrediction : ${JSON.stringify(prediction)}`);
  }
}

await predictImageFromImageAndText();

Java

לפני שמנסים את הדוגמה הזו, צריך לפעול לפי Javaההוראות להגדרה במאמר מדריך למתחילים של Agent Platform באמצעות ספריות לקוח.

כדי לבצע אימות ב-Agent Platform, צריך להגדיר את Application Default Credentials. מידע נוסף זמין במאמר הגדרת אימות לסביבת פיתוח מקומית.


import com.google.cloud.aiplatform.v1beta1.EndpointName;
import com.google.cloud.aiplatform.v1beta1.PredictResponse;
import com.google.cloud.aiplatform.v1beta1.PredictionServiceClient;
import com.google.cloud.aiplatform.v1beta1.PredictionServiceSettings;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.google.protobuf.InvalidProtocolBufferException;
import com.google.protobuf.Value;
import com.google.protobuf.util.JsonFormat;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Base64;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class PredictImageFromImageAndTextSample {

  public static void main(String[] args) throws IOException {
    // TODO(developer): Replace this variable before running the sample.
    String project = "YOUR_PROJECT_ID";
    String textPrompt = "YOUR_TEXT_PROMPT";
    String baseImagePath = "YOUR_BASE_IMAGE_PATH";

    // Learn how to use text prompts to update an image:
    // https://cloud.google.com/vertex-ai/docs/generative-ai/image/edit-images
    Map<String, Object> parameters = new HashMap<String, Object>();
    parameters.put("sampleCount", 1);

    String location = "us-central1";
    String publisher = "google";
    String model = "multimodalembedding@001";

    predictImageFromImageAndText(
        project, location, publisher, model, textPrompt, baseImagePath, parameters);
  }

  // Update images using text prompts
  public static void predictImageFromImageAndText(
      String project,
      String location,
      String publisher,
      String model,
      String textPrompt,
      String baseImagePath,
      Map<String, Object> parameters)
      throws IOException {
    final String endpoint = String.format("%s-aiplatform.googleapis.com:443", location);
    final PredictionServiceSettings predictionServiceSettings =
        PredictionServiceSettings.newBuilder().setEndpoint(endpoint).build();

    // Initialize client that will be used to send requests. This client only needs to be created
    // once, and can be reused for multiple requests.
    try (PredictionServiceClient predictionServiceClient =
        PredictionServiceClient.create(predictionServiceSettings)) {
      final EndpointName endpointName =
          EndpointName.ofProjectLocationPublisherModelName(project, location, publisher, model);

      // Convert the image to Base64
      byte[] imageData = Base64.getEncoder().encode(Files.readAllBytes(Paths.get(baseImagePath)));
      String encodedImage = new String(imageData, StandardCharsets.UTF_8);

      JsonObject jsonInstance = new JsonObject();
      jsonInstance.addProperty("text", textPrompt);
      JsonObject jsonImage = new JsonObject();
      jsonImage.addProperty("bytesBase64Encoded", encodedImage);
      jsonInstance.add("image", jsonImage);

      Value instanceValue = stringToValue(jsonInstance.toString());
      List<Value> instances = new ArrayList<>();
      instances.add(instanceValue);

      Gson gson = new Gson();
      String gsonString = gson.toJson(parameters);
      Value parameterValue = stringToValue(gsonString);

      PredictResponse predictResponse =
          predictionServiceClient.predict(endpointName, instances, parameterValue);
      System.out.println("Predict Response");
      System.out.println(predictResponse);
      for (Value prediction : predictResponse.getPredictionsList()) {
        System.out.format("\tPrediction: %s\n", prediction);
      }
    }
  }

  // Convert a Json string to a protobuf.Value
  static Value stringToValue(String value) throws InvalidProtocolBufferException {
    Value.Builder builder = Value.newBuilder();
    JsonFormat.parser().merge(value, builder);
    return builder.build();
  }
}

Go

לפני שמנסים את הדוגמה הזו, צריך לפעול לפי Goההוראות להגדרה במאמר מדריך למתחילים של Agent Platform באמצעות ספריות לקוח.

כדי לבצע אימות ב-Agent Platform, צריך להגדיר את Application Default Credentials. מידע נוסף זמין במאמר הגדרת אימות לסביבת פיתוח מקומית.

import (
	"context"
	"encoding/json"
	"fmt"
	"io"

	aiplatform "cloud.google.com/go/aiplatform/apiv1beta1"
	aiplatformpb "cloud.google.com/go/aiplatform/apiv1beta1/aiplatformpb"
	"google.golang.org/api/option"
	"google.golang.org/protobuf/encoding/protojson"
	"google.golang.org/protobuf/types/known/structpb"
)

// generateForTextAndImage shows how to use the multimodal model to generate embeddings for
// text and image inputs.
func generateForTextAndImage(w io.Writer, project, location string) error {
	// location = "us-central1"
	ctx := context.Background()
	apiEndpoint := fmt.Sprintf("%s-aiplatform.googleapis.com:443", location)
	client, err := aiplatform.NewPredictionClient(ctx, option.WithEndpoint(apiEndpoint))
	if err != nil {
		return fmt.Errorf("failed to construct API client: %w", err)
	}
	defer client.Close()

	model := "multimodalembedding@001"
	endpoint := fmt.Sprintf("projects/%s/locations/%s/publishers/google/models/%s", project, location, model)

	// This is the input to the model's prediction call. For schema, see:
	// https://cloud.google.com/vertex-ai/generative-ai/docs/model-reference/multimodal-embeddings-api#request_body
	instance, err := structpb.NewValue(map[string]any{
		"image": map[string]any{
			// Image input can be provided either as a Google Cloud Storage URI or as
			// base64-encoded bytes using the "bytesBase64Encoded" field.
			"gcsUri": "gs://cloud-samples-data/vertex-ai/llm/prompts/landmark1.png",
		},
		"text": "Colosseum",
	})
	if err != nil {
		return fmt.Errorf("failed to construct request payload: %w", err)
	}

	req := &aiplatformpb.PredictRequest{
		Endpoint: endpoint,
		// The model supports only 1 instance per request.
		Instances: []*structpb.Value{instance},
	}

	resp, err := client.Predict(ctx, req)
	if err != nil {
		return fmt.Errorf("failed to generate embeddings: %w", err)
	}

	instanceEmbeddingsJson, err := protojson.Marshal(resp.GetPredictions()[0])
	if err != nil {
		return fmt.Errorf("failed to convert protobuf value to JSON: %w", err)
	}
	// For response schema, see:
	// https://cloud.google.com/vertex-ai/generative-ai/docs/model-reference/multimodal-embeddings-api#response-body
	var instanceEmbeddings struct {
		ImageEmbeddings []float32 `json:"imageEmbedding"`
		TextEmbeddings  []float32 `json:"textEmbedding"`
	}
	if err := json.Unmarshal(instanceEmbeddingsJson, &instanceEmbeddings); err != nil {
		return fmt.Errorf("failed to unmarshal JSON: %w", err)
	}

	imageEmbedding := instanceEmbeddings.ImageEmbeddings
	textEmbedding := instanceEmbeddings.TextEmbeddings

	fmt.Fprintf(w, "Text embedding (length=%d): %v\n", len(textEmbedding), textEmbedding)
	fmt.Fprintf(w, "Image embedding (length=%d): %v\n", len(imageEmbedding), imageEmbedding)
	// Example response:
	// Text embedding (length=1408): [0.0023026613 0.027898183 -0.011858357 ... ]
	// Image embedding (length=1408): [-0.012314269 0.07271844 0.00020170923 ... ]

	return nil
}

קבלת הטמעה של סרטון, תמונה או טקסט (multimodalembedding@001)

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

מצבי הטמעה של סרטונים

יש שלושה מצבים שבהם אפשר להשתמש בהטמעות של סרטונים: חיוני, רגיל או פלוס. ההגדרה הזו תואמת לצפיפות של ההטמעות שנוצרות, שאפשר לציין אותה באמצעות interval_sec config בבקשה. לכל מרווח של סרטון באורך interval_sec נוצרת הטמעה. אורך המרווח המינימלי בין סרטונים הוא 4 שניות. אורכי מרווחים שגדולים מ-120 שניות עלולים להשפיע לרעה על איכות ההטמעות שנוצרות.

התמחור של הטמעת סרטונים תלוי במצב שבו משתמשים. מידע נוסף זמין במחירון.

בטבלה הבאה מפורטים שלושת המצבים שבהם אפשר להשתמש בהטמעות של סרטונים:

מצב מספר ההטמעות המקסימלי בדקה מרווח הטמעה של סרטון (ערך מינימלי)
Essential 4 ‫15

הערך הזה תואם ל: intervalSec >= 15
רגילה 8 ‫8

הערך הזה תואם ל: 8 <= intervalSec < 15
Plus 15 ‫4

התנאי הזה מתאים ל: 4 <= intervalSec < 8

שיטות מומלצות להטמעת סרטונים

כששולחים בקשות להטמעת סרטונים, חשוב לשים לב לנקודות הבאות:

  • כדי ליצור הטמעה אחת לשתי הדקות הראשונות של סרטון קלט בכל אורך, משתמשים בהגדרה videoSegmentConfig הבאה:

    request.json:

    // other request body content
    "videoSegmentConfig": {
      "intervalSec": 120
    }
    // other request body content
    
  • כדי ליצור הטמעה של סרטון באורך של יותר משתי דקות, אפשר לשלוח כמה בקשות שבהן מציינים את זמני ההתחלה והסיום בפורמט videoSegmentConfig:

    request1.json:

    // other request body content
    "videoSegmentConfig": {
      "startOffsetSec": 0,
      "endOffsetSec": 120
    }
    // other request body content
    

    request2.json:

    // other request body content
    "videoSegmentConfig": {
      "startOffsetSec": 120,
      "endOffsetSec": 240
    }
    // other request body content
    

    קבלת הטמעות של סרטונים

כדי לקבל הטמעות של תוכן וידאו בלבד, אפשר להשתמש בדוגמה הבאה.

REST

בדוגמה הבאה נעשה שימוש בסרטון שנמצא ב-Cloud Storage. אפשר גם להשתמש בשדה video.bytesBase64Encoded כדי לספק ייצוג מחרוזת של הסרטון בקידוד base64.

לפני שמשתמשים בנתוני הבקשה, צריך להחליף את הנתונים הבאים:

  • ‫PROJECT_ID: Google Cloud מזהה הפרויקט.
  • ‫VIDEO_URI: ה-URI של Cloud Storage של סרטון היעד שאליו רוצים לקבל הטמעות. לדוגמה: gs://my-bucket/embeddings/supermarket-video.mp4.

    אפשר גם לספק את הסרטון כמחרוזת בייטים בקידוד Base64:

    [...]
    "video": {
      "bytesBase64Encoded": "B64_ENCODED_VIDEO"
    }
    [...]
          
  • ‫videoSegmentConfig (START_SECOND, END_SECOND, INTERVAL_SECONDS). אופציונלי. פלחים ספציפיים של סרטונים (בשניות) שעבורם נוצרים ההטמעות.

    לדוגמה:

    [...]
    "videoSegmentConfig": {
      "startOffsetSec": 10,
      "endOffsetSec": 60,
      "intervalSec": 10
    }
    [...]

    ההגדרה הזו מציינת נתוני סרטון מ-10 שניות עד 60 שניות, ומייצרת הטמעות למרווחי הזמן הבאים של סרטונים באורך 10 שניות: [10, 20), [20, 30), [30, 40), [40, 50), [50, 60). האינטרוול הזה של הסרטון ("intervalSec": 10) נכלל ב מצב ההטמעה הרגיל של הסרטון, ותחויבו לפי תעריף התמחור של המצב הרגיל.

    אם לא מציינים את videoSegmentConfig, השירות משתמש בערכי ברירת המחדל הבאים: "videoSegmentConfig": { "startOffsetSec": 0, "endOffsetSec": 120, "intervalSec": 16 }. האינטרוול הזה של הסרטון ("intervalSec": 16) נכלל במצב ההטמעה של הסרטון Essential, והמשתמש מחויב לפי תעריף התמחור של מצב Essential.

ה-method של ה-HTTP וכתובת ה-URL:

POST https://LOCATION-aiplatform.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/publishers/google/models/multimodalembedding@001:predict

גוף בקשת JSON:

{
  "instances": [
    {
      "video": {
        "gcsUri": "VIDEO_URI",
        "videoSegmentConfig": {
          "startOffsetSec": START_SECOND,
          "endOffsetSec": END_SECOND,
          "intervalSec": INTERVAL_SECONDS
        }
      }
    }
  ]
}

כדי לשלוח את הבקשה עליכם לבחור אחת מהאפשרויות הבאות:

curl

שומרים את גוף הבקשה בקובץ בשם request.json ומריצים את הפקודה הבאה:

curl -X POST \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-Type: application/json; charset=utf-8" \
-d @request.json \
"https://LOCATION-aiplatform.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/publishers/google/models/multimodalembedding@001:predict"

PowerShell

שומרים את גוף הבקשה בקובץ בשם request.json ומריצים את הפקודה הבאה:

$cred = gcloud auth print-access-token
$headers = @{ "Authorization" = "Bearer $cred" }

Invoke-WebRequest `
-Method POST `
-Headers $headers `
-ContentType: "application/json; charset=utf-8" `
-InFile request.json `
-Uri "https://LOCATION-aiplatform.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/publishers/google/models/multimodalembedding@001:predict" | Select-Object -Expand Content
ההטמעה שהמודל מחזיר היא וקטור של 1,408 מספרים ממשיים. התגובות לדוגמה הבאות קוצרו כדי לחסוך במקום.

תשובה (סרטון באורך 7 שניות, לא צוין videoSegmentConfig):

{
  "predictions": [
    {
      "videoEmbeddings": [
        {
          "endOffsetSec": 7,
          "embedding": [
            -0.0045467657,
            0.0258095954,
            0.0146885719,
            0.00945400633,
            [...]
            -0.0023291884,
            -0.00493789,
            0.00975185353,
            0.0168156829
          ],
          "startOffsetSec": 0
        }
      ]
    }
  ],
  "deployedModelId": "DEPLOYED_MODEL_ID"
}

תגובה (סרטון באורך 59 שניות, עם הגדרת פלח הסרטון הבאה: "videoSegmentConfig": { "startOffsetSec": 0, "endOffsetSec": 60, "intervalSec": 10 }):

{
  "predictions": [
    {
      "videoEmbeddings": [
        {
          "endOffsetSec": 10,
          "startOffsetSec": 0,
          "embedding": [
            -0.00683252793,
            0.0390476175,
            [...]
            0.00657121744,
            0.013023301
          ]
        },
        {
          "startOffsetSec": 10,
          "endOffsetSec": 20,
          "embedding": [
            -0.0104404651,
            0.0357737206,
            [...]
            0.00509833824,
            0.0131902946
          ]
        },
        {
          "startOffsetSec": 20,
          "embedding": [
            -0.0113538112,
            0.0305239167,
            [...]
            -0.00195809244,
            0.00941874553
          ],
          "endOffsetSec": 30
        },
        {
          "embedding": [
            -0.00299320649,
            0.0322436653,
            [...]
            -0.00993082579,
            0.00968887936
          ],
          "startOffsetSec": 30,
          "endOffsetSec": 40
        },
        {
          "endOffsetSec": 50,
          "startOffsetSec": 40,
          "embedding": [
            -0.00591270532,
            0.0368893594,
            [...]
            -0.00219071587,
            0.0042470959
          ]
        },
        {
          "embedding": [
            -0.00458270218,
            0.0368121453,
            [...]
            -0.00317760976,
            0.00595594104
          ],
          "endOffsetSec": 59,
          "startOffsetSec": 50
        }
      ]
    }
  ],
  "deployedModelId": "DEPLOYED_MODEL_ID"
}

Python

לפני שמנסים את הדוגמה הזו, צריך לפעול לפי Pythonההוראות להגדרה במאמר מדריך למתחילים של Agent Platform באמצעות ספריות לקוח.

כדי לבצע אימות ב-Agent Platform, צריך להגדיר את Application Default Credentials. מידע נוסף זמין במאמר הגדרת אימות לסביבת פיתוח מקומית.

from google import genai
from google.genai import types


def embed_content() -> types.EmbedContentResponse:
    client = genai.Client()

    part = types.Part(
        file_data=types.FileData(
            file_uri="gs://cloud-samples-data/vertex-ai-vision/highway_vehicles.mp4",
            mime_type="video/mp4",
        ),
        video_metadata=types.VideoMetadata(end_offset="1s"),
    )

    content = types.Content(parts=[part])

    response = client.models.embed_content(
        model="gemini-embedding-2",
        contents=[content],
    )
    print(response)
    # Example response:
    # embeddings=[ContentEmbedding(values=[-0.0123147098, 0.0727171078, ...])]
    return response

Go

לפני שמנסים את הדוגמה הזו, צריך לפעול לפי Goההוראות להגדרה במאמר מדריך למתחילים של Agent Platform באמצעות ספריות לקוח.

כדי לבצע אימות ב-Agent Platform, צריך להגדיר את Application Default Credentials. מידע נוסף זמין במאמר הגדרת אימות לסביבת פיתוח מקומית.

import (
	"context"
	"encoding/json"
	"fmt"
	"io"
	"time"

	aiplatform "cloud.google.com/go/aiplatform/apiv1beta1"
	aiplatformpb "cloud.google.com/go/aiplatform/apiv1beta1/aiplatformpb"
	"google.golang.org/api/option"
	"google.golang.org/protobuf/encoding/protojson"
	"google.golang.org/protobuf/types/known/structpb"
)

// generateForVideo shows how to use the multimodal model to generate embeddings for video input.
func generateForVideo(w io.Writer, project, location string) error {
	// location = "us-central1"

	// The default context timeout may be not enough to process a video input.
	ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
	defer cancel()

	apiEndpoint := fmt.Sprintf("%s-aiplatform.googleapis.com:443", location)
	client, err := aiplatform.NewPredictionClient(ctx, option.WithEndpoint(apiEndpoint))
	if err != nil {
		return fmt.Errorf("failed to construct API client: %w", err)
	}
	defer client.Close()

	model := "multimodalembedding@001"
	endpoint := fmt.Sprintf("projects/%s/locations/%s/publishers/google/models/%s", project, location, model)

	// This is the input to the model's prediction call. For schema, see:
	// https://cloud.google.com/vertex-ai/generative-ai/docs/model-reference/multimodal-embeddings-api#request_body
	instances, err := structpb.NewValue(map[string]any{
		"video": map[string]any{
			// Video input can be provided either as a Google Cloud Storage URI or as base64-encoded
			// bytes using the "bytesBase64Encoded" field.
			"gcsUri": "gs://cloud-samples-data/vertex-ai-vision/highway_vehicles.mp4",
			"videoSegmentConfig": map[string]any{
				"startOffsetSec": 1,
				"endOffsetSec":   5,
			},
		},
	})
	if err != nil {
		return fmt.Errorf("failed to construct request payload: %w", err)
	}

	req := &aiplatformpb.PredictRequest{
		Endpoint: endpoint,
		// The model supports only 1 instance per request.
		Instances: []*structpb.Value{instances},
	}
	resp, err := client.Predict(ctx, req)
	if err != nil {
		return fmt.Errorf("failed to generate embeddings: %w", err)
	}

	instanceEmbeddingsJson, err := protojson.Marshal(resp.GetPredictions()[0])
	if err != nil {
		return fmt.Errorf("failed to convert protobuf value to JSON: %w", err)
	}
	// For response schema, see:
	// https://cloud.google.com/vertex-ai/generative-ai/docs/model-reference/multimodal-embeddings-api#response-body
	var instanceEmbeddings struct {
		VideoEmbeddings []struct {
			Embedding      []float32 `json:"embedding"`
			StartOffsetSec float64   `json:"startOffsetSec"`
			EndOffsetSec   float64   `json:"endOffsetSec"`
		} `json:"videoEmbeddings"`
	}
	if err := json.Unmarshal(instanceEmbeddingsJson, &instanceEmbeddings); err != nil {
		return fmt.Errorf("failed to unmarshal json: %w", err)
	}
	// Get the embedding for our single video segment (`.videoEmbeddings` object has one entry per
	// each processed segment).
	videoEmbedding := instanceEmbeddings.VideoEmbeddings[0]

	fmt.Fprintf(w, "Video embedding (seconds: %.f-%.f; length=%d): %v\n",
		videoEmbedding.StartOffsetSec,
		videoEmbedding.EndOffsetSec,
		len(videoEmbedding.Embedding),
		videoEmbedding.Embedding,
	)
	// Example response:
	// Video embedding (seconds: 1-5; length=1408): [-0.016427778 0.032878537 -0.030755188 ... ]

	return nil
}

קבלת הטמעות של תמונות, טקסט וסרטונים

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

REST

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

בנוסף, הדוגמה הזו משתמשת בסרטון שנמצא ב-Cloud Storage. אפשר גם להשתמש בשדה video.bytesBase64Encoded כדי לספק ייצוג מחרוזת של הסרטון בקידוד base64.

לפני שמשתמשים בנתוני הבקשה, צריך להחליף את הנתונים הבאים:

  • ‫PROJECT_ID: מזהה הפרויקט ב- Google Cloud.
  • ‫TEXT: טקסט היעד ליצירת הטמעות. לדוגמה, a cat.
  • ‫IMAGE_URI: ה-URI של Cloud Storage של תמונת היעד שאליה רוצים לקבל הטמעות. לדוגמה: gs://my-bucket/embeddings/supermarket-img.png.

    אפשר גם לספק את התמונה כמחרוזת בייטים בקידוד Base64:

    [...]
    "image": {
      "bytesBase64Encoded": "B64_ENCODED_IMAGE"
    }
    [...]
    
  • ‫VIDEO_URI: ה-URI של Cloud Storage של סרטון היעד שאליו רוצים לקבל הטמעות. לדוגמה: gs://my-bucket/embeddings/supermarket-video.mp4.

    אפשר גם לספק את הסרטון כמחרוזת בייטים בקידוד Base64:

    [...]
    "video": {
      "bytesBase64Encoded": "B64_ENCODED_VIDEO"
    }
    [...]
    
  • ‫videoSegmentConfig (START_SECOND, END_SECOND, INTERVAL_SECONDS). אופציונלי. פלחים ספציפיים של סרטונים (בשניות) שעבורם נוצרים ההטמעות.

    לדוגמה:

    [...]
      "videoSegmentConfig": {
        "startOffsetSec": 10,
        "endOffsetSec": 60,
        "intervalSec": 10
      }
      [...]

    הגדרת התצורה הזו מציינת נתוני סרטון מ-10 שניות עד 60 שניות, ומייצרת הטמעות למרווחי הסרטון הבאים של 10 שניות: [10, 20), [20, 30), [30, 40), [40, 50), [50, 60). האינטרוול הזה של הסרטון ("intervalSec": 10) נכלל ב מצב ההטמעה הרגיל של הסרטון, ולכן תחויבו לפי תעריף התמחור של המצב הרגיל.

    אם לא מציינים את videoSegmentConfig, השירות משתמש בערכי ברירת המחדל הבאים: "videoSegmentConfig": { "startOffsetSec": 0, "endOffsetSec": 120, "intervalSec": 16 }. ההפעלה של הסרטון הזה ("intervalSec": 16) מתבצעת במצב הטמעה חיוני של סרטונים, והמשתמש מחויב לפי תעריף התמחור של מצב חיוני.

ה-method של ה-HTTP וכתובת ה-URL:

POST https://LOCATION-aiplatform.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/publishers/google/models/multimodalembedding@001:predict

גוף בקשת JSON:

{
  "instances": [
    {
      "text": "TEXT",
      "image": {
        "gcsUri": "IMAGE_URI"
      },
      "video": {
        "gcsUri": "VIDEO_URI",
        "videoSegmentConfig": {
          "startOffsetSec": START_SECOND,
          "endOffsetSec": END_SECOND,
          "intervalSec": INTERVAL_SECONDS
        }
      }
    }
  ]
}

כדי לשלוח את הבקשה עליכם לבחור אחת מהאפשרויות הבאות:

curl

שומרים את גוף הבקשה בקובץ בשם request.json ומריצים את הפקודה הבאה:

curl -X POST \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-Type: application/json; charset=utf-8" \
-d @request.json \
"https://LOCATION-aiplatform.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/publishers/google/models/multimodalembedding@001:predict"

PowerShell

שומרים את גוף הבקשה בקובץ בשם request.json ומריצים את הפקודה הבאה:

$cred = gcloud auth print-access-token
$headers = @{ "Authorization" = "Bearer $cred" }

Invoke-WebRequest `
-Method POST `
-Headers $headers `
-ContentType: "application/json; charset=utf-8" `
-InFile request.json `
-Uri "https://LOCATION-aiplatform.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/publishers/google/models/multimodalembedding@001:predict" | Select-Object -Expand Content
ההטמעה שהמודל מחזיר היא וקטור של 1,408 מספרים ממשיים. התגובה לדוגמה הבאה קוצרה כדי לחסוך במקום.
{
  "predictions": [
    {
      "textEmbedding": [
        0.0105433334,
        -0.00302835181,
        0.00656806398,
        0.00603460241,
        [...]
        0.00445805816,
        0.0139605571,
        -0.00170318608,
        -0.00490092579
      ],
      "videoEmbeddings": [
        {
          "startOffsetSec": 0,
          "endOffsetSec": 7,
          "embedding": [
            -0.00673126569,
            0.0248149596,
            0.0128901172,
            0.0107588246,
            [...]
            -0.00180952181,
            -0.0054573305,
            0.0117037306,
            0.0169312079
          ]
        }
      ],
      "imageEmbedding": [
        -0.00728622358,
        0.031021487,
        -0.00206603738,
        0.0273937676,
        [...]
        -0.00204976718,
        0.00321615417,
        0.0121978866,
        0.0193375275
      ]
    }
  ],
  "deployedModelId": "DEPLOYED_MODEL_ID"
}

Python

לפני שמנסים את הדוגמה הזו, צריך לפעול לפי Pythonההוראות להגדרה במאמר מדריך למתחילים של Agent Platform באמצעות ספריות לקוח.

כדי לבצע אימות ב-Agent Platform, צריך להגדיר את Application Default Credentials. מידע נוסף זמין במאמר הגדרת אימות לסביבת פיתוח מקומית.


import os

from google import genai

# Environment configuration
PROJECT_ID = os.getenv("GOOGLE_CLOUD_PROJECT", "your-project-id")
LOCATION_ID = "global"

EMBEDDING_MODEL = "gemini-embedding-2"
IMAGE_URI = "gs://cloud-samples-data/vertex-ai/llm/prompts/landmark1.png"
VIDEO_URI = "gs://cloud-samples-data/vertex-ai-vision/highway_vehicles.mp4"
CONTEXTUAL_TEXT = "Cars on Highway"


def get_image_video_text_embeddings() -> genai.types.EmbedContentResponse:
    """Generates multimodal embeddings from image, video, and text using the google-genai SDK."""

    client = genai.Client(
        vertexai=True,
        project=PROJECT_ID,
        location=LOCATION_ID,
    )

    image_part = genai.types.Part.from_uri(
        file_uri=IMAGE_URI,
        mime_type="image/png",
    )

    video_part = genai.types.Part.from_uri(
        file_uri=VIDEO_URI,
        mime_type="video/mp4",
    )

    content = genai.types.Content(
        parts=[image_part, video_part, genai.types.Part.from_text(text=CONTEXTUAL_TEXT)]
    )

    # Joint/Interleaved Multimodal Embedding (Image + Video + Text in same vector space)
    response = client.models.embed_content(model=EMBEDDING_MODEL, contents=content)

    if response.embeddings:

        vector = response.embeddings[0].values

        print(f"Embeddings ({len(vector)} dims): {vector[:3]}...")

    print(response)

    return response

Go

לפני שמנסים את הדוגמה הזו, צריך לפעול לפי Goההוראות להגדרה במאמר מדריך למתחילים של Agent Platform באמצעות ספריות לקוח.

כדי לבצע אימות ב-Agent Platform, צריך להגדיר את Application Default Credentials. מידע נוסף זמין במאמר הגדרת אימות לסביבת פיתוח מקומית.

import (
	"context"
	"encoding/json"
	"fmt"
	"io"
	"time"

	aiplatform "cloud.google.com/go/aiplatform/apiv1beta1"
	aiplatformpb "cloud.google.com/go/aiplatform/apiv1beta1/aiplatformpb"
	"google.golang.org/api/option"
	"google.golang.org/protobuf/encoding/protojson"
	"google.golang.org/protobuf/types/known/structpb"
)

// generateForImageTextAndVideo shows how to use the multimodal model to generate embeddings for
// image, text and video data.
func generateForImageTextAndVideo(w io.Writer, project, location string) error {
	// location = "us-central1"

	// The default context timeout may be not enough to process a video input.
	ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
	defer cancel()

	apiEndpoint := fmt.Sprintf("%s-aiplatform.googleapis.com:443", location)
	client, err := aiplatform.NewPredictionClient(ctx, option.WithEndpoint(apiEndpoint))
	if err != nil {
		return fmt.Errorf("failed to construct API client: %w", err)
	}
	defer client.Close()

	model := "multimodalembedding@001"
	endpoint := fmt.Sprintf("projects/%s/locations/%s/publishers/google/models/%s", project, location, model)

	// This is the input to the model's prediction call. For schema, see:
	// https://cloud.google.com/vertex-ai/generative-ai/docs/model-reference/multimodal-embeddings-api#request_body
	instance, err := structpb.NewValue(map[string]any{
		"text": "Domestic cats in natural conditions",
		"image": map[string]any{
			// Image and video inputs can be provided either as a Google Cloud Storage URI or as
			// base64-encoded bytes using the "bytesBase64Encoded" field.
			"gcsUri": "gs://cloud-samples-data/generative-ai/image/320px-Felis_catus-cat_on_snow.jpg",
		},
		"video": map[string]any{
			"gcsUri": "gs://cloud-samples-data/video/cat.mp4",
		},
	})
	if err != nil {
		return fmt.Errorf("failed to construct request payload: %w", err)
	}

	req := &aiplatformpb.PredictRequest{
		Endpoint: endpoint,
		// The model supports only 1 instance per request.
		Instances: []*structpb.Value{instance},
	}

	resp, err := client.Predict(ctx, req)
	if err != nil {
		return fmt.Errorf("failed to generate embeddings: %w", err)
	}

	instanceEmbeddingsJson, err := protojson.Marshal(resp.GetPredictions()[0])
	if err != nil {
		return fmt.Errorf("failed to convert protobuf value to JSON: %w", err)
	}
	// For response schema, see:
	// https://cloud.google.com/vertex-ai/generative-ai/docs/model-reference/multimodal-embeddings-api#response-body
	var instanceEmbeddings struct {
		ImageEmbeddings []float32 `json:"imageEmbedding"`
		TextEmbeddings  []float32 `json:"textEmbedding"`
		VideoEmbeddings []struct {
			Embedding      []float32 `json:"embedding"`
			StartOffsetSec float64   `json:"startOffsetSec"`
			EndOffsetSec   float64   `json:"endOffsetSec"`
		} `json:"videoEmbeddings"`
	}
	if err := json.Unmarshal(instanceEmbeddingsJson, &instanceEmbeddings); err != nil {
		return fmt.Errorf("failed to unmarshal JSON: %w", err)
	}

	imageEmbedding := instanceEmbeddings.ImageEmbeddings
	textEmbedding := instanceEmbeddings.TextEmbeddings
	// Get the embedding for our single video segment (`.videoEmbeddings` object has one entry per
	// each processed segment).
	videoEmbedding := instanceEmbeddings.VideoEmbeddings[0].Embedding

	fmt.Fprintf(w, "Image embedding (length=%d): %v\n", len(imageEmbedding), imageEmbedding)
	fmt.Fprintf(w, "Text embedding (length=%d): %v\n", len(textEmbedding), textEmbedding)
	fmt.Fprintf(w, "Video embedding (length=%d): %v\n", len(videoEmbedding), videoEmbedding)
	// Example response:
	// Image embedding (length=1408): [-0.01558477 0.0258355 0.016342038 ... ]
	// Text embedding (length=1408): [-0.005894961 0.008349559 0.015355394 ... ]
	// Video embedding (length=1408): [-0.018867437 0.013997682 0.0012682161 ... ]

	return nil
}

המאמרים הבאים