共用方式為


透過量化、縮小資料類型和儲存體選項來減少向量大小

本文說明如何使用向量量化和其他技術來減少 Azure AI 搜尋服務中的向量大小。 搜尋索引會指定向量欄位定義,包括預存和精簡資料類型的屬性。 量化也會在索引中指定,並透過其向量設定檔指派給向量欄位。

這些功能已在 2024-07-01 REST API 和以該版本為目標的 Azure SDK 套件中正式推出。 本文結尾的範例顯示本文所述每一種方法的向量大小變化。

評估選項

在第一個步驟中,請檢閱三個方法,減少向量欄位所使用的儲存空間大小。 這些方法並非互斥,而且可以合併以達到向量大小縮減上限

我們建議採用內建量化,因為會以最少的投入,壓縮記憶體「和」磁碟上的向量大小,而且在大部分案例中通常會提供最大效益。 相較之下,精簡類型 (除了 float16 之外) 需要特別投入,且 stored 會儲存在磁碟儲存體上,不像記憶體那般昂貴。

方法 為何要使用此選項
新增純量或二進位量化 使用量化將原生 float32 或 float16 內嵌壓縮為 int8 (純量) 或位元組 (二進位)。 此選項可減少記憶體和磁碟上的儲存空間,且查詢效能不會降低。 較小的資料類型 (例如 int8 或位元組) 會產生內容比較大內嵌少的向量索引。 為了克服資訊遺失,內建壓縮會包含使用未壓縮內嵌和過度取樣來傳回更相關結果的查詢後處理選項。 重新排名和過度取樣是 float32 或 float16 欄位內建量化的特定功能,無法用於進行自訂量化的內嵌。
將較小的基本資料類型指派給向量欄位 精簡資料類型,例如 float16、int16、int8 和位元組 (二進位) 在記憶體和磁碟上耗用較少的空間,但您必須有內嵌模型,以精簡資料格式輸出向量。 或者,您必須具有輸出小型資料的自訂量化邏輯。 需要較少投入的第三個使用案例是將大部分模型所產生的原生 float32 內嵌重新轉換成 float16。 如需二進位向量的詳細資訊,請參閱索引二進位向量
排除可擷取向量的選擇性儲存 查詢回應中傳回的向量會與查詢執行期間所使用的向量分開儲存。 如果您不需要傳回向量,您可以關閉可擷取的儲存空間,減少高達 50% 的整體各欄位磁碟記憶體。

所有這些選項都是在空的索引上定義。 若要實作其中任何一項,請使用 Azure 入口網站、REST API 或以該 API 版本為目標的 Azure SDK 套件。

定義索引之後,您可以載入文件並編製索引,作為個別步驟。

選項 1:設定量化

建議量化以減少向量大小,因為它會降低 float16 和 float32 內嵌的記憶體和磁碟儲存體需求。 若要位移較小索引的效果,您可以新增過度取樣,並透過未壓縮的向量重新排名。

量化適用於接收浮點數型向量的向量欄位。 在本文中的範例中,欄位的資料類型為 Collection(Edm.Single),適用於傳入 float32 內嵌,但也支援 float16。 在設定壓縮的欄位上收到向量時,引擎會自動執行量化,以減少記憶體和磁碟上的向量資料使用量。

支援兩種類型的量化:

  • 純量量化會將浮點數值壓縮成較精簡的資料類型。 AI 搜尋目前支援 int8,也就是 8 位元,可減少向量索引大小四倍。

  • 二進位量化會將浮點數轉換成二進位位元,這需要 1 位元。 這可減少最多 28 倍的向量索引大小。

若要使用內建量化,請遵循下列步驟:

  • 使用 [建立索引] 或 [建立或更新索引] 來指定向量壓縮
  • vectorSearch.compressions 新增至搜尋索引
  • 新增 scalarQuantizationbinaryQuantization 組態,並為其提供名稱
  • 設定選擇性屬性,以減輕編製索引失真的影響
  • 建立使用具名組態的新向量設定檔
  • 建立具有新向量設定檔的新向量欄位
  • 透過您定義的組態,使用 float32 或 float16 資料載入已在編製索引期間量化的索引
  • 如果您想要覆寫預設值,請選擇性地使用過度取樣參數查詢量化資料

將「壓縮」新增至搜尋索引

下列範例顯示部分索引定義,其中具有包含向量欄位和 vectorSearch.compressions 區段的欄位集合。

這個範例包含 scalarQuantizationbinaryQuantization。 您可以視需要指定盡可能多的壓縮組態,然後將您想要的壓縮組態指派給向量設定檔。

