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

במאמר הזה מוסבר איך ליצור ולמלא מחדש וקטורים של הטמעות בכמות גדולה לנתוני טקסט (STRING או JSON) שמאוחסנים ב-Spanner באמצעות SQL ומודלים של הטמעת טקסט ב-Vertex AI.

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

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

רישום של מודל הטמעת טקסט בנקודת הקצה של מודל Vertex AI במסד הנתונים של 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: השם של מודל הטמעת הטקסט של Vertex AI
  • PROJECT: הפרויקט שמארח את נקודת הקצה של Vertex AI
  • LOCATION: המיקום של נקודת הקצה של Vertex AI

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: השם של מודל הטמעת הטקסט של Vertex AI

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: הפרויקט שמארח את נקודת הקצה של Vertex AI
  • LOCATION: המיקום של נקודת הקצה של Vertex AI
  • MODEL_NAME: השם של מודל הטמעת הטקסט של Vertex AI

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

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

הגדלת המכסה ל-Vertex AI

יכול להיות שתצטרכו להגדיל את מכסת Vertex AI API באזור שבו נעשה שימוש במודל להטמעת טקסט. כדי לבקש הגדלה, אפשר לעיין במאמר בנושא הגדלת מכסות ב-Vertex AI.

מידע נוסף זמין במאמר מכסות ומגבלות ב-Vertex AI.

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

לבסוף, מריצים את ההצהרה הבאה של 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: השם של מודל ההטמעה של Vertex AI
  • 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: הפרויקט שמארח את נקודת הקצה של Vertex AI
  • LOCATION: המיקום של נקודת הקצה של Vertex AI
  • MODEL_NAME: השם של מודל ההטמעה של Vertex AI
  • MODEL_VERSION: הגרסה של מודל ההטמעה של Vertex AI
  • 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 היא שעה אחת. בהתאם לכמות ההטמעות שאתם מבצעים להן מילוי חוסרים, יכול להיות שתצטרכו להגדיל את הזמן הקצוב לתפוגה כדי לוודא של-UPDATE partitioned DML יהיה מספיק זמן להשלמת הפעולה. מידע נוסף זמין במאמר בנושא הגדרת פסק זמן מותאם אישית וניסיונות חוזרים.

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

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

מספר הצמתים

פקודות DML עם חלוקה למחיצות מריצות את פקודת ה-DML הנתונה במקביל במחיצות שונות. במקרים עם מספר גבוה של צמתים, יכול להיות שתיתקלו בשגיאות שקשורות למכסת השימוש במהלך ההרצה של DML עם חלוקה למחיצות. אם הבקשות ל-Vertex AI API מווסתות בגלל מגבלות המכסה של Vertex AI API,‏ Spanner מנסה שוב את הכשלים האלה עד 20 פעמים במקסימום במצב העסקה של DML עם חלוקה למחיצות. אם אתם רואים שיעור גבוה של שגיאות שקשורות למכסת השימוש ב-Vertex AI, כדאי להגדיל את מכסת השימוש ב-Vertex AI. אפשר גם לשנות את רמת המקביליות באמצעות רמז ברמת ההצהרה @{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;

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

למודל ההטמעה של Vertex AI יש מגבלות על המספר המקסימלי של טוקנים לכל קלט טקסט. לגרסאות שונות של מודלים יש מגבלות שונות על מספר הטוקנים. כל בקשה ל-Vertex AI יכולה לכלול כמה שדות של טקסט קלט, אבל יש מגבלה על המספר המקסימלי של טוקנים שיכולים להיות בבקשה אחת. במסדי נתונים של GoogleSQL, אם נתקלים בשגיאה INVALID_ARGUMENT עם ההודעה 'הבקשה גדולה מדי', כדאי לנסות להקטין את גודל האצווה כדי להימנע מהשגיאה. כדי לעשות זאת, אפשר להגדיר את default_batch_size או להשתמש ברמז לשאילתה @{remote_udf_max_outstanding_rpcs} כשרושמים את המודל.

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

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

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

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

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