在 Azure AI 搜尋中為較小的向量設定向量量化和減少記憶體

重要

這些功能在補充使用規定下處於公開預覽狀態。 2024-03-01-Preview REST API 提供新的數據類型、向量壓縮屬性和 stored 屬性。

本文說明在 Azure AI 搜尋服務中壓縮向量索引的向量量化和其他技術。

評估選項

在第一個步驟中,請檢閱三個選項,以減少向量欄位所使用的記憶體數量。 這些選項並非互斥。

我們建議純量量化,因為它會以最少的努力壓縮記憶體和磁碟上的向量大小,而且在大部分案例中通常會提供最大效益。 相反地,窄型別(除了 Float16除外)需要特別努力進行製作,並 stored 儲存在磁碟記憶體上,這不像記憶體那麼昂貴。

方法 為何使用此選項
將較小的基本數據類型指派給向量欄位 縮小數據類型,例如 Float16Int16Int8,在記憶體和磁碟上耗用較少的空間,但您必須有內嵌模型,以窄型數據格式輸出向量。 或者,您必須具有輸出小型數據的自定義量化邏輯。 需要較少精力的第三個使用案例是將大部分模型所產生的原生 Float32 內嵌重新轉型為 Float16
排除可擷取向量的選擇性儲存 查詢回應中傳回的向量會與查詢執行期間所使用的向量分開儲存。 如果您不需要傳回向量,您可以關閉可擷取的記憶體,減少高達 50% 的整體每個欄位磁碟記憶體。
新增純量量化 使用內建純量量化,將原生 Float32 內嵌壓縮至 Int8。 此選項可減少記憶體和磁碟上的記憶體,而查詢效能不會降低。 較小的數據類型,例如 Int8 產生比內 Float32 嵌內容較少的向量索引。 為了抵消資訊遺失,內建壓縮包含使用未壓縮內嵌和過度取樣來傳回更相關結果的查詢后處理選項。 重新調整和過度取樣是 或 Float16 字段內建純量量化Float32的特定功能,無法用於進行自定義量化的內嵌。

所有這些選項都是在空的索引上定義。 若要實作其中任何一項,請使用 Azure 入口網站、2024-03-01-preview REST API 或 Beta Azure SDK 套件。

定義索引之後,您可以將檔載入並編製索引,做為個別步驟。

選項 1:將窄數據類型指派給向量欄位

向量欄位會儲存向量內嵌,以數位數位數位陣組表示。 當您指定欄位類型時,您可以指定用來儲存這些陣列內每個數位的基礎基本資料類型。 數據類型會影響每個數位佔用多少空間。

