Share via


Azure AI 검색에서 더 작은 벡터에 대한 벡터 양자화 및 스토리지 절약 구성

Important

이 기능은 공개 미리 보기로 제공되며 추가 사용 약관의 적용을 받습니다. 2024-03-01-Preview REST API는 새 데이터 형식, 벡터 압축 속성 및 stored 속성을 제공합니다.

이 문서에서는 Azure AI 검색에서 벡터 인덱스를 압축하기 위한 벡터 양자화 및 기타 기술에 대해 설명합니다.

옵션 평가

첫 번째 단계로, 벡터 필드에 사용되는 스토리지를 줄이기 위한 세 가지 옵션을 검토합니다. 이러한 옵션은 상호 배타적이지 않습니다.

스칼라 양자화는 최소한의 활동으로 메모리와 디스크의 벡터 크기를 압축하고 대부분의 시나리오에서 가장 큰 이점을 제공하는 경향이 있으므로 권장됩니다. 대조적으로, 좁은 형식(Float16 제외)은 이를 만드는데 특별한 활동이 필요하며, stored는 메모리만큼 비싸지 않은 디스크 스토리지를 절약합니다.

접근법 옵션 사용 이유
벡터 필드에 더 작은 기본 데이터 형식 할당 Float16, Int16Int8과 같은 좁은 데이터 서식은 메모리와 디스크에서 더 적은 공간을 사용하지만 좁은 데이터 서식으로 벡터를 출력하는 포함 모델이 있어야 합니다. 또는 작은 데이터를 출력하는 사용자 지정 양자화 논리가 있어야 합니다. 더 적은 활동이 필요한 세 번째 사용 사례는 대부분의 모델에서 생성된 네이티브 Float32 포함을 Float16으로 다시 캐스팅하는 것입니다.
선택적 검색 가능 벡터 스토리지 제거 쿼리 응답에서 반환되는 벡터는 쿼리 실행 중에 사용되는 벡터와 별도로 저장됩니다. 벡터를 반환할 필요가 없는 경우 검색 가능 디스크 스토리지를 비활성화하여 전체 필드별 스토리지를 최대 50%까지 줄일 수 있습니다.
스칼라 양자화 추가 기본 제공 스칼라 양자화를 사용하여 네이티브 Float32 포함을 Int8로 압축합니다. 이 옵션은 쿼리 성능 저하 없이 메모리 및 디스크의 스토리지를 줄입니다. Int8과 같은 더 작은 데이터 형식은 Float32 포함을 사용하는 것보다 콘텐츠가 덜 풍부한 벡터 인덱스를 생성합니다. 정보 손실을 상쇄하기 위해 기본 제공 압축에는 압축되지 않은 포함 및 오버샘플링을 사용하여 보다 관련성이 높은 결과를 반환하는 쿼리 후 처리 옵션이 포함되어 있습니다. 순위 재지정 및 오버샘플링은 Float32 또는 Float16 필드의 기본 제공 스칼라 양자화에 특정된 기능이며 사용자 지정 양자화를 수행하는 포함에는 사용할 수 없습니다.

이러한 옵션 모두는 빈 인덱스로 정의됩니다. 이들 중 하나를 구현하려면 Azure Portal, 2024-03-01-preview REST API 또는 베타 Azure SDK 패키지를 사용하세요.

인덱스가 정의되면 문서를 별도의 단계로 로드하고 인덱싱할 수 있습니다.

옵션 1: 벡터 필드에 좁은 데이터 형식 할당

벡터 필드는 숫자 배열로 표현되는 벡터 포함을 저장합니다. 필드 형식을 지정할 때 사용자가 이러한 배열 내에서 각 숫자를 보유하는 데 사용되는 기본 데이터 형식을 지정합니다. 데이터 형식은 각 숫자가 차지하는 공간에 영향을 줍니다.

