יצירת הטמעות וקטוריות לנתונים טקסטואליים בכמות גדולה באמצעות DML עם חלוקה למחיצות

במאמר הזה מוסבר איך ליצור ולמלא באופן רטרואקטיבי הטמעות וקטורים בכמות גדולה לנתוני טקסט (STRING או JSON) שמאוחסנים ב-Spanner, באמצעות SQL והמודלים להטמעת טקסט של Gemini Enterprise Agent Platform.

דרישות מוקדמות

במסד הנתונים ב-Spanner צריכה להיות טבלה עם נתוני טקסט (STRING או JSON). מידע נוסף על ייבוא נתונים זמין במאמר סקירה כללית על ייבוא וייצוא ב-Spanner.

תרחיש שימוש לדוגמה

נניח שיש לכם טבלה ב-Spanner עם הסכימה הבאה. הטבלה הזו מכילה מיליוני רשומות.

GoogleSQL

CREATE TABLE Products (
  product_id INT64 NOT NULL,
  name STRING(MAX),
  description STRING(MAX)
) PRIMARY KEY(product_id);

PostgreSQL

CREATE TABLE Products (
  product_id INT8 NOT NULL,
  name TEXT,
  description TEXT,
  PRIMARY KEY(product_id)
);

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

רישום של מודל הטמעה

GoogleSQL

רושמים מודל להטמעת טקסט עם נקודת הקצה של מודל Agent Platform במסד הנתונים של Spanner:

CREATE MODEL MODEL_NAME
INPUT(
  content STRING(MAX)
)
OUTPUT(
  embeddings STRUCT<values ARRAY<FLOAT32>>
)
REMOTE OPTIONS(
    endpoint = '//aiplatform.googleapis.com/projects/PROJECT/locations/LOCATION/publishers/google/models/$MODEL_NAME',
  default_batch_size = 5
)

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

  • ‫MODEL_NAME: השם של מודל הטמעת הטקסט ב-Agent Platform
  • ‫PROJECT: הפרויקט שמארח את נקודת הקצה של Agent Platform
  • ‫LOCATION: המיקום של נקודת הקצה של Agent Platform

PostgreSQL

בניב PostgreSQL, אין צורך לרשום את המודל. מעבירים את שם נקודת הקצה ישירות לקריאה לפונקציה spanner.ML_PREDICT_ROW.

כדי להשתמש בשיטות המומלצות, כדאי להביא בחשבון את הדברים הבאים:

  • כדי לשמור על בידוד המכסות, השתמשו בנקודת קצה בפרויקט אחר כדי ליצור ולמלא הטמעות, ולא בנקודת הקצה בסביבת הייצור. שמרו את נקודת הקצה בסביבת הייצור כדי לשרת את התנועה בסביבת הייצור.
  • צריך לוודא שנקודת הקצה של המודל תומכת בערך של default_batch_size. אפשר לשנות את default_batch_size באמצעות הרמז לשאילתה @{remote_udf_max_rows_per_rpc=NEW_NUMBER}. למידע על המגבלה של default_batch_size בכל אזור, קראו את המאמר יצירת הטמעות טקסט לקטע טקסט.
  • מגדירים את נקודת הקצה עם גרסת מודל ספציפית (למשל @003) במקום @latest. הסיבה לכך היא שהווקטורים של ההטמעה שנוצרים לאותו קטע טקסט עשויים להיות שונים בהתאם לגרסת המודל שבה אתם משתמשים. לכן כדאי להימנע משימוש בגרסאות שונות של מודלים כדי ליצור הטמעות באותה קבוצת נתונים. בנוסף, עדכון גרסת המודל בהצהרת הגדרת המודל לא מעדכן את ההטמעות שכבר נוצרו באמצעות המודל הזה. אחת מהדרכים לנהל את גרסת המודל להטמעות היא ליצור עמודה נוספת בטבלה שבה מאוחסנת גרסת המודל.
  • אי אפשר להשתמש במודלים של הטמעת טקסט שעברו כוונון בהתאמה אישית עם הפונקציות ML.PREDICT ב-GoogleSQL ו-spanner.ML_PREDICT_ROW ב-PostgreSQL.

בדיקת השילוב מקצה לקצה של מודל ההטמעות

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

GoogleSQL

SELECT embeddings.values
FROM SAFE.ML.PREDICT(
  MODEL MODEL_NAME,
  (SELECT description AS content FROM products LIMIT 10)
);

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

  • ‫MODEL_NAME: השם של מודל הטמעת הטקסט ב-Agent Platform

PostgreSQL

SELECT spanner.ML_PREDICT_ROW(
    'projects/PROJECT/locations/LOCATION/publishers/google/models/$MODEL_NAME',
    JSONB_BUILD_OBJECT('instances', JSONB_BUILD_ARRAY(JSONB_BUILD_OBJECT('content', description))))
FROM Products
LIMIT 10;

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

  • ‫PROJECT: הפרויקט שמארח את נקודת הקצה של Agent Platform
  • ‫LOCATION: המיקום של נקודת הקצה של Agent Platform
  • ‫MODEL_NAME: השם של מודל הטמעת הטקסט ב-Agent Platform

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

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