使用預覽 API,您可以指派窄型基本數據類型,以減少向量字段的儲存需求。

  1. 檢閱 向量欄位的資料類型:

    • Collection(Edm.Single) 32 位浮點數 (預設值)
    • Collection(Edm.Half) 16 位浮點數
    • Collection(Edm.Int16) 16 位帶正負號的整數
    • Collection(Edm.SByte) 8 位帶正負號的整數

    注意

    目前不支援二進位數據類型。

  2. 針對內嵌模型的輸出,或針對進行自定義量化的向量,選擇有效的數據類型。

    大部分的內嵌模型都會輸出 32 位浮點數,但如果您套用自定義量化,則輸出可能是 Int16Int8。 您現在可以定義接受較小格式的向量欄位。

    文字內嵌模型具有 的 Float32原生輸出格式,其會對應至 Collection(Edm.Single) Azure AI 搜尋服務。 您無法將輸出對應至 Int8 ,因為禁止從 float 轉換成 int 。 不過,您可以從轉換成 Float32Float16 (或 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 入口網站、2024-03-01-preview 或 Beta Azure SDK 套件。

  5. 檢查結果。 假設向量欄位標示為可擷取,請使用 搜尋 總管或 REST API 來驗證欄位內容符合數據類型。 請務必針對查詢使用正確的 2024-03-01-preview API 版本,否則不會顯示新的屬性。

若要檢查向量索引大小,請使用 Azure 入口網站 或 2024-03-01-preview

注意

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

選項 2:設定 stored 屬性以移除可擷取的記憶體

屬性 stored 是向量欄位定義上的新布爾值,可決定是否為可擷取的向量字段內容配置記憶體。 如果您在查詢回應中不需要向量內容,您可以將 設定 stored 為 false,為每個欄位儲存最多 50% 的記憶體。

由於向量不是人類可讀取的,所以通常會在搜尋頁面上轉譯的查詢回應中省略它們。 不過,如果您在下游處理中使用向量,例如將查詢結果傳遞至取用向量內容的模型或程式,您應該保持 stored 設定為 true,並選擇不同的技術來將向量大小降到最低。

下列範例顯示搜尋索引的 fields 集合。 設定 stored 為 false 以永久移除向量字段的可擷取記憶體。

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

重點︰

  • 僅適用於向量欄位

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

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

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

選項 3:設定純量量化

建議使用內建純量量化,因為它可減少記憶體和磁碟儲存需求,並新增重新取樣和過度取樣,以抵消較小索引的影響。 內建純量量化可以套用至包含 Float32Float16 數據的向量欄位。

若要使用內建向量壓縮:

  • 新增 vectorSearch.compressions 至搜尋索引。 此預覽中支援的壓縮演算法是 純量量化
  • 設定選擇性屬性以減輕遺失索引的影響。 和 defaultOversampling 都會rerankWithOriginalVectors在查詢執行期間提供優化。
  • 新增 vectorSearch.profiles.compression 至新的向量配置檔。
  • 將新的向量配置檔指派給新的向量欄位。

新增壓縮設定並設定選擇性屬性

在使用 2024-03-01-preview REST API 建立的索引定義中,新增 區 compressions 段。 使用下列 JSON 作為範本。

"compressions": [

      {  
        "name": "my-scalar-quantization",  
        "kind": "scalarQuantization",  
        "rerankWithOriginalVectors": true,  (optional)
        "defaultOversampling": 10.0,  (optional)
        "scalarQuantizationParameters": {  (optional)
             "quantizedDataType": "int8",  (optional)
        }
      }  
   ]

重點︰

  • kind 必須設定為 scalarQuantization。 這是目前唯一支援的量化方法。

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

  • defaultOversampling 會考慮一組更廣泛的潛在結果,以抵消量化信息減少。 潛在結果的公式包含 k 查詢中的 ,具有過度取樣乘數。 例如,如果查詢指定 5 的 , k 且過度取樣為 20,則查詢會有效要求 100 份檔用於重新執行,並針對該目的使用原始未壓縮的向量。 只會傳回最上層 k 重新建立的結果。 這個屬性為選擇性。 預設值為 4。

  • quantizedDataType 必須設定為 int8。 這是目前唯一支援的基本數據類型。 這個屬性為選擇性。 預設值為 int8

將壓縮設定新增至向量配置檔

純量量化會指定為新向量配置檔中的屬性。 您必須建立新的向量配置檔,才能在記憶體中建置壓縮索引。

在設定檔中,您必須使用階層式導覽小型世界 (HNSW) 演算法。 完整 KNN 不支援內建量化。

  1. 建立新的向量配置檔,並新增壓縮屬性。

    "profiles": [
       {
          "name": "my-vector-profile",
          "compression": "my-scalar-quantization", 
          "algorithm": "my-hnsw-vector-config-1",
          "vectorizer": null
       }
     ]
    
  2. 將向量配置檔指派給 新的 向量欄位。 純量量化會將內容縮減為 Int8,因此請確定您的內容為 Float32Float16

    在 Azure AI 搜尋中,實體資料模型 (EDM) 對等的 Float32Float16 類型 Collection(Edm.Single) 分別是 和 Collection(Edm.Half)

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

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

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

具有 vectorCompression、數據類型和預存屬性的範例索引

以下是搜尋索引的複合範例,指定窄數據類型、減少儲存空間和向量壓縮。

  • “HotelNameVector” 提供窄型數據類型範例,將原始 Float32Float16重新轉換為 ,如 Collection(Edm.Half) 搜尋索引中所表示。
  • “HotelNameVector” 也 stored 設定為 false。 不會儲存查詢回應中使用的額外內嵌。 當 為 false 時 storedretrievable 也必須為 false。
  • “DescriptionVector” 提供向量壓縮的範例。 向量壓縮是在索引中定義,在配置檔中參考,然後指派給向量字段。 “DescriptionVector” 也設定 stored 為 false。
### Create a new index
POST {{baseUrl}}/indexes?api-version=2024-03-01-preview  HTTP/1.1
    Content-Type: application/json
    api-key: {{apiKey}}

{
    "name": "hotels-vector-quickstart",
    "fields": [
        {
            "name": "HotelId", 
            "type": "Edm.String",
            "searchable": false, 
            "filterable": true, 
            "retrievable": true, 
            "sortable": false, 
            "facetable": false,
            "key": true
        },
        {
            "name": "HotelName", 
            "type": "Edm.String",
            "searchable": true, 
            "filterable": false, 
            "retrievable": true, 
            "sortable": true, 
            "facetable": false
        },
        {
            "name": "HotelNameVector",
            "type": "Collection(Edm.Half)",
            "searchable": true,
            "retrievable": false,
            "dimensions": 1536,
            "stored": false,
            "vectorSearchProfile": "my-vector-profile-no-compression"
        },
        {
            "name": "Description", 
            "type": "Edm.String",
            "searchable": true, 
            "filterable": false, 
            "retrievable": false, 
            "sortable": false, 
            "facetable": false
        },
        {
            "name": "DescriptionVector",
            "type": "Collection(Edm.Single)",
            "searchable": true,
            "retrievable": false,
            "dimensions": 1536,
            "stored": false,
            "vectorSearchProfile": "my-vector-profile-with-compression"
        },
        {
            "name": "Category", 
            "type": "Edm.String",
            "searchable": true, 
            "filterable": true, 
            "retrievable": true, 
            "sortable": true, 
            "facetable": true
        },
        {
            "name": "Tags",
            "type": "Collection(Edm.String)",
            "searchable": true,
            "filterable": true,
            "retrievable": true,
            "sortable": false,
            "facetable": true
        },
        {
            "name": "Address", 
            "type": "Edm.ComplexType",
            "fields": [
                {
                    "name": "City", "type": "Edm.String",
                    "searchable": true, "filterable": true, "retrievable": true, "sortable": true, "facetable": true
                },
                {
                    "name": "StateProvince", "type": "Edm.String",
                    "searchable": true, "filterable": true, "retrievable": true, "sortable": true, "facetable": true
                }
            ]
        },
        {
            "name": "Location",
            "type": "Edm.GeographyPoint",
            "searchable": false, 
            "filterable": true, 
            "retrievable": true, 
            "sortable": true, 
            "facetable": false
        }
    ],
"vectorSearch": {
    "compressions": [
        {
            "name": "my-scalar-quantization",
            "kind": "scalarQuantization",
            "rerankWithOriginalVectors": true,
            "defaultOversampling": 10.0,
                "scalarQuantizationParameters": {
                    "quantizedDataType": "int8"
                }
        }
    ],
    "algorithms": [
        {
            "name": "my-hnsw-vector-config-1",
            "kind": "hnsw",
            "hnswParameters": 
            {
                "m": 4,
                "efConstruction": 400,
                "efSearch": 500,
                "metric": "cosine"
            }
        },
        {
            "name": "my-hnsw-vector-config-2",
            "kind": "hnsw",
            "hnswParameters": 
            {
                "m": 4,
                "metric": "euclidean"
            }
        },
        {
            "name": "my-eknn-vector-config",
            "kind": "exhaustiveKnn",
            "exhaustiveKnnParameters": 
            {
                "metric": "cosine"
            }
        }
    ],
    "profiles": [      
        {
            "name": "my-vector-profile-with-compression",
            "compression": "my-scalar-quantization",
            "algorithm": "my-hnsw-vector-config-1",
            "vectorizer": null
        },
        {
            "name": "my-vector-profile-no-compression",
            "compression": null,
            "algorithm": "my-eknn-vector-config",
            "vectorizer": null
        }
    ]
},
    "semantic": {
        "configurations": [
            {
                "name": "my-semantic-config",
                "prioritizedFields": {
                    "titleField": {
                        "fieldName": "HotelName"
                    },
                    "prioritizedContentFields": [
                        { "fieldName": "Description" }
                    ],
                    "prioritizedKeywordsFields": [
                        { "fieldName": "Tags" }
                    ]
                }
            }
        ]
    }
}

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

此範例中的查詢語法適用於使用內建純量量化的向量字段。 根據預設,使用純量量化的向量字段也會使用 rerankWithOriginalVectorsdefaultOversampling 來減輕較小向量索引的影響。 這些設定是在 搜尋索引中指定。

在查詢上,您可以覆寫過度取樣預設值。 例如,如果 defaultOversampling 是 10.0,您可以將它變更為查詢要求中的其他專案。

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

POST https://[service-name].search.windows.net/indexes/[index-name]/docs/search?api-version=2024-03-01-Preview   
  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覆寫值或在查詢時引入過度取樣,即使索引的壓縮組態未指定過度取樣或重新取樣選項也一樣。

另請參閱