全部產品
Search
文件中心

Tablestore:向量檢索介紹與使用

更新時間:Sep 21, 2024

Table Store向量檢索(KnnVectorQuery)使用數值向量進行近似最近鄰查詢,可以在大規模資料集中找到最相似的資料項目。向量檢索功能適用於檢索增強產生(RAG)、推薦系統、相似性檢測、自然語言處理與語義搜尋等情境。

應用情境

向量檢索適用於推薦系統、映像與視頻檢索、自然語言處理與語義搜尋等情境。

  • 檢索增強產生(RAG)

    RAG是一種將檢索能力和大模型能力結合在一起的AI架構,通過檢索能力增強大模型輸出結果的準確性,尤其是在私域資料或者專業資料領域可以大幅提升大模型輸出結果的準確性。當前廣泛應用於知識庫情境。

  • 推薦系統

    在電商、社交媒體、視頻流媒體等平台中,使用者行為、偏好、內容特徵等內容可以編碼為向量進行儲存,然後通過向量檢索快速找到與使用者興趣相匹配的產品、文章或視頻,實現個人化推薦,提升使用者滿意度和留存率。

  • 相似性檢測(映像、視頻和語音等)

    在映像,視頻、語音、聲紋和Face Service等領域中,可以將這些非結構化的資料轉換為向量表示,然後通過向量檢索快速找到最相似的目標。例如,在電商平台中,使用者上傳一張圖片後,系統能迅速找出具有類似樣式、顏色或圖案的商品圖片。

  • 自然語言處理與語義搜尋

    在NLP領域,將文本轉換為向量表示(例如Word2Vec、BERT嵌入等),然後通過向量檢索理解查詢語句的語義,並找出語義上最相關的文檔、新聞、問答等內容,提升搜尋結果的相關性和使用者體驗。

  • 知識圖譜與智能問答

    知識圖譜節點和關係可以表示為向量,通過向量檢索能夠加速實體連結、關係推理以及智能問答系統的響應速度,使系統能夠更準確地理解和回回覆雜的問題。

功能概述

向量檢索(KnnVectorQuery)使用數值向量進行近似最近鄰查詢,可以在大規模資料集中找到最相似的資料項目。

向量檢索繼承了多元索引的所有特性,無需部署搭建系統,即開即用,隨用隨付。支援多元索引的流式構建,資料寫入表後近即時可查詢;支援高吞吐的新增、更新和刪除;查詢效能和採用HNSW演算法的系統相當。

使用KnnVectorQuery功能查詢資料時,您可以需要指定要查詢相似性的向量、要匹配的向量欄位以及要查詢的最鄰近TopK個值,來擷取向量欄位中與要查詢相似性的向量最相似的TopK個值。您還可以組合使用其他非向量檢索的查詢功能來過濾查詢結果。

向量欄位說明

使用KnnVectorQuery功能前,您需要在建立多元索引時配置向量欄位並指定向量維度、向量資料類型和向量之間的距離度量演算法。

向量欄位在資料表中對應欄位的資料類型必須為字串類型,在多元索引中的資料類型必須為Float32數組字串。向量欄位的具體配置說明請參見下表。

配置項

說明

dimension

向量維度,當前最大支援2048維。維度值必須和上遊向量產生(embedded)系統產生的向量維度一致。

向量欄位的數組長度與該欄位的dimension參數配置相等,例如向量欄位的值為[1, 5.1, 4.7, 0.08]字串,該欄位的維度為4。

說明

當前僅支援稠密向量,多元索引中向量欄位的資料維度必須和建立索引時Schema中設定的維度保持一致。如果過多或者過少都會導致該行資料構建索引失敗。

dataType

向量的資料類型。當前僅支援Float32,並且Float32不支援NaN和Infinite等極端值。

資料類型必須和上遊向量產生(embedded)系統產生的向量資料類型保持一致。

說明

如果有其他資料類型的向量使用需求,請提交工單聯絡我們。

metricType