GoogleSQL

ALTER TABLE TABLE_NAME
ADD COLUMN EMBEDDING_COLUMN_NAME ARRAY<FLOAT32>(vector_length=>VECTOR_LENGTH);

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

  • ‫TABLE_NAME: השם של טבלת המקור
  • ‫EMBEDDING_COLUMN_NAME: שם העמודה שבה רוצים להוסיף את ההטמעות שנוצרו
  • ‫VECTOR_LENGTH: ממד הפלט של מודל ההטמעה, למשל 768 או 3072

PostgreSQL

ALTER TABLE TABLE_NAME
ADD COLUMN EMBEDDING_COLUMN_NAME real[] VECTOR LENGTH VECTOR_LENGTH;

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

  • ‫TABLE_NAME: השם של טבלת המקור
  • ‫EMBEDDING_COLUMN_NAME: שם העמודה שבה רוצים להוסיף את ההטמעות שנוצרו
  • ‫VECTOR_LENGTH: ממד הפלט של מודל ההטמעה, למשל 768 או 3072

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

GoogleSQL

ALTER TABLE Products
ADD COLUMN desc_embed ARRAY<FLOAT32>(vector_length=>768);

PostgreSQL

ALTER TABLE Products
ADD COLUMN desc_embed real[] VECTOR LENGTH 768;

אפשר להוסיף עוד עמודה כדי לנהל את הגרסה של מודל ההטמעה.

GoogleSQL

ALTER TABLE Products
ADD COLUMN desc_embed_model_version INT64;

PostgreSQL

ALTER TABLE Products
ADD COLUMN desc_embed_model_version INT8;

הגדלת המכסה של Agent Platform

יכול להיות שתצטרכו להגדיל את המכסה של Agent Platform API באזור שבו אתם משתמשים במודל הטמעת הטקסט. כדי לבקש הגדלה, קראו את המאמר הגדלת המכסות ב-Agent Platform.

מילוי חוסרים בהטמעות

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

GoogleSQL

UPDATE TABLE_NAME
SET
  TABLE_NAME.EMBEDDING_COLUMN_NAME = (
    SELECT embeddings.values
    FROM SAFE.ML.PREDICT(
      MODEL MODEL_NAME,
      (SELECT TABLE_NAME.DATA_COLUMN_NAME AS content)
    ) @{remote_udf_max_rows_per_rpc=MAX_ROWS}
  ),
  TABLE_NAME.EMBEDDING_VERSION_COLUMN = MODEL_VERSION
WHERE FILTER_CONDITION;

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

  • ‫TABLE_NAME: שם הטבלה עם הנתונים הטקסטואליים
  • ‫EMBEDDING_COLUMN_NAME: שם העמודה שבה רוצים להוסיף את ההטמעות שנוצרו
  • DATA_COLUMN_NAME: שם העמודה עם הנתונים הטקסטואליים
  • ‫MODEL_NAME: השם של מודל ההטמעה ב-Agent Platform
  • ‫MAX_ROWS: המספר המקסימלי של שורות לכל RPC
  • ‫EMBEDDING_VERSION_COLUMN: העמודה שמנהלת את הגרסה של מודל ההטמעה שמשמש למילוי חוסרים בהטמעות
  • ‫MODEL_VERSION: גרסת המודל להטמעת טקסט
  • ‫FILTER_CONDITION: תנאי סינון שניתן לחלוקה שרוצים להחיל

אם משתמשים ב-SAFE.ML.PREDICT, הפונקציה מחזירה את הערך NULL לבקשות שנכשלו. אפשר גם להשתמש ב-SAFE.ML.PREDICT בשילוב עם מסנן WHERE embedding_column IS NULL כדי להריץ מחדש את השאילתה בלי לחשב את ההטמעות של השדות שכבר חושבו.

PostgreSQL

UPDATE TABLE_NAME
SET
  EMBEDDING_COLUMN_NAME = spanner.FLOAT32_ARRAY(spanner.ML_PREDICT_ROW(
    'projects/PROJECT/locations/LOCATION/publishers/google/models/$MODEL_NAME',
    JSONB_BUILD_OBJECT('instances', JSONB_BUILD_ARRAY(JSONB_BUILD_OBJECT('content', DATA_COLUMN_NAME)))
  ) /*@ remote_udf_max_rows_per_rpc=MAX_ROWS */ ->'predictions'->0->'embeddings'->'values'),
  EMBEDDING_VERSION_COLUMN = MODEL_VERSION
WHERE FILTER_CONDITION;

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

  • ‫TABLE_NAME: שם הטבלה עם הנתונים הטקסטואליים
  • ‫EMBEDDING_COLUMN_NAME: שם העמודה שבה רוצים להוסיף את ההטמעות שנוצרו
  • DATA_COLUMN_NAME: שם העמודה עם הנתונים הטקסטואליים
  • ‫PROJECT: הפרויקט שמארח את נקודת הקצה של Agent Platform
  • ‫LOCATION: המיקום של נקודת הקצה של Agent Platform
  • ‫MODEL_NAME: השם של מודל ההטמעה ב-Agent Platform
  • ‫MODEL_VERSION: הגרסה של מודל ההטמעה ב-Agent Platform
  • ‫MAX_ROWS: המספר המקסימלי של שורות לכל RPC
  • ‫EMBEDDING_VERSION_COLUMN: העמודה שבה מנוהלת הגרסה של מודל הטמעת הטקסט שמשמש למילוי חוסרים בהטמעות
  • ‫FILTER_CONDITION: תנאי סינון שניתן לחלוקה שרוצים להחיל

