使用 AlloyDB AI 建構生成式 AI 應用程式

本節說明如何使用 pgvector 擴充功能叫用預測功能,以及查詢嵌入項目和建立索引。這些 AI 函式採用機器學習技術,可透過 AlloyDB AI 使用。AlloyDB AI 是一套 AlloyDB for PostgreSQL 功能,可讓您將機器學習 (ML) 模型的語意和預測功能套用至資料。

如要進一步瞭解 AlloyDB AI,請前往 https://cloud.google.com//alloydb/docs/ai

叫用預測

如要將 Vertex AI 整合至 AlloyDB Omni,並在 Vertex AI 儲存的模型上執行預測,請按照下列步驟操作。

事前準備

  1. 在 GDC 中啟用 Vertex AI 線上預測
  2. 執行下列指令,根據先前步驟下載的服務帳戶金鑰建立 Kubernetes 密鑰。請務必在與 DBCluster 資源相同的命名空間中建立 Kubernetes 密鑰。

    kubectl create secret generic SECRET_NAME \
    --from-file=PATH_TO_SERVICE_ACCOUNT_KEY/private-key.json \
    -n NAMESPACE

    更改下列內容:

    • SECRET_NAME:建立 DBCluster 資訊清單時使用的密鑰名稱,可讓 AlloyDB Omni 存取 Distributed Cloud AI 功能。例如:vertex-ai-key-alloydb

    • PATH_TO_SERVICE_ACCOUNT_KEY:您下載 private-key.json 服務帳戶金鑰的路徑。

    • NAMESPACE:資料庫叢集的命名空間。

  3. 按照「選擇資料庫引擎類型並建立資料庫叢集」一文列出的步驟,安裝 AlloyDB Omni 運算子。

  4. 使用 AlloyDB AI 建立資料庫叢集,並在 DBCluster 資訊清單的 googleMLExtension 欄位中,將 vertexAIKeyRef 設為在上一步中建立的 Kubernetes 密鑰。

    apiVersion: v1
    kind: Secret
    metadata:
      name: db-pw-DBCLUSTER_NAME
      namespace: USER_PROJECT
    type: Opaque
    data:
      DBCLUSTER_NAME: "BASE64_PASSWORD"
    ---
    apiVersion: DBENGINE_NAME.dbadmin.gdc.goog/v1
    kind: DBCluster
    metadata:
      name: DBCLUSTER_NAME
      namespace: USER_PROJECT
    spec:
      primarySpec:
        adminUser:
          passwordRef:
            name: db-pw-DBCLUSTER_NAME
        features:
          googleMLExtension:
            config:
              vertexAIKeyRef: SECRET_NAME
        version: "DB_VERSION"
        resources:
          memory: DB_MEMORY
          cpu: DB_CPU
          disks:
          - name: DataDisk
            size: DB_DATA_DISK
    

    請替換下列變數:

    • DBCLUSTER_NAME:資料庫叢集的名稱。
    • USER_PROJECT:要建立資料庫叢集的使用者專案名稱。
    • BASE64_PASSWORD:資料庫管理員密碼的 Base64 編碼。
    • DBENGINE_NAME:資料庫引擎的名稱。請設為 alloydbomni
    • DB_VERSION:資料庫引擎版本。
    • DB_MEMORY:分配給資料庫叢集的記憶體量,例如 5Gi
    • DB_CPU:分配給資料庫叢集的 CPU 數量,例如 2
    • DB_DATA_DISK:分配給資料庫叢集的空間大小,例如 10 Gi

    套用資訊清單。

    kubectl apply -f DB_CLUSTER_YAML

    更改下列內容:

    • DB_CLUSTER_YAML:這個資料庫叢集資訊清單檔案的名稱,例如 alloydb-omni-db-cluster.yaml
  5. 安裝 google_ml_integration 擴充功能。

    CREATE EXTENSION google_ml_integration CASCADE;
    

叫用預測

