- 為新資料表建立初始向量嵌入
- 匯入大量資料後產生嵌入內容
- 在資料大幅變更後重新整理嵌入內容
- 逐步維護嵌入
瞭解自動向量嵌入
AlloyDB Omni 的自動向量嵌入功能提供可擴充的方式,自動生成及維護資料的向量嵌入。您不必為每段新增或更新的文字手動產生嵌入,只要設定自動向量嵌入,系統就會為您處理這項程序。對於依賴最新嵌入內容進行語意搜尋、檢索增強生成 (RAG) 和其他 AI 輔助功能的應用程式而言,這項功能特別實用。
使用自動向量嵌入功能,您可以執行下列操作:
- 初始化整個資料表的嵌入:使用單一指令,為資料表資料欄中的所有現有資料產生嵌入。
- 保持嵌入內容同步:來源資料變更時,系統會自動更新嵌入內容,確保 AI 應用程式一律使用最新資訊。
- 大規模生成嵌入:有效率地為數百萬列的大型資料表建立嵌入。
- 呼叫每個嵌入資料欄的管理函式,即可設定及管理同一資料表中的多個資料欄嵌入。
這項功能會隱藏向量嵌入建立和維護作業的複雜性,簡化 AI 應用程式的開發和維護作業。
事前準備
如要為大型資料表產生及管理向量嵌入,請先按照下列步驟操作:
檢查並提高 Vertex AI 配額:為確保最佳效能,並避免作業緩慢、QPS 偏低或多次重試,請檢查 Vertex AI 配額,並視需要提高配額。
如要查看及提高配額,請按照下列步驟操作:
- 前往 Google Cloud 控制台的「配額」頁面。
- 篩選與模型和區域相關的下列指標:
- 每分鐘要求數 (RPM):
Regional online prediction requests per base model per minute per region per base_model - Gemini 權杖:
Embed content input tokens per minute per region per base_model
- 每分鐘要求數 (RPM):
- 如果目前的限制不足以容納表格大小,請找出要更新的配額值,然後勾選該配額旁邊的核取方塊。
點選「編輯」,「Quota changes」(配額變更) 對話方塊隨即顯示。
詳情請參閱「要求調整配額」。
如要瞭解 Vertex AI 嵌入模型限制,請參閱「Gemini 嵌入模型權杖限制」。
如需完整配額清單,請參閱「Vertex AI 配額與限制」。
使用
psql以postgres使用者身分連線至資料庫。如要從 AlloyDB Omni 資料庫產生嵌入,必須先設定 AlloyDB Omni,才能與 Vertex AI 搭配使用。詳情請參閱「整合資料庫與 Vertex AI」。
如要管理及監控自動產生嵌入內容,使用者預設擁有
Select存取google_ml.embed_gen_progress和google_ml.embed_gen_settings資料表的權限。如要讓使用者管理自動產生嵌入內容的功能,請在
google_ml.embed_gen_progress和google_ml.embed_gen_settings資料表上授予INSERT、UPDATE和DELETE權限:GRANT INSERT, UPDATE, DELETE ON google_ml.embed_gen_progress TO 'USER_NAME';更改下列內容:
- USER_NAME:獲授權的使用者名稱。
完成「生成文字嵌入」一文所述的初始設定。
確認您使用的 PostgreSQL 用戶端中,
AUTOCOMMIT是否設為ON。
確認擴充功能版本
如要檢查 google_ml_integration 擴充功能的版本,請執行下列指令:
SELECT extversion FROM pg_extension WHERE extname = 'google_ml_integration';
如要更新擴充功能,請執行下列指令:
ALTER EXTENSION google_ml_integration UPDATE;
確認資料庫旗標已設為 on
如要確認資料庫標記是否設定正確,請執行下列指令:
SHOW google_ml_integration.enable_model_support;
SHOW google_ml_integration.enable_faster_embedding_generation;
如果這些旗標設為 off,請參閱設定執行個體的資料庫旗標。如要進一步瞭解這些標記,請參閱「支援的資料庫標記」。
準備資料表
您必須先在資料表中建立欄,才能產生自動嵌入內容,並儲存產生的向量。這個資料欄通常會使用 vector(DIMENSION) 型別,且必須有 DEFAULT NULL 值。
舉例來說,如要將 768 維度嵌入的資料欄新增至名為 user_reviews 的資料表,請使用以下指令:
ALTER TABLE user_reviews ADD COLUMN IF NOT EXISTS content_embeddings vector(768) DEFAULT NULL;
初始化資料表的嵌入項目
管理自動向量嵌入的函式可在 ai 和 google_ml 結構定義中使用。ai 架構提供簡化的介面,方便您使用 AlloyDB Omni 的最新 AI 功能。
使用 ai.initialize_embeddings() SQL 函式,為資料表的內容資料欄產生嵌入內容。這是封鎖呼叫,也就是說,資料庫工作階段會等待作業完成,然後傳回結果,並允許您在該工作階段中發出新指令。不過,資料庫的其他連線不會遭到封鎖,可以繼續使用資料表:
- 如果函式傳回成功,表示向量嵌入建立作業已完成。
- 這項函式會自動嘗試從暫時性問題 (例如模型配額錯誤) 中復原。只有在這些復原嘗試失敗時,系統才會傳回失敗訊息。如果問題持續發生,例如
batch_size設定錯誤導致要求超出大小限制,或是作業遭到手動取消,您必須手動重新發出呼叫。
這項功能支援 Google 提供的模型 (例如 Vertex AI 的 text-embedding-005),以及您註冊的自訂模型。
執行批次生成作業
根據預設,AlloyDB Omni 會使用批次處理,在單一要求中為多個文字輸入內容生成嵌入項目,藉此提升效率。如果您未提供特定批量大小,AlloyDB Omni 會套用自動判斷的預設值。
提示批量大小
ai.initialize_embeddings 中的 batch_size 參數可讓您為直接支援的模型建議偏好的批量大小,引導 AlloyDB Omni 的查詢最佳化工具。AlloyDB Omni 可能會根據模型限制或配額動態縮減大小,但提示有助於影響查詢執行計畫。
CALL ai.initialize_embeddings(
model_id => 'text-embedding-005',
table_name => 'user_reviews',
content_column => 'content',
embedding_column => 'content_embeddings',
batch_size => 50
);
使用支援批次的自訂嵌入模型
如要使用支援批次處理的自訂或外部支援模型,請定義批次轉換函式,並在建立模型時將這些函式指定為 model_batch_in_transform_fn 和 model_batch_out_transform_fn。您也可以在 initialize_embeddings 呼叫中指定 batch_size。對於支援批次處理的模型,建議您使用大於 1 的 batch_size,以提升效能。
定義自訂模型的輸入、輸出和批次轉換函式。
-- Scalar input transform functions CREATE OR REPLACE FUNCTION acme_text_input_transform(model_id TEXT, input TEXT) RETURNS JSON; CREATE OR REPLACE FUNCTION acme_text_output_transform(model_id TEXT, model_output JSON) RETURNS real[]; CREATE OR REPLACE FUNCTION acme_generate_headers(model_id TEXT, input TEXT) RETURNS JSON; -- Batch input transform functions CREATE OR REPLACE FUNCTION acme_text_batch_input_transform(model_id TEXT, input TEXT[]) RETURNS JSON; CREATE OR REPLACE FUNCTION acme_text_batch_output_transform(model_id TEXT, model_output JSON) RETURNS real[][];如要建立模型,請指定批次轉換函式。
CALL ai.create_model( model_id => 'custom-embedding-model', model_request_url => 'https://acme.com/models/text/embeddings/v1', model_type => 'text_embedding', model_in_transform_fn => 'acme_text_input_transform', model_out_transform_fn => 'acme_text_output_transform', generate_headers_fn => 'acme_generate_headers', model_batch_in_transform_fn => 'acme_text_batch_input_transform', model_batch_out_transform_fn => 'acme_text_batch_output_transform' );使用自訂模型生成向量嵌入。
CALL ai.initialize_embeddings( model_id => 'custom-embedding-model', table_name => 'user_reviews', content_column => 'content', embedding_column => 'content_embeddings', batch_size => 10 );
您也可以搭配不支援批次的自訂模型使用自動嵌入功能。如要這麼做,您仍須定義批次轉換函式 model_batch_in_transform_fn 和 model_batch_out_transform_fn。如果是非批次處理模型,請定義這些函式,一次處理輸入陣列中的單一輸入。呼叫這個模型的 ai.initialize_embeddings 時,請將 batch_size 設為 1。
使用自訂維度 (支援批次作業)
如要搭配 OUTPUT_DIMENSIONALITY 參數使用自訂批次輸入轉換函式,您可以定義函式,在要求參數中指定所選維度。這項功能有助於針對支援可變輸出大小的模型,最佳化嵌入生成作業。
舉例來說,下列函式會為輸出維度為 768 的模型定義自訂批次輸入轉換:
CREATE OR REPLACE FUNCTION google_ml.vertexai_text_embedding_batch_input_transform_with_768_dims(model_id VARCHAR(100), input_list TEXT[])
RETURNS JSON
LANGUAGE SQL
AS $$
SELECT pg_catalog.json_build_object(
'instances',
pg_catalog.json_agg(pg_catalog.json_build_object('content', content)),
'parameters',
pg_catalog.json_build_object('outputDimensionality', 768)
) FROM unnest(input_list) AS content;
$$;
使用自訂模型進行 JSONB 最佳化
您可以在自訂輸出轉換函式中使用 JSONB 資料型別,提升效能。使用批次支援功能建立自訂模型時,google_ml_integration 擴充功能會自動尋找並使用轉換函式的 JSONB 變體。
這項最佳化措施可大幅提升自動產生嵌入內容的效能,因為 JSONB 是更有效率的二進位格式,可在 PostgreSQL 中儲存及處理 JSON 資料。
如要使用這項功能,您需要提供另一個版本的轉換函式,該函式接受 JSONB 引數,而不是 JSON。
舉例來說,假設您有下列簽章的批次輸出轉換函式:
CREATE OR REPLACE FUNCTION my_batch_output_transform(model_id TEXT, model_output JSON) RETURNS real[][];
您可以建立如下所示的 JSONB 變體:
CREATE OR REPLACE FUNCTION my_batch_output_transform(model_id TEXT, model_output JSONB) RETURNS real[][];
擴充功能會自動偵測函式的 JSONB 版本,並用於批次處理。如果您已建立使用 JSON 轉換函式的模型註冊,則無須更新 ai.create_model 呼叫。只要新 JSONB 函式與現有 JSON 函式使用完全相同的名稱,擴充功能就會自動偵測並使用 JSONB 變體進行批次處理。
逐步重新整理嵌入
重新整理嵌入內容時,系統會根據輸入內容資料欄中的最新值重新產生嵌入內容。
為方便您控管一致性和效能,AlloyDB Omni 支援多種模式,可逐步重新整理嵌入內容。您可以在 ai.initialize_embeddings() 中使用 incremental_refresh_mode 列舉引數選取模式。以下列出可能的模式:
transactional:在更新內容資料欄的交易中,一併重新整理嵌入內容。這個程序通常會使用類似資料庫觸發程序的機制,在內容欄更新時自動產生嵌入內容,但可能會造成額外負擔,並減緩更新作業。導入的額外負荷是為了維持交易語意,並確保嵌入內容與內容同步。這個模式會依據模型的純量轉換函式,因此您必須在建立模型時定義model_in_transform_fn和model_out_transform_fn。如要使用transactional模式,您必須具備表格的擁有者角色。CALL ai.initialize_embeddings( model_id => 'text-embedding-005', table_name => 'user_reviews', content_column => 'content', embedding_column => 'content_embeddings', batch_size => 10, incremental_refresh_mode => 'transactional' );在
transactional模式中,系統會使用觸發條件自動保持嵌入內容同步,因此ai.refresh_embeddings()函式會停用。如要為整個資料表重新產生嵌入內容,或從這個模式中中斷的ai.initialize_embeddings()呼叫復原,請先使用ai.drop_embedding_config()函式捨棄設定,然後重新發出ai.initialize_embeddings()呼叫。如果資料集或表格不大,且插入和更新的資料量相較於初始載入量較少 (例如,一百萬列的表格每天更新幾百列),就適合使用這種自動模式進行示範。如果維護即時資料一致性比更新作業期間產生的額外延遲更重要,就適合使用這項功能。
manual:這是預設模式。在這個模式下,系統會在表格中新增布林追蹤資料欄,追蹤過時的嵌入。呼叫ai.refresh_embeddings()函式會執行定期增量重新整理,只為新的或更新的資料列產生嵌入內容。如果使用者需要進一步控管效能,尤其是在初始載入後處理大量插入或更新作業時,建議使用這個模式。如果優先要盡量縮短寫入延遲時間,且可接受暫時過時或空值的嵌入,直到使用ai.refresh_embeddings觸發定期增量重新整理為止,就適合使用這項功能。如要更新過時或新的資料列,請按照「重新整理資料表的所有嵌入內容」一節的說明使用ai.refresh_embeddings()函式。
選擇重新整理模式
下表比較這兩種累加式重新整理模式,協助您為應用程式選擇最合適的方法。
| 模式 | 說明 | 一致性和效能 | 適用情境 |
|---|---|---|---|
transactional |
系統會使用類似觸發程序的機制,在資料庫交易中更新嵌入內容。請注意,ai.refresh_embeddings() 在這個模式下會停用。 |
立即保持一致性。每次 INSERT 或 UPDATE 都會觸發嵌入生成作業,導致寫入延遲時間過長。 |
示範、小型資料集或資料一致性至關重要的資料表。 |
manual (預設) |
使用布林追蹤資料欄監控過時或新的資料列。您必須呼叫 ai.refresh_embeddings(),才能觸發定期增量重新整理。
|
最終一致性。可選擇一次大量生成嵌入內容,將寫入延遲時間降到最低。 | 大型資料集、寫入頻率高的實際工作環境,或對效能要求嚴苛的應用程式。 |
重新整理資料表的所有嵌入
使用 manual 增量重新整理模式成功執行資料表的 ai.initialize_embeddings() 後,即可定期增量重新整理嵌入內容,並使用 ai.refresh_embeddings 觸發這項作業。您可以透過重新整理作業,更新在初始 initialize_embeddings 呼叫期間同時修改的資料列嵌入內容,或執行定期增量重新整理。
如果手動模式的嵌入建立程序遭到中斷 (例如透過 pg_cancel),請呼叫 ai.refresh_embeddings() 函式,完成其餘資料列的生成作業。
重新整理函式會重複使用初始呼叫中的設定,因此您只需要指定表格和嵌入資料欄。您也可以提供選用的 batch_size 來覆寫預設值。
CALL ai.refresh_embeddings(
table_name => 'user_reviews',
embedding_column => 'content_embeddings',
batch_size => 50 -- Optional override
);
在建立向量嵌入時處理表格資料
雖然 ai.initialize_embeddings() 是在執行階段中封鎖的呼叫,但其他連線仍可繼續使用資料表。自動向量嵌入程序會使用標準的資料列層級鎖定,分批更新資料列。也就是說,如果其他連線嘗試修改有效嵌入作業所指定的相同資料列,系統只會短暫封鎖並行資料修改語言 (DML) 作業 (例如 UPDATE 或 DELETE)。不會封鎖非修改型 SELECT 查詢。
刪除自動向量嵌入設定
如要移除特定表格和嵌入資料欄組合的自動向量嵌入設定,請使用 ai.drop_embedding_config() 函式。這項函式可用於清理資料,或重新設定資料欄的嵌入管理功能。
CALL
ai.drop_embedding_config(
table_name => 'user_reviews',
embedding_column => 'content_embeddings');
使用分區資料表
自動向量嵌入功能支援分區資料表。方便您有效管理大型分割資料集的嵌入內容。以下是使用分區資料表的常見用途。
初始化分區資料表的嵌入項目
您只能在資料表的根分區初始化嵌入內容。這項操作只需對整個分區資料表執行一次。
CALL ai.initialize_embeddings(
model_id => 'text-embeddings-005',
table_name => 'documents', -- This is the root partitioned table
content_column => 'content',
embedding_column => 'content_embeddings'
);
重新整理分區資料表的嵌入
初始化後,您可以重新整理任何分區的嵌入內容,包括根分區、子分區或個別葉分區。對於大型資料集,您可以從不同的資料庫連線,平行重新整理不同分割區的嵌入內容,藉此提升效能:
- 如要重新整理整個表格,請執行下列指令:
CALL ai.refresh_embeddings(
table_name => 'documents', -- This is the root partitioned table
embedding_column => 'content_embeddings'
);
- 如要重新整理單一資料分割,請執行下列指令:
CALL ai.refresh_embeddings(
table_name => 'documents_eu',
embedding_column => 'content_embeddings'
);
為新加入或附加的分割區重新整理嵌入內容
自動嵌入功能支援為併入主資料表的分割區產生嵌入內容,但須完成初始設定。具體步驟取決於您要新增完全新的分區,還是附加現有資料表。
- 新加入的分區:如果將新分區加入資料表,可以對新分區呼叫
ai.refresh_embeddings,產生該分區的嵌入內容。
-- Add a new partition
CREATE TABLE documents_africa PARTITION OF documents
FOR VALUES IN ('africa');
-- Refresh embeddings for the new partition
CALL ai.refresh_embeddings(
table_name => 'documents_africa',
embedding_column => 'content_embeddings'
);
- 新附加的分區:如要將現有資料表附加為分區,請先使用
ai.embedding_prepare_partition程序,確保資料表結構與分區資料表相容。自動嵌入功能支援在階層式分區設定的任何層級新增或附加分區。ai.embedding_prepare_partition程序可確保結構定義與階層中的任何父項資料表相容。
如要將現有資料表附加為分區,請先使用 ai.embedding_prepare_partition 程序,確保資料表結構定義與分區資料表相容:
-- Prepare the table to be attached
CALL ai.embedding_prepare_partition(
parent_table => 'documents',
child_table => 'documents_misc'
);
-- Attach the partition
ALTER TABLE documents ATTACH partition documents_misc DEFAULT;
-- Refresh embeddings for the newly attached partition
CALL ai.refresh_embeddings(
table_name => 'documents_misc',
embedding_column => 'content_embeddings'
);
自動嵌入功能支援在階層式分區設定的任何層級新增或附加分區。ai.embedding_prepare_partition 程序可確保結構定義與階層中的任何父項資料表相容:
-- Prepare a sub-partition for a non-root parent table
CALL ai.embedding_prepare_partition(
parent_table => 'documents_eu', -- An existing partition
child_table => 'documents_eu_germany'
);
-- Attach the new sub-partition
ALTER TABLE documents_eu ATTACH PARTITION documents_eu_germany
FOR VALUES IN ('germany');
-- Refresh embeddings for the new sub-partition
CALL ai.refresh_embeddings(
table_name => 'documents_eu_germany',
embedding_column => 'content_embeddings'
);
監控嵌入生成進度
您可以查詢 ai.embedding_progress_view,監控有效 initialize_embeddings 和 refresh_embeddings 呼叫的即時狀態。這個檢視畫面會顯示作業進度詳細資料,包括完成百分比、經過時間和預估剩餘時間。
如要查看進度,請執行下列查詢:
SELECT
table_name,
content_column,
embedding_column,
model_id,
percent_progress,
status,
elapsed_time,
rows_processed,
partition_root
FROM
ai.embedding_progress_view;
這個檢視畫面提供下列資訊:
| 欄 | 說明 |
|---|---|
table_name |
正在處理的資料表或分區名稱。 |
content_column |
含有嵌入來源內容的資料欄。 |
embedding_column |
儲存嵌入內容的資料欄。 |
model_id |
用於生成內容的模型。 |
percent_progress |
作業完成的百分比。 |
status |
作業的目前狀態 (例如執行中、成功)。 |
elapsed_time |
作業開始後經過的時間。 |
rows_processed |
目前處理的列數。 |
partition_root |
根分區資料表的名稱。 |
自動生成嵌入的範例
本節提供範例,說明如何使用已註冊的模型端點,在自動模式中生成嵌入。
OpenAI 嵌入模型
如要使用 OpenAI 提供的已註冊的 text-embedding-3-small 模型端點生成嵌入,請執行下列陳述式:
CALL ai.initialize_embeddings(
model_id => 'text-embedding-3-small',
table_name => 'user_reviews',
content_column => 'content',
embedding_column => 'content_embeddings'
);
自訂嵌入模型
如果是您自己的模型或外部支援的模型,您必須定義輸入和輸出轉換函式,並向 ai.create_model 註冊。如果您打算使用自動嵌入功能,就必須同時指定純量轉換函式 (例如 acme_text_input_transform、acme_text_output_transform) 和批次轉換函式 (例如 acme_text_batch_input_transform、acme_text_batch_output_transform)。