POST https://[servicename].search.windows.net/indexes?api-version=2024-07-01

{
  "name": "my-index",
  "fields": [
    { "name": "Id", "type": "Edm.String", "key": true, "retrievable": true, "searchable": true, "filterable": true },
    { "name": "content", "type": "Edm.String", "retrievable": true, "searchable": true },
    { "name": "vectorContent", "type": "Collection(Edm.Single)", "retrievable": false, "searchable": true },
  ],
  "vectorSearch": {
        "profiles": [ ],
        "algorithms": [ ],
        "compressions": [
          {
            "name": "use-scalar",
            "kind": "scalarQuantization",
            "scalarQuantizationParameters": {
              "quantizedDataType": "int8"
            },
            "rerankWithOriginalVectors": true,
            "defaultOversampling": 10
          },
          {
            "name": "use-binary",
            "kind": "binaryQuantization",
            "rerankWithOriginalVectors": true,
            "defaultOversampling": 10
          }
        ]
    }
}

重點︰

  • kind 必須設定為 scalarQuantizationbinaryQuantization

  • rerankWithOriginalVectors 會使用原始未壓縮的向量來重新計算相似度,並將初始搜尋查詢所傳回的前幾個結果重新排名。 即使 stored 為 false,未壓縮的向量仍存在於搜尋索引中。 這個屬性為選擇性。 預設為 true。

  • defaultOversampling 會考慮一組更廣泛的潛在結果,以克服量化資訊減少的問題。 潛在結果的公式包含查詢中的 k,以及過度取樣乘數。 例如,如果查詢指定 k (總計 5),且過度取樣為 20,則查詢會有效要求 100 份文件用於重新排名,並針對該目的使用原始未壓縮的向量。 只會傳回前 k 個重新排名的結果。 這個屬性為選擇性。 預設值為 4。

  • quantizedDataType 是選擇性的,且僅適用於純量量化。 如果您新增它,則必須設定為 int8。 這是目前唯一支援純量量化的基本資料類型。 預設值為 int8

新增 HNSW 演算法

請確定您的索引具有階層式導覽小型世界 (HNSW) 演算法。 完整 KNN 不支援內建量化。

"vectorSearch": {
    "profiles": [ ],
    "algorithms": [
      {
          "name": "use-hnsw",
          "kind": "hnsw",
          "hnswParameters": {
              "m": 4,
              "efConstruction": 400,
              "efSearch": 500,
              "metric": "cosine"
          }
      }
    ],
     "compressions": [ <see previous section>] 
}

建立並指派新的向量設定檔

若要使用新的量化設定,您必須建立新的向量設定檔。 您必須建立新的向量設定檔,才能在記憶體中建置壓縮索引。 您的新設定檔會使用 HNSW。

  1. 在相同的索引定義中,建立新的向量設定檔,並新增壓縮屬性和演算法。 以下是兩個設定檔,每個量化方法各一個。

    "vectorSearch": {
        "profiles": [
           {
              "name": "vector-profile-hnsw-scalar",
              "compression": "use-scalar", 
              "algorithm": "use-hnsw",
              "vectorizer": null
           },
           {
              "name": "vector-profile-hnsw-binary",
              "compression": "use-binary", 
              "algorithm": "use-hnsw",
              "vectorizer": null
           }
         ],
         "algorithms": [  <see previous section> ],
         "compressions": [ <see previous section> ] 
    }
    
  2. 將向量設定檔指派給新的向量欄位。 欄位的資料類型為 float32 或 float16。

    在 Azure AI 搜尋服務中,與 float32 和 float16 類型相當的實體資料模型 (EDM) 分別是 Collection(Edm.Single)Collection(Edm.Half)

    {
       "name": "vectorContent",
       "type": "Collection(Edm.Single)",
       "searchable": true,
       "retrievable": true,
       "dimensions": 1536,
       "vectorSearchProfile": "vector-profile-hnsw-scalar",
    }
    
  3. 使用索引器來載入索引,以提取模型索引,或使用推送模型索引的 API。

純量量化可減少每個向量內嵌中各個數字的解析度。 純量量化會使用 8 位數的整數,而不是將每個數字描述為 16 位元或 32 位元的浮點數。 純量量化會識別數字範圍 (通常是第 99 個百分位數下限和上限),並分割成有限數目的層級或間隔,並且為每個間隔指派識別碼。 在 8 位元的純量量化中,有 2^8 或 256 個可能的間隔。