向量之間的距離度量演算法。取值範圍包括歐氏距離(euclidean)、餘弦相似性(cosine)、點積(dot_product)。

距離度量演算法必須和上遊向量產生(embedded)系統的建議演算法保持一致。

更多資訊,請參見距離度量演算法說明

說明

向量產生(embedded)系統的不同模型或者不同版本產生的向量屬性不同,包括維度、資料類型和距離度量演算法。向量檢索系統中的向量欄位的屬性(維度、資料類型和距離度量演算法)必須和向量產生(embedded)系統中產生的向量屬性保持一致。關於向量產生的具體操作,請參見兩種產生向量的方式

距離度量演算法說明

向量檢索支援的距離度量演算法包括歐氏距離(euclidean)、餘弦相似性(cosine)、點積(dot_product)。具體說明請參見下表。評分公式的值越大表示兩個向量的相似性越大。

MetricType

評分公式

效能

說明

歐氏距離

(euclidean)

image

較高

多維空間中兩個向量之間的直線距離。出於效能考慮,Table Store中的歐氏距離演算法未進行最後的平方根計算。歐氏距離的評分越大表示兩個向量的相似性越大。

點積

(dot_product)

image

最高

維度相同的兩個向量的對應座標相乘,然後將結果相加。點積的評分越高表示兩個向量的相似性越大。

Float32向量必須在寫入表前進行歸一化(例如使用L2範數進行歸一化),否則會出現查詢效果差、構建向量索引慢、查詢效能差等潛在問題。

餘弦相似性

(cosine)

image

較低

向量空間中兩個向量間夾角的餘弦值。餘弦相似性的評分越高表示兩個向量的相似性越大。常用於文本資料的相似性計算。

由於0無法作為除數,無法完成餘弦相似性的計算,因此Float32向量的平方和不允許為0

餘弦相似性計算複雜,推薦您在寫入資料到表之前進行向量的歸一化,然後使用點積(dot_product)作為向量距離的度量演算法。

產品核心優勢

低成本

核心引擎採用最佳化後的DiskAnn技術,相較於HNSW演算法,無需載入所有索引資料到記憶體,只需不到10%的記憶體即可達到HNSW圖演算法的高召回率和高效能,使整體成本顯著低於同類型系統。

簡單易用

  • 向量檢索作為多元索引的一個子功能,也具備Serverless特性,使用者無需搭建部署系統,只需通過Table Store控制台建立執行個體即可開始使用。

  • 使用過程中支援隨用隨付,無需關心水位和擴容,系統在儲存和計算上均支援水平擴充。向量檢索最大可以支援千億規模,非向量檢索最大可以支援十萬億規模。

  • 向量檢索時內部引擎使用查詢最佳化工具自動選擇最佳演算法和執行路徑,無需進行眾多參數的調優即可達到高召回率和高效能,大幅降低使用門檻,有效縮短業務研發周期。

  • 支援通過SQL、多種SDK(Java、Golang、Python和Node.js等語言)和開源架構(Langchain、LangChain4J和LlamaIndex)等方式使用向量檢索。

計費說明

公測期間,使用向量索引不引入額外的向量索引專用計費項目,當前按照已有模式進行計費。

使用多元索引查詢資料時會消耗讀輸送量。更多資訊,請參見多元索引計量計費

前提條件

建立多元索引時已配置向量欄位。具體操作,請參見建立多元索引

說明

如果已建立多元索引,您可以通過動態修改Schema修改多元索引的Schema。具體操作,請參見動態修改schema

注意事項

使用向量檢索時,請注意如下事項:

  • 向量欄位類型的個數、維度等存在限制。更多資訊,請參見多元索引限制

  • 由於多元索引服務端是多分區的,多元索引服務端的每個分區均會返回自身最鄰近的TopK個值並在協調節點進行匯總,因此如果要使用Token翻頁擷取所有資料,則擷取到的總行數與多元索引服務端的分區數有關。

  • 目前支援使用向量檢索功能的地區包括華東1(杭州)、華東2(上海)、華北1(青島)、華北2(北京)、華北3(張家口)、華南1(深圳)、華南3(廣州)、西南1(成都)、中國香港、新加坡、馬來西亞(吉隆坡)、印尼(雅加達)、日本(東京)、德國(法蘭克福)、英國(倫敦)、沙特(利雅得)和菲律賓(馬尼拉)。