미리 보기 API를 사용해 좁은 기본 데이터 형식을 할당하여 벡터 필드의 스토리지 요구 사항을 줄일 수 있습니다.

  1. 벡터 필드의 데이터 형식을 살펴봅니다.

    • Collection(Edm.Single) 32비트 부동 소수점(기본값)
    • Collection(Edm.Half) 16비트 부동 소수점
    • Collection(Edm.Int16) 16비트 부호 있는 정수
    • Collection(Edm.SByte) 8비트 부호 있는 정수

    참고 항목

    이진 데이터 형식은 현재 지원되지 않습니다.

  2. 포함 모델의 출력 또는 사용자 지정 양자화를 거치는 벡터에 유효한 데이터 형식을 선택합니다.

    대부분의 포함 모델은 32비트 부동 소수점 숫자를 출력하지만 사용자 지정 양자화를 적용하는 경우 출력이 Int16 또는 Int8일 수 있습니다. 이제 더 작은 형식을 허용하는 벡터 필드를 정의할 수 있습니다.

    텍스트 포함 모델에는 Azure AI 검색의 Collection(Edm.Single)에 매핑되는 Float32의 네이티브 출력 형식이 있습니다. float에서 int로의 캐스팅이 금지되어 있으므로 해당 출력을 Int8에 매핑할 수 없습니다. 그러나 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)
    int8 embedding_type을 사용하는 Cohere V3 포함 모델 Int8 Collection(Edm.SByte)
  3. 좁은 데이터 형식의 장단점을 이해해야 합니다. Collection(Edm.Half)은 정보가 더 적으므로 해상도가 낮습니다. 같은 유형의 데이터이거나 밀집 데이터인 경우 추가 세부 정보나 미묘한 차이가 손실되면 인접 벡터를 구별하는 데 사용할 수 있는 세부 정보가 적기 때문에 쿼리 시 허용할 수 없는 결과가 발생할 수 있습니다.

  4. 인덱스를 정의하고 작성합니다. 이 단계에서는 Azure Portal, 2024-03-01-preview 또는 베타 Azure SDK 패키지를 사용할 수 있습니다.

  5. 결과를 확인합니다. 벡터 필드가 검색 가능한 것으로 표시되어 있다고 가정하고 검색 탐색기 또는 REST API를 사용하여 필드 콘텐츠가 데이터 형식과 일치하는지 확인합니다. 쿼리에 올바른 2024-03-01-preview API 버전을 사용해야 합니다. 그러지 않으면 새 속성이 표시되지 않습니다.

벡터 인덱스 크기를 확인하려면 Azure Portal 또는 2024-03-01-preview를 사용합니다.

참고 항목

필드의 데이터 형식은 실제 데이터 구조를 만드는 데 사용됩니다. 나중에 데이터 형식을 변경하려면 인덱스를 삭제 후 다시 작성하거나 새 정의로 두 번째 필드를 만듭니다.

옵션 2: 검색 가능 스토리지를 제거하도록 stored 속성 설정

stored 속성은 검색 가능 벡터 필드 콘텐츠에 스토리지가 할당되는지 여부를 결정하는 벡터 필드 정의의 새로운 부울입니다. 쿼리 응답에 벡터 콘텐츠가 필요하지 않은 경우 stored를 false로 설정하여 필드당 최대 50%의 스토리지를 절약할 수 있습니다.

벡터는 사람이 읽을 수 없으므로 일반적으로 검색 페이지에서 렌더링되는 쿼리 응답에서 생략됩니다. 그러나 벡터 콘텐츠를 사용하는 모델이나 프로세스에 쿼리 결과를 전달하는 등 다운스트림 처리에서 벡터를 사용하는 경우에는 stored를 true로 설정하고 벡터 크기를 최소화하기 위한 다른 기술을 선택해야 합니다.

다음 예에서는 검색 인덱스의 필드 컬렉션을 보여줍니다. 벡터 필드에 대해 검색 가능 스토리지를 영구적으로 제거하려면 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입니다. 기본 구성에서는 검색 가능 복사본이 저장되지만 결과에 자동으로 반환되지는 않습니다. stored가 true이면 인덱스를 다시 작성하지 않고도 언제든지 retrievable을 true 및 false로 전환할 수 있습니다. stored가 false인 경우 retrievable이 false여야 하며 변경할 수 없습니다.

옵션 3: 스칼라 양자화 구성

기본 제공 스칼라 양자화는 메모리 및 디스크 스토리지 요구 사항을 줄이고 순위 재지정 및 오버샘플링을 추가하여 더 작은 인덱스의 영향을 상쇄하므로 사용이 권장됩니다. 기본 제공 스칼라 양자화는 Float32 또는 Float16 데이터를 포함하는 벡터 필드에 적용할 수 있습니다.

기본 제공 벡터 압축을 사용하려면 다음을 수행합니다.

  • 검색 인덱스에 vectorSearch.compressions를 추가합니다. 이 미리 보기에서 지원되는 압축 알고리즘은 스칼라 양자화입니다.
  • 선택적 속성을 설정하여 손실 인덱싱의 영향을 완화합니다. rerankWithOriginalVectorsdefaultOversampling 둘 다 쿼리 실행 중에 최적화를 제공합니다.
  • 새 벡터 프로필에 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)
        }
      }  
   ]