向量的每個元件都會對應至這一組量化層級內最接近的代表值,其過程類似於將實數四捨五入為最接近的整數。 在量化的 8 位數向量中,識別碼編號會取代原始值。 量化之後,每個向量都會以其元件所屬間隔的識別碼陣列表示。 相較於原始向量,這些量化向量所需的儲存間隔少很多,因此可減少儲存需求和磁碟使用量。

二進位量化會藉由將每個元件表示為單一位元 0 或 1 來壓縮高維度向量。 此方法可大幅減少記憶體使用量,並加速向量比較作業,這對搜尋和擷取工作至關重要。 效能評定測試顯示向量索引大小最多可減少96%。

對於維度大於 1024 的內嵌特別有效。 針對較小的維度,建議您改為測試二進位量化的品質,或改為嘗試純量。 此外,我們發現 BQ 在內嵌以零為中心時表現非常好。 最熱門的內嵌模型,例如 OpenAI、Cohere 和 Mistral 都以零為中心。

選項 2:將窄資料類型指派給向量欄位

減少向量大小的簡單方法是以較小的資料格式儲存內嵌。 大部分的內嵌模型都會輸出 32 位元浮點數,但如果您量化向量,或內嵌模型原生支援,則輸出可能是 float16、int16 或 int8,這明顯小於 float32。 您可以將精簡資料類型指派給向量欄位,以容納這些較小的向量大小。 在向量索引中,精簡資料類型會耗用較少的儲存體。

  1. 檢閱用於向量欄位的資料類型,以取得建議的使用方式:

    • Collection(Edm.Single) 32 位元浮點數 (預設值)
    • Collection(Edm.Half) 16 位元浮點數 (精簡)
    • Collection(Edm.Int16) 16 位元帶正負號的整數 (精簡)
    • Collection(Edm.SByte) 8 位元帶正負號的整數 (精簡)
    • Collection(Edm.Byte) 8 位元不帶正負號的整數 (只允許搭配封裝的二進位資料類型)
  2. 從該清單中,判斷哪一個資料類型對內嵌模型的輸出有效,或用於進行自訂量化的向量。

    下表提供數個內嵌模型的連結,這些模型可以使用精簡資料類型 (Collection(Edm.Half)),而不需額外的量化。 您可以從 float32 轉換為 float16 (使用 Collection(Edm.Half)),而不需要額外的工作。

    內嵌模型 原生輸出 在 Azure AI 搜尋服務中指派此類型
    text-embedding-ada-002 Float32 Collection(Edm.Single)Collection(Edm.Half)
    text-embedding-3-small Float32 Collection(Edm.Single)Collection(Edm.Half)
    text-embedding-3-large Float32 Collection(Edm.Single)Collection(Edm.Half)
    Cohere V3 內嵌模型,搭配 int8 embedding_type Int8 Collection(Edm.SByte)

    如果您的模型以較小的資料格式發出內嵌,或者如果您有將向量轉換成較小格式的自訂量化,則可以使用其他精簡資料類型。

  3. 請務必了解使用窄資料類型的取捨。 Collection(Edm.Half) 資訊較少,會導致解析度較低。 如果您的資料是同質或密集資料,遺失額外的詳細資料或細微差別可能會導致查詢時間發生難以接受的結果,因為可用來區分附近向量的詳細資料較少。

  4. 定義及建置索引。 您可以針對此步驟使用 Azure 入口網站、建立或更新索引 (REST API) 或 Azure SDK 套件。

  5. 查看結果。 假設向量欄位標示為可擷取,請使用搜尋總管搜尋 - POST 來確認欄位內容符合資料類型。

    若要檢查向量索引大小,請使用 Azure 入口網站或 GET 統計資料 (REST API)

注意

欄位的資料類型可用來建立實體資料結構。 如果您想要在稍後變更資料類型,請卸除並重建索引,或使用新的定義建立第二個欄位。

選項 3:設定 stored 屬性以移除可擷取的儲存體

stored 屬性是向量欄位定義上的布林值,可決定是否為可擷取的向量欄位內容配置儲存體。 stored 屬性依預設為 true。 如果您在查詢回應中不需要向量內容,您可以將 stored 設定為 false,為每個欄位節省高達 50% 的儲存體。