介面

向量檢索的介面為Search,具體的Query類型為KnnVectorQuery

參數

參數

是否必選

說明

fieldName

向量欄位名稱。

topK

查詢最鄰近的topK個值。關於最大值的說明請參見多元索引限制

重要
  • K值越大,召回率越好,但是查詢延遲和費用越高。

  • 當topK的值小於SearchQuery中limit的值時,服務端會自動把topK的值放大到limit的值。

float32QueryVector

要查詢相似性的向量。

filter

查詢過濾器,支援組合使用任意的非向量檢索的查詢條件。

使用方式

說明

如果使用向量檢索功能時遇到問題,請提交工單聯絡我們。

您可以使用控制台或者SDK進行向量檢索。進行向量檢索之前,您需要完成如下準備工作。

  • 使用阿里雲帳號或者使用具有Table Store操作許可權的RAM使用者進行操作。如果需要為RAM使用者授權Table Store操作許可權,請參見通過RAM Policy為RAM使用者授權進行配置。

    使用SDK方式和命令列工具方式進行操作時,如果當前無可用AccessKey,則需要為阿里雲帳號或者RAM使用者建立AccessKey。具體操作,請參見建立AccessKey

  • 已建立資料表。具體操作,請參見資料表操作

  • 已為資料表建立多元索引。具體操作,請參見建立多元索引

    在建立多元索引時需要配置向量欄位。

  • 使用SDK方式進行操作時,還需要完成初始化Client。具體操作,請參見初始化OTSClient

使用控制台

  1. 進入索引管理頁簽。

    1. 登入Table Store控制台

    2. 在頁面上方,選擇資源群組和地區。

    3. 概覽頁面,單擊執行個體名稱或在操作列單擊執行個體管理

    4. 執行個體詳情頁簽下的資料表列表頁簽,單擊資料表名稱或在操作列單擊索引管理

  2. 索引管理頁簽,單擊目標多元索引操作列的搜尋

  3. 查詢資料對話方塊,查詢資料。

    1. 系統預設返回所有列,如需顯示指定屬性列,關閉擷取所有列並輸入需要返回的屬性列,多個屬性列之間用半形逗號(,)隔開。

      說明

      系統預設會返回資料表的主鍵列。

    2. 根據需要選擇邏輯操作符為AndOr或者Not

      當選擇邏輯操作符為And時,返回滿足指定條件的資料。當選擇邏輯操作符為Or時,如果配置了單個條件,則返回滿足指定條件的資料;如果配置了多個條件,則返回滿足任意一個條件的資料。當選擇邏輯操作符為Not時,返回不滿足指定條件的資料。

    3. 選擇向量欄位,單擊添加

    4. 設定向量欄位的查詢類型為向量檢索(KnnVectorQuery)以及輸入要查詢的向量和topK值。

      請按照介面提示輸入符合格式的向量。

    5. 系統預設關閉排序功能,如需根據指定欄位對返回結果進行排序,開啟是否排序開關後,根據需要添加要進行排序的欄位並配置排序方式。

    6. 系統預設關閉統計功能,如需對指定欄位進行資料統計,開啟是否統計開關後,根據需要添加要進行統計的欄位和配置統計資訊。

  4. 單擊確定

    符合查詢條件的資料會顯示在索引管理頁簽中。

使用SDK

說明

Table StoreJava SDK從5.17.0版本開始支援向量檢索,Go SDK請使用最新SDK版本,Python SDK從5.4.4版本開始支援向量檢索,Node.js SDK從5.5.0版本開始支援向量檢索。

您可以通過Java SDKGo SDKPython SDKNode.js SDK使用向量檢索功能。此處以Java SDK為例介紹使用向量檢索的操作。