주요 정보:

  • kindscalarQuantization로 설정해야 합니다. 현재 지원되는 유일한 양자화 메서드입니다.

  • rerankWithOriginalVectors는 원래의 압축되지 않은 벡터를 사용하여 유사성을 다시 계산하고 초기 검색 쿼리에서 반환된 상위 결과의 순위를 다시 지정합니다. 압축되지 않은 벡터는 stored가 false인 경우에도 검색 인덱스에 존재합니다. 이 속성은 선택 사항입니다. 기본값은 true입니다.

  • defaultOversampling은 양자화로 인한 정보 감소를 상쇄하기 위해 더 광범위한 잠재적 결과 집합을 고려합니다. 잠재적 결과에 대한 수식은 오버샘플링 승수와 함께 쿼리의 k로 구성됩니다. 예를 들어 쿼리에서 k를 5로 지정하고 오버샘플링이 20인 경우 쿼리는 해당 목적으로 압축되지 않은 원래 벡터를 사용하여 순위 재지정에 사용할 문서 100개를 효과적으로 요청합니다. 상위 k개의 순위 변경 결과만 반환됩니다. 이 속성은 선택 사항입니다. 기본값은 4입니다.

  • quantizedDataTypeint8로 설정해야 합니다. 현재 지원되는 유일한 기본 데이터 형식입니다. 이 속성은 선택 사항입니다. 기본값은 int8입니다.

벡터 프로필에 압축 설정 추가

스칼라 양자화는 벡터 프로필의 속성으로 지정됩니다. 메모리에 압축된 인덱스를 작성하려면 새 벡터 프로필을 만들어야 합니다.

프로필 내에서 HNSW(Hierarchical Navigable Small Worlds) 알고리즘을 사용해야 합니다. 기본 제공 양자화는 전체(Exhaustive) KNN에서 지원되지 않습니다.

  1. 새 벡터 프로필을 만들고 압축 속성을 추가합니다.

    "profiles": [
       {
          "name": "my-vector-profile",
          "compression": "my-scalar-quantization", 
          "algorithm": "my-hnsw-vector-config-1",
          "vectorizer": null
       }
     ]
    
  2. 벡터 필드에 벡터 프로필을 할당합니다. 스칼라 양자화는 콘텐츠를 Int8로 줄이므로 콘텐츠가 Float32 또는 Float16이어야 합니다.

    Azure AI 검색에서 Float32Float16 형식에 해당하는 EDM(엔터티 데이터 모델)은 각각 Collection(Edm.Single)Collection(Edm.Half)입니다.

    {
       "name": "DescriptionVector",
       "type": "Collection(Edm.Single)",
       "searchable": true,
       "retrievable": true,
       "dimensions": 1536,
       "vectorSearchProfile": "my-vector-profile"
    }
    
  3. 풀 모델 인덱싱에 인덱서를 사용하거나 푸시 모델 인덱싱에 API를 사용하여 인덱스를 로드합니다.

스칼라 양자화는 각 벡터 포함 내 각 숫자의 해상도를 줄입니다. 각 숫자를 32비트 부동 소수점 숫자로 표현하는 대신 8비트 정수를 사용합니다. 숫자 범위(일반적으로 99번째 백분위수 최소값 및 최대값)를 식별하고 유한한 수의 수준 또는 계급구간(bin)으로 나누어 각 계급구간에 식별자를 할당합니다. 8비트 스칼라 양자화에는 2^8, 즉 256개의 가능한 계급구간이 있습니다.

벡터의 각 구성 요소는 실수를 가장 가까운 정수로 반올림하는 것과 유사한 프로세스에서 이 양자화 수준 집합 내에서 가장 가까운 대표값에 매핑됩니다. 양자화된 8비트 벡터에서는 원래 값 대신 식별자 번호가 사용됩니다. 양자화 후 각 벡터는 해당 구성 요소가 속한 계급구간에 대한 식별자 배열로 표시됩니다. 이러한 양자화된 벡터는 원래 벡터에 비해 저장해야 하는 비트가 훨씬 적기 때문에 스토리지 요구 사항과 메모리 공간이 줄어듭니다.

vectorCompression, 데이터 형식, 저장된 속성이 있는 인덱스 예시

다음은 좁은 데이터 형식, 감소된 스토리지 및 벡터 압축을 지정하는 검색 인덱스의 복합 예입니다.

  • "HotelNameVector"는 원래 Float32 값을 검색 인덱스에서 Collection(Edm.Half)로 표시되는 Float16으로 다시 변환하는 좁은 데이터 형식의 예를 제공합니다.
  • "HotelNameVector"에도 stored가 false로 설정되어 있습니다. 쿼리 응답에 사용된 추가 포함은 저장되지 않습니다. stored가 거짓이면 retrievable도 거짓이어야 합니다.
  • "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인 경우 쿼리 요청에서 다르게 변경할 수 있습니다.

인덱스에 명시적인 rerankWithOriginalVectors 또는 defaultOversampling 정의가 없더라도 오버샘플링 매개 변수를 설정할 수 있습니다. 쿼리 시 oversampling을 제공하면 해당 쿼리에 대한 인덱스 설정이 재정의되고 유효한 rerankWithOriginalVectors가 true로 설정된 쿼리가 실행됩니다.

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 값을 재정의하거나 오버샘플링을 도입합니다.

참고 항목