שאילתה לדוגמה למילוי חוסרים בטבלה products:

GoogleSQL

UPDATE products
SET
  products.desc_embed = (
    SELECT embeddings.values
    FROM SAFE.ML.PREDICT(
      MODEL embedding_model,
      (SELECT products.description AS content)
    ) @{remote_udf_max_rows_per_rpc=200}
  ),
  products.desc_embed_model_version = 3
WHERE products.desc_embed IS NULL;

PostgreSQL

UPDATE products
SET
  desc_embed = spanner.FLOAT32_ARRAY(spanner.ML_PREDICT_ROW(
    'projects/PROJECT/locations/LOCATION/publishers/google/models/$MODEL_NAME',
    JSONB_BUILD_OBJECT('instances', JSONB_BUILD_ARRAY(JSONB_BUILD_OBJECT('content', description)))
  ) /*@ remote_udf_max_rows_per_rpc=200 */ ->'predictions'->0->'embeddings'->'values'),
  desc_embed_model_version = 3
WHERE desc_embed IS NULL;

כדי להשתמש בשיטות המומלצות, כדאי להביא בחשבון את הדברים הבאים:

  • זמן הקצוב לתפוגה של gRPC כברירת מחדל ל-Spanner API הוא שעה אחת. בהתאם לכמות ההטמעות שאתם ממלאים, יכול להיות שתצטרכו להגדיל את הזמן הקצוב לתפוגה כדי לוודא שיש מספיק זמן להשלים את ה-DML המפוצל של UPDATE. מידע נוסף מופיע במאמר הגדרת זמן קצוב לתפוגה וניסיונות חוזרים בהתאמה אישית.

ביצועים ושיקולים אחרים

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

מספר הצמתים

‫DML מחולק למחיצות מריץ את פקודת ה-DML הנתונה במחיצות שונות במקביל. במכונות עם מספר גבוה של צמתים, יכול להיות שיופיעו שגיאות מכסה במהלך ההרצה של DML מחולק למחיצות. אם בקשות ה-API של Agent Platform מווסתות בגלל מגבלות המכסות של Agent Platform API, מערכת Spanner מנסה שוב את הכשלים האלה במצב טרנזקציית DML מחולקת למחיצות עד 20 פעמים. אם יש שיעור גבוה של שגיאות שקשורות למכסות ב-Agent Platform, הגדילו את המכסה של Agent Platform. אפשר גם לכוונן את ההקבלה באמצעות הרמז ברמת ההצהרה @{pdml_max_parallelism=DESIRED_NUMBER} כשמשתמשים ב-GoogleSQL. בדוגמה הבאה, המקביליות מוגדרת ל-"5":

GoogleSQL

@{pdml_max_parallelism=5} UPDATE products
SET products.desc_embed =(
  SELECT embeddings.values
  FROM SAFE.ML.PREDICT(MODEL embedding_model, (
        SELECT products.value AS CONTENT
        )
  )
      @{remote_udf_max_rows_per_rpc=200}
),
products.desc_embed_model_version = MODEL_VERSION
WHERE products.desc_embed IS NULL;

גודל הטקסט בעמודת הנתונים

במודל ההטמעה של Agent Platform יש מגבלות על המספר המקסימלי של אסימונים לכל קלט טקסט. לגרסאות שונות של המודל יש מגבלות שונות על מספר הטוקנים. כל בקשה ב-Agent Platform יכולה לכלול כמה שדות טקסט להזנה, אבל יש מגבלה על מספר הטוקנים המקסימלי שיכול להיות בבקשה אחת. במסדי נתונים של GoogleSQL, אם נתקלים בשגיאה INVALID_ARGUMENT עם ההודעה "Request is too large", כדאי לנסות להקטין את גודל האצווה כדי למנוע את השגיאה. כדי לעשות את זה, אפשר להגדיר את default_batch_size או להשתמש ברמז השאילתה @{remote_udf_max_outstanding_rpcs} כשרושמים את המודל.

מספר בקשות ה-API שנשלחו אל Agent Platform

אתם יכולים להשתמש בהנחיה לשאילתה @{remote_udf_max_outstanding_rpcs} כדי להגדיל או להקטין את מספר הבקשות שנשלחות מ-Spanner אל Agent Platform. חשוב לזכור שהגדלת המגבלה הזו יכולה להגדיל את השימוש במעבד (CPU) ואת השימוש בזיכרון של המכונה ב-Spanner. במסדי נתונים של GoogleSQL, השימוש בהנחיה הזו לשאילתה מבטל את הערך של default_batch_size שהוגדר למודל.

מעקב אחרי התקדמות המילוי החוזר

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

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