以下樣本用於查詢表中與指定向量最鄰近的10個向量資料,並且最鄰近的向量需要滿足Col_Keyword列值等於"hangzhou"且Col_Long列值小於4的條件。

private static void knnVectorQuery(SyncClient client) {
    SearchQuery searchQuery = new SearchQuery();
    KnnVectorQuery query = new KnnVectorQuery();
    query.setFieldName("Col_Vector");
    query.setTopK(10); // 返回最鄰近的topK。
    query.setFloat32QueryVector(new float[]{0.1f, 0.2f, 0.3f, 0.4f});
    // 最鄰近的向量需要滿足Col_Keyword=hangzhou && Col_Long<4條件。
    query.setFilter(QueryBuilders.bool()
            .must(QueryBuilders.term("Col_Keyword", "hangzhou"))
            .must(QueryBuilders.range("Col_Long").lessThan(4))
    );
    searchQuery.setQuery(query);
    searchQuery.setLimit(10);
    // 按照分數排序。
    searchQuery.setSort(new Sort(Collections.singletonList(new ScoreSort())));
    SearchRequest searchRequest = new SearchRequest("<TABLE_NAME>", "<SEARCH_INDEX_NAME>", searchQuery);
    SearchRequest.ColumnsToGet columnsToGet = new SearchRequest.ColumnsToGet();
    columnsToGet.setColumns(Arrays.asList("Col_Keyword", "Col_Long"));
    searchRequest.setColumnsToGet(columnsToGet);
    // 訪問Search介面。
    SearchResponse resp = client.search(searchRequest);
    for (SearchHit hit : resp.getSearchHits()) {
        // 列印分數。
        System.out.println(hit.getScore());
        // 列印資料。
        System.out.println(hit.getRow());
    }
}

相關文檔

附錄1:與BoolQuery組合使用說明

KnnVectorQuery可以和BoolQuery自由組合使用,不同的組合使用方式會有不同的效果,以下對兩種常見的使用方式進行說明。此處以一個Filter命中資料量較少的情境為例進行介紹。

假設表中有1億張圖片,其中使用者“a”總計有5萬張圖片,但是近7天內僅有50張圖片,使用者“a”希望以圖搜圖的方式找到7天內最相似的10張圖片。由下表說明可知KnnVectorQuery的Filter內部使用BoolQuery的組合使用方式能滿足使用者“a”的查詢需求。

組合使用方式

查詢條件圖示

說明

KnnVectorQuery的Filter內部使用BoolQuery

image

KnnVectorQuery命中的行資料為在滿足BoolQuery條件下返回最相似的TopK個行資料,SearchRequest返回的結果為TopK行數中的前Size個。

在此樣本中,KnnVectorQuery首先通過Filter篩選出該使用者“a”在7天內的所有50張圖片,然後再從50張圖片中找到最相似的10張圖片返回給使用者。

BoolQuery中使用KnnVectorQuery

image

BoolQuery的每一個子查詢條件會首先進行查詢,然後對所有子查詢求交集。

在此樣本中,KnnVectorQuery會返回表中1億張圖片中最相似的前TopK=500張圖片,然後再按照順序找出使用者“a”在7天內的10張圖片。但是由於所有圖片的TopK=500張圖片中不一定包含使用者“a”近7天內所有的50張圖片,因此該查詢方式不一定能找到近7天內的10張圖片,甚至找不到任何資料。

附錄2:向量歸一化樣本

向量歸一化的範例程式碼如下:

  public static float[] l2normalize(float[] v, boolean throwOnZero) {
    double squareSum = 0.0f;
    int dim = v.length;
    for (float x : v) {
      squareSum += x * x;
    }
    if (squareSum == 0) {
      if (throwOnZero) {
        throw new IllegalArgumentException("can't normalize a zero-length vector");
      } else {
        return v;
      }
    }
    double length = Math.sqrt(squareSum);
    for (int i = 0; i < dim; i++) {
      v[i] /= length;
    }
    return v;
  }