יצירת הטמעות וקטוריות לנתונים טקסטואליים בכמות גדולה באמצעות 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

רושמים מודל הטמעה של טקסט בנקודת הקצה של מודל פלטפורמת הסוכנים במסד הנתונים של 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.

כדי להפיק את המרב מהשימוש ב-Google Ads, כדאי לפעול לפי השיטות המומלצות הבאות:

  • כדי לשמור על בידוד המכסות, צריך להשתמש בנקודת קצה בפרויקט אחר כדי ליצור הטמעות ולמלא אותן, ולא בנקודת הקצה של סביבת הייצור. שומרים את נקודת הקצה של סביבת הייצור להצגת תנועה בסביבת הייצור.
  • מוודאים שנקודת הקצה של המודל תומכת בערך של 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

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

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

GoogleSQL

ALTER TABLE TABLE_NAME
ADD COLUMN EMBEDDING_COLUMN_NAME ARRAY<FLOAT32>;

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

  • TABLE_NAME: השם של טבלת המקור
  • EMBEDDING_COLUMN_NAME: שם העמודה שרוצים להוסיף לה את ההטמעות שנוצרו

PostgreSQL

ALTER TABLE TABLE_NAME
ADD COLUMN EMBEDDING_COLUMN_NAME real[];

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

  • TABLE_NAME: השם של טבלת המקור
  • EMBEDDING_COLUMN_NAME: שם העמודה שרוצים להוסיף לה את ההטמעות שנוצרו

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

GoogleSQL

ALTER TABLE Products
ADD COLUMN desc_embed ARRAY<FLOAT32>;

PostgreSQL

ALTER TABLE Products
ADD COLUMN desc_embed real[];

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

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.

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

לבסוף, מריצים את ההצהרה הבאה של 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: העמודה שמנהלת את הגרסה של מודל ה-Embedding שמשמש למילוי חוסרים ב-Embeddings
  • 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;

כדי להפיק את המרב מהשימוש ב-Google Ads, כדאי לפעול לפי השיטות המומלצות הבאות:

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

ביצועים ושיקולים נוספים

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

מספר הצמתים

פקודות DML עם חלוקה למחיצות מריצות את פקודת ה-DML הנתונה במקביל במחיצות שונות. במקרים עם מספר גבוה של צמתים, יכול להיות שתראו שגיאות שקשורות למכסת השימוש במהלך ההרצה של DML עם חלוקה למחיצות. אם הבקשות של Agent Platform API מווסתות בגלל מגבלות המכסה של Agent Platform API,‏ Spanner מנסה שוב את הפעולות שנכשלו האלה עד 20 פעמים לכל היותר, במסגרת מצב העסקה של DML מחולק. אם אתם רואים שיש שיעור גבוה של שגיאות שקשורות למכסות ב-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 עם ההודעה 'הבקשה גדולה מדי', כדאי לנסות להקטין את גודל האצווה כדי להימנע מהשגיאה. כדי לעשות זאת, אפשר להגדיר את default_batch_size או להשתמש ברמז לשאילתה @{remote_udf_max_outstanding_rpcs} כשרושמים את המודל.

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

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

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

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

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