stored 設定為 false 的考量:

  • 由於人類無法讀取向量,因此您可以從 RAG 案例中傳送至 LLM 的結果,以及從搜尋頁面上轉譯的結果中省略它們。 不過,如果您要在取用向量內容的下游流程中使用向量,請保留它們。

  • 不過,如果您的索引策略包含部分文件更新,例如文件中的「merge」或「mergeOrUpload」,請注意,將 stored 設定為 false 會導致非預存欄位中的向量在合併期間省略。 在每個「merge」或「mergeOrUpload」作業上,除了您要更新的其他非向量欄位之外,您還必須提供向量欄位,否則會卸除向量。

請記住,stored 屬性是不可逆轉的。 在建立實體資料結構時,它會在向量欄位上於索引建立期間設定。 如果您想要稍後可擷取的向量內容,您必須卸除並重建索引,或建立並載入具有新屬性的新欄位。

下列範例會顯示搜尋索引的欄位集合。 將 stored 設定為 false,以永久移除向量欄位的可擷取儲存空間。

PUT https://[service-name].search.windows.net/indexes/demo-index?api-version=2024-07-01 
   Content-Type: application/json  
   api-key: [admin key]  
 
     { 
       "name": "demo-index", 
       "fields": [ 
         { 
           "name": "vectorContent", 
           "type": "Collection(Edm.Single)", 
           "retrievable": false, 
           "stored": false, 
           "dimensions": 1536, 
           "vectorSearchProfile": "vectorProfile" 
         } 
       ] 
     } 

重點︰

  • 僅適用於向量欄位

  • 影響磁碟上的儲存空間,而非記憶體,且不會影響查詢。 查詢執行會使用不受 stored 屬性影響的不同向量索引。

  • 在向量欄位的索引建立期間,會設定 stored 屬性,而且無法復原。 如果您想要稍後擷取內容,您必須卸除並重建索引,或建立並載入具有新屬性的新欄位。

  • 預設值為 stored 設為 true,retrievable 設為 false。 在預設設定中,會儲存可擷取的副本,但不會在結果中自動傳回。 當 stored 為 true 時,您可以隨時在 true 和 false 之間切換 retrievable,而不需要重建索引。 當 stored 為 false 時,retrievable 必須是 false 且無法變更。

範例:向量壓縮技術

以下是示範量化、精簡資料類型和使用預存屬性的 Python 程式碼:程式碼範例:使用 Python 的向量量化和儲存選項

此程式碼會為每個選項建立和比較儲存空間和向量索引大小:

****************************************
Index Name: compressiontest-baseline
Storage Size: 21.3613MB
Vector Size: 4.8277MB
****************************************
Index Name: compressiontest-compression
Storage Size: 17.7604MB
Vector Size: 1.2242MB
****************************************
Index Name: compressiontest-narrow
Storage Size: 16.5567MB
Vector Size: 2.4254MB
****************************************
Index Name: compressiontest-no-stored
Storage Size: 10.9224MB
Vector Size: 4.8277MB
****************************************
Index Name: compressiontest-all-options
Storage Size: 4.9192MB
Vector Size: 1.2242MB

搜尋 API 會報告索引層級的儲存空間和向量大小,因此索引和欄位不一定是比較的基礎。 使用 Azure SDK 中的 GET 索引統計資料或對等 API 來取得向量大小。

使用過度取樣查詢量化向量欄位

壓縮或量化向量欄位的查詢語法與非壓縮向量欄位相同,除非您想要覆寫與過度取樣或以原始向量重新排名相關聯的參數。

回想一下,索引中的向量壓縮定義具有 rerankWithOriginalVectorsdefaultOversampling 的設定,以減輕較小向量索引的影響。 您可以覆寫預設值,以在查詢時間改變行為。 例如,如果 defaultOversampling 為 10.0,您可以將其變更為查詢要求中的其他值。

即使索引沒有明確的 rerankWithOriginalVectorsdefaultOversampling 定義,您也可以設定過度取樣參數。 在查詢時間提供 oversampling 會覆寫該查詢的索引設定,並以有效的 rerankWithOriginalVectors 為 true 來執行查詢。

POST https://[service-name].search.windows.net/indexes/demo-index/docs/search?api-version=2024-07-01   
  Content-Type: application/json   
  api-key: [admin key]   

    {    
       "vectorQueries": [
            {    
                "kind": "vector",    
                "vector": [8, 2, 3, 4, 3, 5, 2, 1],    
                "fields": "myvector",
                "oversampling": 12.0,
                "k": 5   
            }
      ]    
    }

重點︰

  • 適用於進行向量壓縮的向量欄位 (根據向量設定檔指派)。

  • 覆寫 defaultOversampling 值,或在查詢時引入過度取樣,即使索引的壓縮設定未指定過度取樣或重新排名選項也一樣。

另請參閱