執行下列 ml_predict_row() SQL 函式,使用 Vertex AI 模型端點叫用線上預測:

  SELECT ml_predict_row('PREDICTION_ENDPOINT/PROJECT_NAMESPACE/ORGANIZATION/ZONE/DNS/DNS_SUFFIX', '{ "instances": [ INSTANCES ], "parameters":
  PARAMETERS');

更改下列內容:

  • PREDICTION_ENDPOINT:Vertex AI 端點的合格名稱

  • PROJECT_NAMESPACE:部署 Vertex AI 端點的命名空間

  • ORGANIZATION:部署 Vertex AI 端點的機構名稱

  • :部署 Vertex AI 端點的區域ZONE

  • DNS:貴機構的 DNS

  • DNS_SUFFIX:DNS 物件的尾碼

  • INSTANCES:預測呼叫的輸入內容,採用 JSON 格式

  • PARAMETERS:預測呼叫的參數,格式為 JSON

使用 pgvector 查詢及建立嵌入索引

pgvector PostgreSQL 擴充功能可讓您在資料庫中儲存、建立索引及查詢文字嵌入時,使用向量專屬的運算子和函式。AlloyDB 提供 pgvector 的最佳化功能,可讓您建立索引,加快涉及嵌入項目的特定查詢速度。

如要進一步瞭解如何將 AlloyDB 做為大型語言模型使用,以及如何根據大型語言模型產生及儲存向量嵌入,請參閱 https://cloud.google.com/alloydb/docs/ai/work-with-embeddings#index

使用 ScaNN 建立索引及查詢向量

本節說明如何使用儲存的嵌入生成索引,以及查詢嵌入。您可以使用 AlloyDB 建立 ScaNN 索引。

事前準備

開始建立索引前,請先完成下列必要條件。

  • 嵌入向量會新增至 AlloyDB 資料庫中的資料表。

  • 已安裝以 pgvector 為基礎,由 Google 為 AlloyDB 擴充的 vector 擴充功能版本 0.5.0 以上版本。

    CREATE EXTENSION IF NOT EXISTS vector;
    
  • 如要產生 ScaNN 索引,請安裝 postgres_ann 擴充功能,以及 vector 擴充功能。

    CREATE EXTENSION IF NOT EXISTS postgres_ann;
    

建立 ScaNN 索引

您可以為資料庫中的資料表建立 ScaNN 索引。

AlloyDB postgres_ann:Google 開發的 PostgreSQL 擴充功能,可實作由 ScaNN 演算法驅動的高效率最鄰近索引。

ScaNN 索引是樹狀結構的量化索引,用於近似最近鄰搜尋。可縮短索引建構時間,並減少記憶體用量。此外,系統還會根據工作負載提供快速 QPS。

兩層樹狀結構 ScaNN 索引

如要使用 ScaNN 演算法,將兩層樹狀結構索引套用至含有儲存向量嵌入的資料欄,請執行下列 DDL 查詢:

CREATE INDEX INDEX_NAME ON TABLE
  USING scann (EMBEDDING_COLUMN DISTANCE_FUNCTION)
  WITH (num_leaves=NUM_LEAVES_VALUE);

更改下列內容:

  • INDEX_NAME:要建立的索引名稱,例如 my-scann-index。索引名稱會在資料庫中共用。請確保資料庫中每個資料表的索引名稱都不重複。

  • TABLE:要新增索引的資料表。

  • EMBEDDING_COLUMN:儲存 vector 資料的資料欄。

  • DISTANCE_FUNCTION:要用於這個索引的距離函式。選擇下列其中一個選項:

    • L2 距離: l2

    • 點積: dot_product

    • 餘弦距離: cosine

  • NUM_LEAVES_VALUE:要套用至這個索引的分區數量。設為 1 到 1048576 之間的任何值。

三層樹狀結構 ScaNN 索引

如要使用 ScaNN 演算法,為含有已儲存向量嵌入的資料欄建立三層樹狀結構索引,請執行下列 DDL 查詢:

CREATE INDEX INDEX_NAME ON TABLE
  USING scann (EMBEDDING_COLUMN DISTANCE_FUNCTION)
  WITH (num_leaves=NUM_LEAVES_VALUE, max_num_levels = MAX_NUM_LEVELS);

更改下列內容:

  • MAX_NUM_LEVELS:K 平均值叢集樹狀結構的層級數量上限。設為 1(預設值) 可進行兩層樹狀結構量化,設為 2 則可進行三層樹狀結構量化。

建立索引後,您可以按照「使用指定文字進行最鄰近查詢」一文中的操作說明,執行最鄰近搜尋查詢,藉此使用索引。

請務必設定索引參數,在 QPS 和召回率之間取得適當平衡。

如要在使用 real[] 資料類型 (而非 vector) 的嵌入資料欄上建立這個索引,請將該資料欄轉換為 vector 資料類型:

CREATE INDEX INDEX_NAME ON TABLE
  USING scann (CAST(EMBEDDING_COLUMN AS vector(DIMENSIONS)) DISTANCE_FUNCTION)
  WITH (num_leaves=NUM_LEAVES_VALUE, max_num_levels = MAX_NUM_LEVELS);

請將 DIMENSIONS 改成嵌入資料欄的維度寬度。

如要查看索引建立進度,請使用 pg_stat_progress_create_index 檢視畫面:

SELECT * FROM pg_stat_progress_create_index;

phase」欄會顯示索引建立作業的目前狀態,而「building index: tree training」階段會在索引建立完成後消失。

執行查詢

將嵌入內容儲存並編入資料庫索引後,您就可以使用 pgvector 查詢功能開始查詢。您無法使用 postgres_ann 擴充功能執行大量搜尋查詢。

如要找出嵌入向量最鄰近的語意鄰項,可以執行下列查詢範例,並設定您在建立索引時使用的相同距離函式。

  SELECT * FROM TABLE
    ORDER BY EMBEDDING_COLUMN DISTANCE_FUNCTION_QUERY ['EMBEDDING']
    LIMIT ROW_COUNT

更改下列內容:

  • TABLE:包含要與文字比較的嵌入內容的資料表。

  • INDEX_NAME:要使用的索引名稱,例如 my-scann-index

  • EMBEDDING_COLUMN:包含儲存的嵌入內容的資料欄。

  • DISTANCE_FUNCTION_QUERY:要用於這項查詢的距離函式。根據建立索引時使用的距離函式,選擇下列其中一項:

    • L2 距離: <->

    • 內積: <#>

    • 餘弦距離: <=>

  • EMBEDDING:您要找出最接近的儲存語意鄰項的嵌入向量。

  • ROW_COUNT:要傳回的列數。

    如只要取得最佳單一比對結果,請指定 1

您也可以使用 embedding() 函式將文字翻譯成向量。您將向量套用至其中一個pgvector最鄰近運算子 (適用於 L2 距離) <->,找出具有語意最相似嵌入項目的資料庫列。請注意,您必須先註冊文字嵌入 Gecko 模型,才能使用這項函式。

由於 embedding() 會傳回 real 陣列,您必須明確將 embedding() 呼叫轉換為 vector,才能搭配 pgvector 運算子使用這些值。

  CREATE EXTENSION google_ml_integration;
  CREATE EXTENSION IF NOT EXISTS vector;

  SELECT * FROM TABLE
    ORDER BY EMBEDDING_COLUMN::vector
    <-> embedding('MODEL_IDVERSION_TAG', 'TEXT')
    LIMIT ROW_COUNT

更改下列內容:

  • MODEL_ID:要查詢的模型 ID。

    如果您使用 Vertex AI Model Garden,請指定 textembedding-gecko@003 做為模型 ID。這些是 Distributed Cloud 可用於文字嵌入的雲端模型。

  • 選用:VERSION_TAG:要查詢的模型版本標記。在標記開頭加上 @

    如果您使用其中一個 textembedding-gecko 英文模型搭配 Vertex AI,請指定其中一個版本標記,例如 textembedding-gecko@003

    Google 強烈建議您一律指定版本標記。如果您未指定版本標記,AlloyDB 一律會使用最新模型版本,這可能會導致非預期的結果。

  • TEXT:要翻譯成向量嵌入的文字。

向量索引指標

本節列出與您在 AlloyDB 中產生的向量索引相關的指標。安裝postgres_ann擴充功能後,即可使用 pg_stat_ann_indexes 檢視畫面查看這些指標。

可用性指標

可用性指標包括可協助您瞭解索引使用狀態的指標,例如索引設定和索引掃描次數。

指標名稱 資料類型 說明
relid OID 包含向量索引的資料表專屬 ID。
indexrelid OID 向量索引的專屬 ID。
schemaname NAME 索引所屬的結構定義名稱。
relname NAME 包含索引的資料表名稱。
indexrelname NAME 索引名稱。
indextype NAME 索引類型。這個值一律會設為 postgres_ann
indexconfig TEXT[] 建立索引時定義的設定,例如葉片數量和量化器。
indexsize TEXT 索引大小。
indexscan BIGINT 在索引上啟動的索引掃描次數。

調整指標

調整指標可提供目前的索引最佳化洞察資料,讓您套用建議,加快查詢效能。

指標名稱 資料類型 說明
insertcount BIGINT 索引的插入作業數。這項指標也包括建立索引前存在的任何列數。
updatecount BIGINT 索引的更新作業數。這項指標不會將任何 HOT 更新納入考量。
deletecount BIGINT 索引的刪除作業數量。
distribution JSONB 索引中所有分區的向量分布情形。

下列欄位會顯示分布情形:
  • maximum (INT8):所有分區的向量數量上限。
  • minimum (INT8):所有分區的向量數量下限。
  • average (FLOAT):所有分區的平均向量數。
  • outliers (INT8[]):所有分區中的頂尖離群值。這個值會顯示前 20 個離群值。

注意:由於 K 平均值叢集演算法的固有特性,即使是初始建立索引時,向量在各個分割區的分布情況也一定會出現某種程度的差異。

根據指標調整建議

更改
insertcountupdatecountdeletecount 指標會一起顯示索引向量的變化或突變。
索引是使用特定數量的向量和分區建立而成。對向量索引執行插入、更新或刪除等作業時,只會影響向量所在的初始分割區集。因此,每個分區中的向量數量會隨時間波動,可能影響召回率、每秒查詢次數或兩者。
如果 ANN 搜尋查詢長期出現速度緩慢或準確度問題 (例如 QPS 偏低或召回率不佳),請考慮查看這些指標。如果變動次數相對於向量總數偏高,可能表示需要重新建立索引。
分布
distribution」指標會顯示所有分割區的向量分布情形。
建立索引時,系統會以特定數量的向量和固定分區建立索引。系統會根據這項考量進行分割程序和後續分配。如果新增其他向量,系統會將這些向量分配到現有分區,因此與建立索引時的分配方式不同。由於最終分配並未同時考量所有向量,因此召回率、QPS 或兩者都可能受到影響。
如果發現 ANN 搜尋查詢的成效逐漸下滑,例如回應時間變慢或結果準確度降低 (以 QPS 或喚回度衡量),請考慮檢查這項指標並重新建立索引。