양자화 (Quantization)
양자화 (Quantization)
양자화(Quantization)는 Qdrant가 가진 선택 기능 중 하나예요. 고차원 벡터를 더 효율적으로 저장하고 검색할 수 있게 해 주죠. 원본 벡터를 새로운 표현으로 변환해 데이터를 압축하는데, 벡터 사이의 상대적인 거리는 원본에 가깝게 그대로 보존합니다. 양자화 방법마다 동작 방식과 장단점이 달라서, 이번 절에서 하나씩 살펴볼게요.
양자화는 주로 고차원 벡터 공간에서 메모리 사용량을 줄이고 검색 속도를 높이는 데 쓰입니다. Qdrant 맥락에서는 검색 엔진을 특정 사용 사례에 맞게 최적화해서, 정확도·저장 효율·검색 속도 사이의 균형을 잡을 수 있게 해 주는 기술이에요.
물론 양자화에는 트레이드오프가 따라와요. 한쪽에서는 저장 공간을 크게 줄여주고 검색도 빨라집니다. 리소스 사용을 최소화하는 게 최우선인 대규모 애플리케이션에서 특히 유용하죠. 하지만 다른 한쪽에서는 근사 오차(approximation error)가 생겨서 검색 품질이 약간 떨어질 수 있어요. 그 균형이 어느 정도로 기울어지는지는 양자화 방법과 그 파라미터, 그리고 데이터의 특성에 따라 달라집니다.
Qdrant는 네 가지 양자화 방법을 지원해요.
- TurboQuant — 최대 32배 압축을 지원하고, 대부분의 임베딩 모델에서 높은 리콜을 보여줍니다.
- 스칼라 양자화(Scalar Quantization) — 각 벡터 컴포넌트를 32비트 float에서 8비트 정수로 압축해 4배 압축을 달성하고, 정확도 손실은 최소화합니다.
- 이진 양자화(Binary Quantization) — 각 벡터 컴포넌트를 1~2비트로 줄여 최대 32배 압축합니다. 고차원이고 분포가 중앙에 집중된 벡터에 가장 잘 맞아요.
- 제품 양자화(Product Quantization) — 메모리 최소화가 최우선일 때 최대 64배 압축을 가능하게 합니다.
어떤 양자화 방법을 쓸지 정하는 방법은 다음 절에서 이어서 설명할게요.
올바른 양자화 방법 고르기
리콜·압축·거리 메트릭 요구사항에 따라, 아래 표를 참고해서 선택하면 돼요.
| 압축률 | 방법 |
|---|---|
| 4 | 스칼라 양자화를 사용하세요. 리콜과 압축 사이에 좋은 균형을 가진 검증된 방법이에요. 다만 Manhattan(L1) 거리 메트릭을 써야 하는 경우가 아니라면, 스칼라 양자화 대신 4비트 TurboQuant를 고려해 보세요. 비슷한 리콜을 두 배의 압축률로 얻을 수 있어요. |
| 8 | 4비트 TurboQuant를 사용하세요. 리콜과 압축 사이에 좋은 균형을 제공합니다. Manhattan(L1) 거리 메트릭을 쓸 때는 다른 방법을 고려해 보세요. |
| 16 | 2비트 TurboQuant와 2비트 이진 양자화가 이 압축 수준에서 비슷한 결과를 보여줍니다. 이진 양자화가 더 빠르지만, TurboQuant가 더 나은 리콜을 제공해요. |
| 24 | 1.5비트 TurboQuant와 1.5비트 이진 양자화가 이 압축 수준에서 비슷한 결과를 보여줍니다. 이진 양자화가 더 빠르지만, TurboQuant가 더 나은 리콜을 제공해요. |
| 32 | 1비트 TurboQuant와 1비트 이진 양자화가 이 압축 수준에서 비슷한 결과를 보여줍니다. 이진 양자화가 더 빠르지만, TurboQuant가 더 나은 리콜을 제공해요. |
| 최대 64 | 메모리 사용량이 최우선이고 정확도나 속도가 중요하지 않다면 제품 양자화를 사용하세요. |
TurboQuant 양자화
v1.18.0부터 사용 가능
TurboQuant는 Google이 개발한 양자화 방법이에요. 압축하기 전에 벡터에 빠른 무작위 회전(random rotation)을 적용해서, 데이터를 좌표 전체에 고르게 재분배하는 방식으로 동작합니다. 그 덕분에 데이터셋 전체에 적용할 수 있는, 미리 계산된 전역 최적 양자화 매핑 하나를 쓸 수 있어요. 그래서 어떤 벡터 분포에서도 잘 동작하고, 이진 양자화가 가진 핵심 한계를 극복합니다.
Qdrant의 TurboQuant 구현은 원래 알고리즘을 확장해서, 알고리즘의 이론적 가정과 실제 임베딩 사이의 간극을 메웠어요.
TurboQuant는 자동으로 비대칭 양자화(asymmetric quantization)를 사용합니다. 저장된 벡터만 압축하고, 쿼리는 전체 정밀도(full precision)로 계산해요. 이렇게 하면 정확도가 좋아지고, 별도의 설정이 필요 없습니다.
인코딩 옵션
TurboQuant는 네 가지 비트 깊이를 지원합니다.
| 인코딩 | 비트 깊이 | 압축률 |
|---|---|---|
bits4 (기본값) |
4비트 | 8× |
bits2 |
2비트 | 16× |
bits1_5 |
1.5비트 | 24× |
bits1 |
1비트 | 32× |
저희 벤치마크에서, 4비트 TurboQuant는 스칼라 양자화의 두 배 압축률에서 비슷한 리콜과 속도를 보여줬어요. 결과는 데이터셋과 임베딩 모델에 따라 달라져서, 스칼라 양자화보다 더 좋을 수도 약간 못할 수도 있습니다. 그래서 4비트 TurboQuant가 많은 사용 사례에서 좋은 기본 선택이 됩니다.
이진 양자화와 비교하면, TurboQuant는 같은 저장 공간 예산에서 더 나은 리콜을 제공하고 속도는 더 느립니다.
기본 인코딩은 bits4이며, 가장 좋은 정확도를 제공해요.
거리 메트릭 지원
TurboQuant는 Cosine, Dot, Euclidean(L2) 거리를 SIMD 가속 스코어링으로 완전히 지원합니다.
Manhattan(L1) 거리도 지원하긴 하는데, 비교할 때마다 벡터 전체를 재구성해야 해서 다른 메트릭보다 훨씬 느려요. TurboQuant에서 최상의 성능을 원한다면 Cosine, Dot, Euclidean 거리를 사용하세요.
스칼라 양자화
v1.1.0부터 사용 가능
스칼라 양자화는 벡터 검색 엔진에서, 각 벡터 컴포넌트를 표현하는 데 쓰는 비트 수를 줄여 벡터를 압축하는 기법이에요.
예를 들어 Qdrant는 원본 벡터 컴포넌트를 32비트 부동소수점으로 표현해요. 스칼라 양자화를 쓰면 이 비트 수를 8로 줄일 수 있죠. 다시 말해, Qdrant가 각 벡터 컴포넌트에 대해 float32 -> uint8 변환을 수행합니다. 결과적으로 벡터 하나를 저장하는 데 필요한 메모리가 4분의 1로 줄어들어요.
메모리 사용량을 줄이는 것 외에도 스칼라 양자화는 검색 속도도 높여줍니다. Qdrant는 빠른 벡터 비교를 위해 특별한 SIMD CPU 명령어를 사용하는데, 이 명령어가 8비트 정수와 함께 동작해서 uint8로 변환하면 비교를 더 빠르게 수행할 수 있어요.
스칼라 양자화의 가장 큰 단점은 정확도 손실입니다. float32 -> uint8 변환에서 생기는 오차가 검색 품질을 약간 떨어뜨릴 수 있어요. 다만 이 오차는 보통 무시할 만하고, 고차원 벡터일수록 영향이 작은 편입니다. 저희 실험에서는 스칼라 양자화가 만드는 오차가 보통 1% 미만이었어요.
하지만 이 값은 데이터와 양자화 파라미터에 따라 달라집니다. 사용 사례에 맞게 양자화 파라미터를 최적화하는 방법은 Quantization Tips 절에서 더 자세히 다룰게요.
이진 양자화
v1.5.0부터 사용 가능
이진 양자화는 스칼라 양자화의 극단적인 경우예요. 각 벡터 컴포넌트를 단일 비트로 표현해서, 메모리 사용량을 32분의 1로 줄여줍니다. 몇 개의 CPU 명령어만으로 벡터 비교를 수행할 수 있기 때문에 가장 빠른 양자화 방법이에요. 원본 벡터와 비교했을 때 최대 40배까지 속도 향상을 얻을 수 있습니다.
다만 이진 양자화는 고차원 벡터에서만 효율적이고, 벡터 컴포넌트의 분포가 중앙에 집중되어 있어야 해요.
현재 이진 양자화는 다음 모델에서 좋은 정확도 결과를 보여줍니다.
- OpenAI
text-embedding-ada-002— 1536d, dbpedia 데이터셋으로 테스트했고 4배 오버샘플링에서 0.98 recall@100 달성 - Cohere AI
embed-english-v2.0— 4096d, Wikipedia 임베딩으로 테스트했고 2배 오버샘플링에서 0.98 recall@50 달성
차원이 낮거나 벡터 컴포넌트 분포가 다른 모델은 최적의 양자화 파라미터를 찾기 위해 추가 실험이 필요할 수 있어요.
이진 양자화는 리스코어링(rescoring)을 켠 상태에서만 사용할 것을 권장합니다. 이렇게 하면 검색 품질이 크게 좋아질 수 있어요. 다만 원본 벡터가 디스크에 저장되어 있다면 리스코어링이 검색 속도를 크게 떨어뜨릴 수 있다는 점을 기억하세요.
여기에 더해 오버샘플링(oversampling)을 사용하면 쿼리 시점에 검색 속도와 검색 품질 사이의 트레이드오프를 조절할 수 있습니다.
이진 양자화를 해밍 거리로 쓰기
이 방법이 주는 추가 이점은, dot product로 해밍 거리(Hamming distance)를 효율적으로 흉내 낼 수 있다는 점이에요.
구체적으로, 원본 벡터가 가능한 값으로 {-1, 1}만 가진다면, -1을 0으로, 1을 1로 바꾸기만 해도 두 벡터의 dot product가 해밍 거리와 같아집니다.
참고 진리표
| 벡터 1 | 벡터 2 | Dot product |
|---|---|---|
| 1 | 1 | 1 |
| 1 | -1 | -1 |
| -1 | 1 | -1 |
| -1 | -1 | 1 |
| 벡터 1 | 벡터 2 | 해밍 거리 |
|---|---|---|
| 1 | 1 | 0 |
| 1 | 0 | 1 |
| 0 | 1 | 1 |
| 0 | 0 | 0 |
보시다시피 두 함수는 상수 배수 기준으로 동일해서, 유사도 검색이 서로 동등해져요. 이진 양자화는 이런 표현을 이용해 벡터를 효율적으로 비교할 수 있게 해 줍니다.
1.5비트 및 2비트 양자화
v1.15.0부터 사용 가능
이진 양자화 저장소는 차원당 2비트와 1.5비트를 사용할 수 있어요. 작은 벡터에서 정밀도를 더 높여주죠. 1비트 압축은 천 차원보다 작은 벡터에서 상당한 데이터 손실과 정밀도 하락을 일으켰고, 값비싼 리스코어링이 필요한 경우가 많았어요. 2비트 양자화는 1비트의 32배 압축에 비해 16배 압축을 제공해서, 작은 벡터 차원에서 성능을 개선합니다. 1.5비트 양자화는 24배 압축에 중간 수준의 정확도를 제공해요.
이진 양자화의 큰 한계 중 하나는 0에 가까운 값을 잘 다루지 못한다는 점이에요. 2비트 양자화는 효율적인 스코어링 메커니즘으로 0을 명시적으로 표현해서 이 문제를 해결합니다. 1.5비트 양자화는 두 값 사이에서 0비트를 공유하는 방식이라, 2비트 BQ가 메모리를 너무 많이 쓸 때 이진 양자화의 효율성과 2비트 양자화의 정확도 향상을 균형 있게 가져갑니다.
2비트 표현을 만들기 위해 Qdrant는 값 분포를 계산한 다음, 비트 값을 3개의 버킷에 할당합니다.
-1- 000- 011- 11
1.5비트 양자화도 비슷하지만, 요소 쌍의 버킷을 이진 트리플릿(binary triplet)으로 합칩니다.

1.5비트와 2비트 양자화를 설정하는 방법은 다음 절에서 다룹니다.
비대칭 양자화
v1.15.0부터 사용 가능
비대칭 양자화(Asymmetric Quantization) 기법은 저장된 벡터와 쿼리에 서로 다른 벡터 인코딩 알고리즘을 쓸 수 있게 해 줍니다. 특히 흥미로운 조합은 이진으로 저장된 벡터와 스칼라 양자화된 쿼리예요.

이 방식은 이진 양자화와 비슷한 저장 크기와 RAM 사용량을 유지하면서 정밀도를 높여줍니다. 메모리가 제약된 배포 환경이나, 병목이 CPU가 아니라 디스크 I/O인 경우에 유용해요. 특히 수백만 개의 벡터를 인덱싱할 때 유용한데, 이런 시나리오의 한계는 CPU가 아니라 디스크 속도라서 정밀도를 크게 희생하지 않으면서도 개선할 수 있거든요. 같은 품질 출력에 필요한 리스코어링도 더 적어요.
비대칭 양자화를 설정하는 방법은 다음 절에서 다룹니다.
제품 양자화
v1.2.0부터 사용 가능
제품 양자화는 벡터를 청크로 나누고 각 세그먼트를 개별적으로 양자화해서 메모리 사용을 최소화하는 압축 방법이에요. 각 청크는 원본 벡터 컴포넌트를 대표하는 센트로이드(centroid) 인덱스로 근사됩니다. 센트로이드의 위치는 k-means 같은 클러스터링 알고리즘을 이용해 결정돼요. 현재 Qdrant는 256개의 센트로이드만 사용하므로, 각 센트로이드 인덱스를 1바이트로 표현할 수 있습니다.
제품 양자화는 스칼라 양자화보다 더 큰 압축률을 낼 수 있어요. 하지만 트레이드오프가 있고, 제품 양자화의 거리 계산은 SIMD 친화적이지 않아서 스칼라 양자화보다 느립니다. 또 정확도 손실도 있어서, 고차원 벡터에서만 쓰는 것을 권장해요.
사용 사례에 맞게 양자화 파라미터를 최적화하는 방법은 Quantization Tips 절에서 다룰게요.
Qdrant에서 양자화 설정하기
컬렉션 구성의 quantization_config 섹션에 양자화 파라미터를 지정하면, 컬렉션에 대해 양자화를 구성할 수 있어요.
양자화는 인덱싱 과정에서 모든 벡터에 자동으로 적용됩니다. 양자화된 벡터는 원본 벡터와 함께 컬렉션에 저장되므로, 필요하면 원본 벡터에도 계속 접근할 수 있어요.
v1.1.1부터 사용 가능
quantization_config는 named vector에서 지정하면 벡터별로도 설정할 수 있어요.
TurboQuant 설정하기
TurboQuant를 활성화하려면 컬렉션 구성의 quantization_config 섹션에 지정하면 됩니다.
기존 컬렉션에서 TurboQuant를 활성화할 때는 PATCH 요청이나 해당하는 update_collection 메서드를 사용하고, 벡터 구성이 이미 정의되어 있으므로 생략하세요.
PUT /collections/{collection_name}
{
"vectors": {
"size": 1536,
"distance": "Cosine"
},
"quantization_config": {
"turbo": {
"memory": "pinned"
}
}
}
from qdrant_client import QdrantClient, models
client.create_collection(
collection_name="{collection_name}",
vectors_config=models.VectorParams(size=1536, distance=models.Distance.COSINE),
quantization_config=models.TurboQuantization(
turbo=models.TurboQuantQuantizationConfig(memory=models.Memory.PINNED),
),
)
import { QdrantClient } from "@qdrant/js-client-rest";
const client = new QdrantClient({ host: "localhost", port: 6333 });
client.createCollection("{collection_name}", {
vectors: {
size: 1536,
distance: "Cosine",
},
quantization_config: {
turbo: {
memory: "pinned",
},
},
});
use qdrant_client::qdrant::{
CreateCollectionBuilder, Distance, Memory, TurboQuantizationBuilder, VectorParamsBuilder,
};
use qdrant_client::Qdrant;
client
.create_collection(
CreateCollectionBuilder::new("{collection_name}")
.vectors_config(VectorParamsBuilder::new(1536, Distance::Cosine))
.quantization_config(TurboQuantizationBuilder::new().memory(Memory::Pinned)),
)
.await?;
import io.qdrant.client.QdrantClient;
import io.qdrant.client.QdrantGrpcClient;
import io.qdrant.client.grpc.Collections.CreateCollection;
import io.qdrant.client.grpc.Collections.Distance;
import io.qdrant.client.grpc.Collections.Memory;
import io.qdrant.client.grpc.Collections.QuantizationConfig;
import io.qdrant.client.grpc.Collections.TurboQuantization;
import io.qdrant.client.grpc.Collections.VectorParams;
import io.qdrant.client.grpc.Collections.VectorsConfig;
client.createCollectionAsync(
CreateCollection.newBuilder()
.setCollectionName("{collection_name}")
.setVectorsConfig(
VectorsConfig.newBuilder()
.setParams(
VectorParams.newBuilder()
.setSize(1536)
.setDistance(Distance.Cosine)
.build()
)
.build()
)
.setQuantizationConfig(
QuantizationConfig.newBuilder()
.setTurboquant(
TurboQuantization.newBuilder()
.setMemory(Memory.Pinned)
.build()
)
.build()
)
.build()
).get();
using Qdrant.Client;
using Qdrant.Client.Grpc;
await client.CreateCollectionAsync(
collectionName: "{collection_name}",
vectorsConfig: new VectorParams
{
Size = 1536,
Distance = Distance.Cosine,
},
quantizationConfig: new QuantizationConfig
{
Turboquant = new TurboQuantization
{
Memory = Memory.Pinned,
},
}
);
import (
"context"
"github.com/qdrant/go-client/qdrant"
)
client.CreateCollection(
context.Background(),
&qdrant.CreateCollection{
CollectionName: "{collection_name}",
VectorsConfig: qdrant.NewVectorsConfig(
&qdrant.VectorParams{
Size: 1536,
Distance: qdrant.Distance_Cosine,
},
),
QuantizationConfig: qdrant.NewQuantizationTurbo(
&qdrant.TurboQuantization{
Memory: qdrant.Memory_Pinned.Enum(),
},
),
},
)
bits — 인코딩 비트 깊이입니다. 기본값은 bits4. 사용 가능한 값은 bits4, bits2, bits1_5, bits1이에요. 비트 깊이가 낮을수록 압축률은 높아지지만 정확도가 떨어집니다.
memory — 양자화된 벡터의 메모리 티어입니다. 기본값은 원본 벡터의 배치 위치에 따라 달라져요. 기본 티어를 참고하세요. pinned로 설정하면 양자화된 벡터를 항상 RAM에 유지합니다. 1.19보다 오래된 버전을 쓰고 있다면 Legacy 설정을 참고하세요.
비트 깊이 선택하기
특정 압축 수준을 쓰려면 bits 파라미터를 설정합니다.
PUT /collections/{collection_name}
{
"vectors": {
"size": 1536,
"distance": "Cosine"
},
"quantization_config": {
"turbo": {
"bits": "bits2",
"memory": "pinned"
}
}
}
from qdrant_client import QdrantClient, models
client.create_collection(
collection_name="{collection_name}",
vectors_config=models.VectorParams(size=1536, distance=models.Distance.COSINE),
quantization_config=models.TurboQuantization(
turbo=models.TurboQuantQuantizationConfig(
memory=models.Memory.PINNED,
bits=models.TurboQuantBitSize.BITS2,
),
),
)
import { QdrantClient } from "@qdrant/js-client-rest";
const client = new QdrantClient({ host: "localhost", port: 6333 });
client.createCollection("{collection_name}", {
vectors: {
size: 1536,
distance: "Cosine",
},
quantization_config: {
turbo: {
memory: "pinned",
bits: "bits2",
},
},
});
use qdrant_client::qdrant::{
CreateCollectionBuilder, Distance, Memory, TurboQuantBitSize, TurboQuantizationBuilder,
VectorParamsBuilder,
};
use qdrant_client::Qdrant;
client
.create_collection(
CreateCollectionBuilder::new("{collection_name}")
.vectors_config(VectorParamsBuilder::new(1536, Distance::Cosine))
.quantization_config(
TurboQuantizationBuilder::new()
.memory(Memory::Pinned)
.bits(TurboQuantBitSize::Bits2),
),
)
.await?;
import io.qdrant.client.QdrantClient;
import io.qdrant.client.QdrantGrpcClient;
import io.qdrant.client.grpc.Collections.CreateCollection;
import io.qdrant.client.grpc.Collections.Distance;
import io.qdrant.client.grpc.Collections.Memory;
import io.qdrant.client.grpc.Collections.QuantizationConfig;
import io.qdrant.client.grpc.Collections.TurboQuantBitSize;
import io.qdrant.client.grpc.Collections.TurboQuantization;
import io.qdrant.client.grpc.Collections.VectorParams;
import io.qdrant.client.grpc.Collections.VectorsConfig;
client.createCollectionAsync(
CreateCollection.newBuilder()
.setCollectionName("{collection_name}")
.setVectorsConfig(
VectorsConfig.newBuilder()
.setParams(
VectorParams.newBuilder()
.setSize(1536)
.setDistance(Distance.Cosine)
.build()
)
.build()
)
.setQuantizationConfig(
QuantizationConfig.newBuilder()
.setTurboquant(
TurboQuantization.newBuilder()
.setMemory(Memory.Pinned)
.setBits(TurboQuantBitSize.Bits2)
.build()
)
.build()
)
.build()
).get();
using Qdrant.Client;
using Qdrant.Client.Grpc;
await client.CreateCollectionAsync(
collectionName: "{collection_name}",
vectorsConfig: new VectorParams
{
Size = 1536,
Distance = Distance.Cosine,
},
quantizationConfig: new QuantizationConfig
{
Turboquant = new TurboQuantization
{
Memory = Memory.Pinned,
Bits = TurboQuantBitSize.Bits2,
},
}
);
import (
"context"
"github.com/qdrant/go-client/qdrant"
)
client.CreateCollection(
context.Background(),
&qdrant.CreateCollection{
CollectionName: "{collection_name}",
VectorsConfig: qdrant.NewVectorsConfig(
&qdrant.VectorParams{
Size: 1536,
Distance: qdrant.Distance_Cosine,
},
),
QuantizationConfig: qdrant.NewQuantizationTurbo(
&qdrant.TurboQuantization{
Memory: qdrant.Memory_Pinned.Enum(),
Bits: qdrant.TurboQuantBitSize_Bits2.Enum(),
},
),
},
)
스칼라 양자화 설정하기
스칼라 양자화를 활성화하려면 컬렉션 구성의 quantization_config 섹션에 양자화 파라미터를 지정하면 됩니다.
기존 컬렉션에서 스칼라 양자화를 활성화할 때는 PATCH 요청이나 해당하는 update_collection 메서드를 사용하고, 벡터 구성이 이미 정의되어 있으므로 생략하세요.
PUT /collections/{collection_name}
{
"vectors": {
"size": 768,
"distance": "Cosine"
},
"quantization_config": {
"scalar": {
"type": "int8",
"quantile": 0.99,
"memory": "pinned"
}
}
}
from qdrant_client import QdrantClient, models
client.create_collection(
collection_name="{collection_name}",
vectors_config=models.VectorParams(size=768, distance=models.Distance.COSINE),
quantization_config=models.ScalarQuantization(
scalar=models.ScalarQuantizationConfig(
type=models.ScalarType.INT8,
quantile=0.99,
memory=models.Memory.PINNED,
),
),
)
import { QdrantClient } from "@qdrant/js-client-rest";
const client = new QdrantClient({ host: "localhost", port: 6333 });
client.createCollection("{collection_name}", {
vectors: {
size: 768,
distance: "Cosine",
},
quantization_config: {
scalar: {
type: "int8",
quantile: 0.99,
memory: "pinned",
},
},
});
use qdrant_client::qdrant::{
CreateCollectionBuilder, Distance, Memory, QuantizationType, ScalarQuantizationBuilder,
VectorParamsBuilder,
};
use qdrant_client::Qdrant;
client
.create_collection(
CreateCollectionBuilder::new("{collection_name}")
.vectors_config(VectorParamsBuilder::new(768, Distance::Cosine))
.quantization_config(
ScalarQuantizationBuilder::default()
.r#type(QuantizationType::Int8.into())
.quantile(0.99)
.memory(Memory::Pinned),
),
)
.await?;
import io.qdrant.client.QdrantClient;
import io.qdrant.client.QdrantGrpcClient;
import io.qdrant.client.grpc.Collections.CreateCollection;
import io.qdrant.client.grpc.Collections.Distance;
import io.qdrant.client.grpc.Collections.Memory;
import io.qdrant.client.grpc.Collections.QuantizationConfig;
import io.qdrant.client.grpc.Collections.QuantizationType;
import io.qdrant.client.grpc.Collections.ScalarQuantization;
import io.qdrant.client.grpc.Collections.VectorParams;
import io.qdrant.client.grpc.Collections.VectorsConfig;
client.createCollectionAsync(
CreateCollection.newBuilder()
.setCollectionName("{collection_name}")
.setVectorsConfig(
VectorsConfig.newBuilder()
.setParams(
VectorParams.newBuilder()
.setSize(768)
.setDistance(Distance.Cosine)
.build()
)
.build()
)
.setQuantizationConfig(
QuantizationConfig.newBuilder()
.setScalar(
ScalarQuantization.newBuilder()
.setType(QuantizationType.Int8)
.setQuantile(0.99f)
.setMemory(Memory.Pinned)
.build()
)
.build()
)
.build()
).get();
using Qdrant.Client;
using Qdrant.Client.Grpc;
await client.CreateCollectionAsync(
collectionName: "{collection_name}",
vectorsConfig: new VectorParams
{
Size = 768,
Distance = Distance.Cosine,
},
quantizationConfig: new QuantizationConfig
{
Scalar = new ScalarQuantization
{
Type = QuantizationType.Int8,
Quantile = 0.99f,
Memory = Memory.Pinned,
},
}
);
import (
"context"
"github.com/qdrant/go-client/qdrant"
)
client.CreateCollection(
context.Background(),
&qdrant.CreateCollection{
CollectionName: "{collection_name}",
VectorsConfig: qdrant.NewVectorsConfig(
&qdrant.VectorParams{
Size: 768,
Distance: qdrant.Distance_Cosine,
},
),
QuantizationConfig: qdrant.NewQuantizationScalar(
&qdrant.ScalarQuantization{
Type: qdrant.QuantizationType_Int8,
Quantile: qdrant.PtrOf(float32(0.99)),
Memory: qdrant.Memory_Pinned.Enum(),
},
),
},
)
quantization_config 섹션에서 지정할 수 있는 파라미터는 3개예요.
type — 양자화된 벡터 컴포넌트의 타입입니다. 현재 Qdrant는 int8만 지원해요.
quantile — 양자화된 벡터 컴포넌트의 분위수(quantile)입니다. 양자화 경계를 계산하는 데 사용됩니다. 예를 들어 0.99로 지정하면 극단값의 1%가 양자화 경계에서 제외돼요.
벡터 컴포넌트에 이상치(outlier)가 있다면 1.0보다 낮은 quantile이 유용할 수 있어요. 이 파라미터는 결과 정밀도에만 영향을 주고 메모리 사용량에는 영향을 주지 않습니다. 검색 품질이 크게 떨어지는 걸 겪고 있다면 이 파라미터를 조정해 볼 만해요.
memory — 양자화된 벡터의 메모리 티어입니다. 기본값은 원본 벡터의 배치 위치에 따라 달라져요. 기본 티어를 참고하세요. 다만 일부 설정에서는 검색 속도를 높이기 위해 양자화된 벡터를 RAM에 유지하고 싶을 수 있어요. 1.19보다 오래된 버전을 쓰고 있다면 Legacy 설정을 참고하세요.
이런 경우 memory를 pinned로 설정하면 양자화된 벡터를 항상 RAM에 유지할 수 있어요.
이진 양자화 설정하기
이진 양자화를 활성화하려면 컬렉션 구성의 quantization_config 섹션에 양자화 파라미터를 지정하면 됩니다.
기존 컬렉션에서 이진 양자화를 활성화할 때는 PATCH 요청이나 해당하는 update_collection 메서드를 사용하고, 벡터 구성이 이미 정의되어 있으므로 생략하세요.
PUT /collections/{collection_name}
{
"vectors": {
"size": 1536,
"distance": "Cosine"
},
"quantization_config": {
"binary": {
"memory": "pinned"
}
}
}
from qdrant_client import QdrantClient, models
client.create_collection(
collection_name="{collection_name}",
vectors_config=models.VectorParams(size=1536, distance=models.Distance.COSINE),
quantization_config=models.BinaryQuantization(
binary=models.BinaryQuantizationConfig(
memory=models.Memory.PINNED,
),
),
)
import { QdrantClient } from "@qdrant/js-client-rest";
const client = new QdrantClient({ host: "localhost", port: 6333 });
client.createCollection("{collection_name}", {
vectors: {
size: 1536,
distance: "Cosine",
},
quantization_config: {
binary: {
memory: "pinned",
},
},
});
use qdrant_client::qdrant::{
BinaryQuantizationBuilder, CreateCollectionBuilder, Distance, Memory, VectorParamsBuilder,
};
use qdrant_client::Qdrant;
client
.create_collection(
CreateCollectionBuilder::new("{collection_name}")
.vectors_config(VectorParamsBuilder::new(1536, Distance::Cosine))
.quantization_config(BinaryQuantizationBuilder::default().memory(Memory::Pinned)),
)
.await?;
import io.qdrant.client.QdrantClient;
import io.qdrant.client.QdrantGrpcClient;
import io.qdrant.client.grpc.Collections.BinaryQuantization;
import io.qdrant.client.grpc.Collections.CreateCollection;
import io.qdrant.client.grpc.Collections.Distance;
import io.qdrant.client.grpc.Collections.Memory;
import io.qdrant.client.grpc.Collections.QuantizationConfig;
import io.qdrant.client.grpc.Collections.VectorParams;
import io.qdrant.client.grpc.Collections.VectorsConfig;
client.createCollectionAsync(
CreateCollection.newBuilder()
.setCollectionName("{collection_name}")
.setVectorsConfig(
VectorsConfig.newBuilder()
.setParams(
VectorParams.newBuilder()
.setSize(1536)
.setDistance(Distance.Cosine)
.build()
)
.build()
)
.setQuantizationConfig(
QuantizationConfig.newBuilder()
.setBinary(
BinaryQuantization.newBuilder()
.setMemory(Memory.Pinned)
.build()
)
.build()
)
.build()
).get();
using Qdrant.Client;
using Qdrant.Client.Grpc;
await client.CreateCollectionAsync(
collectionName: "{collection_name}",
vectorsConfig: new VectorParams
{
Size = 1536,
Distance = Distance.Cosine,
},
quantizationConfig: new QuantizationConfig
{
Binary = new BinaryQuantization
{
Memory = Memory.Pinned,
},
}
);
import (
"context"
"github.com/qdrant/go-client/qdrant"
)
client.CreateCollection(
context.Background(),
&qdrant.CreateCollection{
CollectionName: "{collection_name}",
VectorsConfig: qdrant.NewVectorsConfig(
&qdrant.VectorParams{
Size: 1536,
Distance: qdrant.Distance_Cosine,
},
),
QuantizationConfig: qdrant.NewQuantizationBinary(
&qdrant.BinaryQuantization{
Memory: qdrant.Memory_Pinned.Enum(),
},
),
},
)
memory — 양자화된 벡터의 메모리 티어입니다. 기본값은 원본 벡터의 배치 위치에 따라 달라져요. 기본 티어를 참고하세요. 다만 일부 설정에서는 검색 속도를 높이기 위해 양자화된 벡터를 RAM에 유지하고 싶을 수 있어요. 1.19보다 오래된 버전을 쓰고 있다면 Legacy 설정을 참고하세요.
이런 경우 memory를 pinned로 설정하면 양자화된 벡터를 항상 RAM에 유지할 수 있어요.
비트 깊이 설정하기
2비트나 1.5비트 양자화를 활성화하려면 컬렉션 구성의 quantization_config 섹션에 encoding 파라미터를 지정하면 됩니다. 사용 가능한 값은 two_bits와 one_and_half_bits예요.
PUT /collections/{collection_name}
{
"vectors": {
"size": 1536,
"distance": "Cosine"
},
"quantization_config": {
"binary": {
"encoding": "two_bits",
"memory": "pinned"
}
}
}
from qdrant_client import QdrantClient, models
client.create_collection(
collection_name="{collection_name}",
vectors_config=models.VectorParams(size=1536, distance=models.Distance.COSINE),
quantization_config=models.BinaryQuantization(
binary=models.BinaryQuantizationConfig(
encoding=models.BinaryQuantizationEncoding.TWO_BITS,
memory=models.Memory.PINNED,
),
),
)
import { QdrantClient } from "@qdrant/js-client-rest";
const client = new QdrantClient({ host: "localhost", port: 6333 });
client.createCollection("{collection_name}", {
vectors: {
size: 1536,
distance: "Cosine",
},
quantization_config: {
binary: {
encoding: "two_bits",
memory: "pinned",
},
},
});
use qdrant_client::qdrant::{
BinaryQuantizationBuilder, CreateCollectionBuilder, Distance, Memory, VectorParamsBuilder,
BinaryQuantizationEncoding,
};
use qdrant_client::Qdrant;
client
.create_collection(
CreateCollectionBuilder::new("{collection_name}")
.vectors_config(VectorParamsBuilder::new(1536, Distance::Cosine))
.quantization_config(
BinaryQuantizationBuilder::default()
.memory(Memory::Pinned)
.encoding(BinaryQuantizationEncoding::TwoBits),
),
)
.await?;
import io.qdrant.client.QdrantClient;
import io.qdrant.client.QdrantGrpcClient;
import io.qdrant.client.grpc.Collections.BinaryQuantization;
import io.qdrant.client.grpc.Collections.BinaryQuantizationEncoding;
import io.qdrant.client.grpc.Collections.CreateCollection;
import io.qdrant.client.grpc.Collections.Distance;
import io.qdrant.client.grpc.Collections.Memory;
import io.qdrant.client.grpc.Collections.QuantizationConfig;
import io.qdrant.client.grpc.Collections.VectorParams;
import io.qdrant.client.grpc.Collections.VectorsConfig;
client.createCollectionAsync(
CreateCollection.newBuilder()
.setCollectionName("{collection_name}")
.setVectorsConfig(
VectorsConfig.newBuilder()
.setParams(
VectorParams.newBuilder()
.setSize(1536)
.setDistance(Distance.Cosine)
.build()
)
.build()
)
.setQuantizationConfig(
QuantizationConfig.newBuilder()
.setBinary(
BinaryQuantization.newBuilder()
.setEncoding(BinaryQuantizationEncoding.TwoBits)
.setMemory(Memory.Pinned)
.build()
)
.build()
)
.build()
).get();
using Qdrant.Client;
using Qdrant.Client.Grpc;
await client.CreateCollectionAsync(
collectionName: "{collection_name}",
vectorsConfig: new VectorParams
{
Size = 1536,
Distance = Distance.Cosine,
},
quantizationConfig: new QuantizationConfig
{
Binary = new BinaryQuantization
{
Encoding = BinaryQuantizationEncoding.TwoBits,
Memory = Memory.Pinned,
},
}
);
import (
"context"
"github.com/qdrant/go-client/qdrant"
)
client.CreateCollection(
context.Background(),
&qdrant.CreateCollection{
CollectionName: "{collection_name}",
VectorsConfig: qdrant.NewVectorsConfig(
&qdrant.VectorParams{
Size: 1536,
Distance: qdrant.Distance_Cosine,
},
),
QuantizationConfig: qdrant.NewQuantizationBinary(
&qdrant.BinaryQuantization{
Encoding: qdrant.BinaryQuantizationEncoding_TwoBits.Enum(),
Memory: qdrant.Memory_Pinned.Enum(),
},
),
},
)
비대칭 양자화 설정하기
비대칭 양자화를 활성화하려면 컬렉션 구성의 quantization_config 섹션에 query_encoding 파라미터를 지정하면 됩니다. 사용 가능한 값은 다음과 같아요.
default,binary— 쿼리에 일반 이진 양자화를 사용합니다.scalar8bits— 쿼리에 8비트 양자화를 사용합니다.scalar4bits— 쿼리에 4비트 양자화를 사용합니다.
PUT /collections/{collection_name}
{
"vectors": {
"size": 1536,
"distance": "Cosine"
},
"quantization_config": {
"binary": {
"query_encoding": "scalar8bits",
"memory": "pinned"
}
}
}
from qdrant_client import QdrantClient, models
client.create_collection(
collection_name="{collection_name}",
vectors_config=models.VectorParams(size=1536, distance=models.Distance.COSINE),
quantization_config=models.BinaryQuantization(
binary=models.BinaryQuantizationConfig(
query_encoding=models.BinaryQuantizationQueryEncoding.SCALAR8BITS,
memory=models.Memory.PINNED,
),
),
)
import { QdrantClient } from "@qdrant/js-client-rest";
const client = new QdrantClient({ host: "localhost", port: 6333 });
client.createCollection("{collection_name}", {
vectors: {
size: 1536,
distance: "Cosine",
},
quantization_config: {
binary: {
query_encoding: "scalar8bits",
memory: "pinned",
},
},
});
use qdrant_client::qdrant::{
BinaryQuantizationBuilder, CreateCollectionBuilder, Distance, Memory, VectorParamsBuilder,
BinaryQuantizationQueryEncoding,
};
use qdrant_client::Qdrant;
client
.create_collection(
CreateCollectionBuilder::new("{collection_name}")
.vectors_config(VectorParamsBuilder::new(1536, Distance::Cosine))
.quantization_config(
BinaryQuantizationBuilder::default()
.memory(Memory::Pinned)
.query_encoding(BinaryQuantizationQueryEncoding::scalar8bits()),
),
)
.await?;
import io.qdrant.client.QdrantClient;
import io.qdrant.client.QdrantGrpcClient;
import io.qdrant.client.grpc.Collections.BinaryQuantization;
import io.qdrant.client.grpc.Collections.BinaryQuantizationQueryEncoding;
import io.qdrant.client.grpc.Collections.CreateCollection;
import io.qdrant.client.grpc.Collections.Distance;
import io.qdrant.client.grpc.Collections.Memory;
import io.qdrant.client.grpc.Collections.QuantizationConfig;
import io.qdrant.client.grpc.Collections.VectorParams;
import io.qdrant.client.grpc.Collections.VectorsConfig;
client.createCollectionAsync(
CreateCollection.newBuilder()
.setCollectionName("{collection_name}")
.setVectorsConfig(
VectorsConfig.newBuilder()
.setParams(
VectorParams.newBuilder()
.setSize(1536)
.setDistance(Distance.Cosine)
.build()
)
.build()
)
.setQuantizationConfig(
QuantizationConfig.newBuilder()
.setBinary(
BinaryQuantization.newBuilder()
.setQueryEncoding(
BinaryQuantizationQueryEncoding.newBuilder()
.setSetting(BinaryQuantizationQueryEncoding.Setting.Scalar8Bits)
.build()
)
.setMemory(Memory.Pinned)
.build()
)
.build()
)
.build()
).get();
using Qdrant.Client;
using Qdrant.Client.Grpc;
await client.CreateCollectionAsync(
collectionName: "{collection_name}",
vectorsConfig: new VectorParams
{
Size = 1536,
Distance = Distance.Cosine,
},
quantizationConfig: new QuantizationConfig
{
Binary = new BinaryQuantization
{
QueryEncoding = new BinaryQuantizationQueryEncoding
{
Setting = BinaryQuantizationQueryEncoding.Types.Setting.Scalar8Bits,
},
Memory = Memory.Pinned,
},
}
);
import (
"context"
"github.com/qdrant/go-client/qdrant"
)
client.CreateCollection(
context.Background(),
&qdrant.CreateCollection{
CollectionName: "{collection_name}",
VectorsConfig: qdrant.NewVectorsConfig(
&qdrant.VectorParams{
Size: 1536,
Distance: qdrant.Distance_Cosine,
},
),
QuantizationConfig: qdrant.NewQuantizationBinary(
&qdrant.BinaryQuantization{
QueryEncoding: qdrant.NewBinaryQuantizationQueryEncodingSetting(
qdrant.BinaryQuantizationQueryEncoding_Scalar8Bits,
),
Memory: qdrant.Memory_Pinned.Enum(),
},
),
},
)
제품 양자화 설정하기
제품 양자화를 활성화하려면 컬렉션 구성의 quantization_config 섹션에 양자화 파라미터를 지정하면 됩니다.
기존 컬렉션에서 제품 양자화를 활성화할 때는 PATCH 요청이나 해당하는 update_collection 메서드를 사용하고, 벡터 구성이 이미 정의되어 있으므로 생략하세요.
PUT /collections/{collection_name}
{
"vectors": {
"size": 768,
"distance": "Cosine"
},
"quantization_config": {
"product": {
"compression": "x16",
"memory": "pinned"
}
}
}
from qdrant_client import QdrantClient, models
client.create_collection(
collection_name="{collection_name}",
vectors_config=models.VectorParams(size=768, distance=models.Distance.COSINE),
quantization_config=models.ProductQuantization(
product=models.ProductQuantizationConfig(
compression=models.CompressionRatio.X16,
memory=models.Memory.PINNED,
),
),
)
import { QdrantClient } from "@qdrant/js-client-rest";
const client = new QdrantClient({ host: "localhost", port: 6333 });
client.createCollection("{collection_name}", {
vectors: {
size: 768,
distance: "Cosine",
},
quantization_config: {
product: {
compression: "x16",
memory: "pinned",
},
},
});
use qdrant_client::qdrant::{
CompressionRatio, CreateCollectionBuilder, Distance, Memory, ProductQuantizationBuilder,
VectorParamsBuilder,
};
use qdrant_client::Qdrant;
client
.create_collection(
CreateCollectionBuilder::new("{collection_name}")
.vectors_config(VectorParamsBuilder::new(768, Distance::Cosine))
.quantization_config(
ProductQuantizationBuilder::new(CompressionRatio::X16.into())
.memory(Memory::Pinned),
),
)
.await?;
import io.qdrant.client.QdrantClient;
import io.qdrant.client.QdrantGrpcClient;
import io.qdrant.client.grpc.Collections.CompressionRatio;
import io.qdrant.client.grpc.Collections.CreateCollection;
import io.qdrant.client.grpc.Collections.Distance;
import io.qdrant.client.grpc.Collections.Memory;
import io.qdrant.client.grpc.Collections.ProductQuantization;
import io.qdrant.client.grpc.Collections.QuantizationConfig;
import io.qdrant.client.grpc.Collections.VectorParams;
import io.qdrant.client.grpc.Collections.VectorsConfig;
client.createCollectionAsync(
CreateCollection.newBuilder()
.setCollectionName("{collection_name}")
.setVectorsConfig(
VectorsConfig.newBuilder()
.setParams(
VectorParams.newBuilder()
.setSize(768)
.setDistance(Distance.Cosine)
.build()
)
.build()
)
.setQuantizationConfig(
QuantizationConfig.newBuilder()
.setProduct(
ProductQuantization.newBuilder()
.setCompression(CompressionRatio.x16)
.setMemory(Memory.Pinned)
.build()
)
.build()
)
.build()
).get();
using Qdrant.Client;
using Qdrant.Client.Grpc;
await client.CreateCollectionAsync(
collectionName: "{collection_name}",
vectorsConfig: new VectorParams
{
Size = 768,
Distance = Distance.Cosine,
},
quantizationConfig: new QuantizationConfig
{
Product = new ProductQuantization
{
Compression = CompressionRatio.X16,
Memory = Memory.Pinned,
},
}
);
import (
"context"
"github.com/qdrant/go-client/qdrant"
)
client.CreateCollection(
context.Background(),
&qdrant.CreateCollection{
CollectionName: "{collection_name}",
VectorsConfig: qdrant.NewVectorsConfig(
&qdrant.VectorParams{
Size: 768,
Distance: qdrant.Distance_Cosine,
},
),
QuantizationConfig: qdrant.NewQuantizationProduct(
&qdrant.ProductQuantization{
Compression: qdrant.CompressionRatio_x16,
Memory: qdrant.Memory_Pinned.Enum(),
},
),
},
)
quantization_config 섹션에서 지정할 수 있는 파라미터는 두 개예요.
compression — 압축률입니다. 압축률은 양자화된 벡터의 크기(바이트)를 원본 벡터의 크기(바이트)로 나눈 값이에요. 예를 들어 x16이면 양자화된 벡터가 원본보다 16배 작아집니다.
memory — 양자화된 벡터의 메모리 티어입니다. 기본값은 원본 벡터의 배치 위치에 따라 달라져요. 기본 티어를 참고하세요. 다만 일부 설정에서는 검색 속도를 높이기 위해 양자화된 벡터를 RAM에 유지하고 싶을 수 있어요. 그럴 땐 memory를 pinned로 설정하면 됩니다. 1.19보다 오래된 버전을 쓰고 있다면 Legacy 설정을 참고하세요.
양자화 비활성화하기
기존 컬렉션에서 양자화를 비활성화하려면 다음과 같이 하면 됩니다.
PATCH /collections/{collection_name}
{
"quantization_config": "Disabled"
}
curl -X PATCH http://localhost:6333/collections/{collection_name} \
-H 'Content-Type: application/json' \
--data-raw '{
"quantization_config": "Disabled"
}'
client.update_collection(
collection_name="{collection_name}",
quantization_config=models.Disabled.DISABLED,
)
client.updateCollection("{collection_name}", {
quantization_config: 'Disabled',
});
use qdrant_client::qdrant::{Disabled, UpdateCollectionBuilder};
client
.update_collection(
UpdateCollectionBuilder::new("{collection_name}").quantization_config(Disabled{}),
)
.await?;
import io.qdrant.client.grpc.Collections.Disabled;
import io.qdrant.client.grpc.Collections.QuantizationConfigDiff;
import io.qdrant.client.grpc.Collections.UpdateCollection;
client.updateCollectionAsync(
UpdateCollection.newBuilder()
.setCollectionName("{collection_name}")
.setQuantizationConfig(
QuantizationConfigDiff.newBuilder()
.setDisabled(Disabled.getDefaultInstance())
.build()
)
.build()
);
using Qdrant.Client;
using Qdrant.Client.Grpc;
var client = new QdrantClient("localhost", 6334);
await client.UpdateCollectionAsync(
collectionName: "{collection_name}",
quantizationConfig: new QuantizationConfigDiff
{
Disabled = new Disabled(),
}
);
import (
"context"
"github.com/qdrant/go-client/qdrant"
)
client, err := qdrant.NewClient(&qdrant.Config{
Host: "localhost",
Port: 6334,
})
client.UpdateCollection(
context.Background(),
&qdrant.UpdateCollection{
CollectionName: "{collection_name}",
QuantizationConfig: qdrant.NewQuantizationDiffDisabled(),
},
)
양자화로 검색하기
컬렉션에 양자화를 구성하면 검색에 양자화를 쓰기 위해 추가로 할 일은 없어요. Qdrant는 양자화된 벡터가 있으면 자동으로 사용합니다.
다만 검색 과정을 제어할 수 있는 몇 가지 옵션이 있어요.
POST /collections/{collection_name}/points/query
{
"query": [0.2, 0.1, 0.9, 0.7],
"params": {
"quantization": {
"ignore": false,
"rescore": true,
"oversampling": 2.0
}
},
"limit": 10
}
from qdrant_client import QdrantClient, models
client = QdrantClient(url="http://localhost:6333")
client.query_points(
collection_name="{collection_name}",
query=[0.2, 0.1, 0.9, 0.7],
search_params=models.SearchParams(
quantization=models.QuantizationSearchParams(
ignore=False,
rescore=True,
oversampling=2.0,
)
),
)
import { QdrantClient } from "@qdrant/js-client-rest";
const client = new QdrantClient({ host: "localhost", port: 6333 });
client.query("{collection_name}", {
query: [0.2, 0.1, 0.9, 0.7],
params: {
quantization: {
ignore: false,
rescore: true,
oversampling: 2.0,
},
},
limit: 10,
});
use qdrant_client::qdrant::{
QuantizationSearchParamsBuilder, QueryPointsBuilder, SearchParamsBuilder,
};
use qdrant_client::Qdrant;
let client = Qdrant::from_url("http://localhost:6334").build()?;
client
.query(
QueryPointsBuilder::new("{collection_name}")
.query(vec![0.2, 0.1, 0.9, 0.7])
.limit(10)
.params(
SearchParamsBuilder::default()
.quantization(
QuantizationSearchParamsBuilder::default()
.ignore(false)
.rescore(true)
.oversampling(2.0),
),
),
)
.await?;
import static io.qdrant.client.QueryFactory.nearest;
import io.qdrant.client.QdrantClient;
import io.qdrant.client.QdrantGrpcClient;
import io.qdrant.client.grpc.Points.QuantizationSearchParams;
import io.qdrant.client.grpc.Points.QueryPoints;
import io.qdrant.client.grpc.Points.SearchParams;
QdrantClient client = new QdrantClient(
QdrantGrpcClient.newBuilder("localhost", 6334, false).build()
);
client
.queryAsync(
QueryPoints.newBuilder()
.setCollectionName("{collection_name}")
.setQuery(nearest(0.2f, 0.1f, 0.9f, 0.7f))
.setParams(
SearchParams.newBuilder()
.setQuantization(
QuantizationSearchParams.newBuilder()
.setIgnore(false)
.setRescore(true)
.setOversampling(2.0)
.build()
)
.build()
)
.setLimit(10)
.build()
)
.get();
using Qdrant.Client;
using Qdrant.Client.Grpc;
var client = new QdrantClient("localhost", 6334);
await client.QueryAsync(
collectionName: "{collection_name}",
query: new float[] { 0.2f, 0.1f, 0.9f, 0.7f },
searchParams: new SearchParams
{
Quantization = new QuantizationSearchParams
{
Ignore = false,
Rescore = true,
Oversampling = 2.0,
},
},
limit: 10
);
import (
"context"
"github.com/qdrant/go-client/qdrant"
)
client, err := qdrant.NewClient(&qdrant.Config{
Host: "localhost",
Port: 6334,
})
client.Query(
context.Background(),
&qdrant.QueryPoints{
CollectionName: "{collection_name}",
Query: qdrant.NewQuery(0.2, 0.1, 0.9, 0.7),
Params: &qdrant.SearchParams{
Quantization: &qdrant.QuantizationSearchParams{
Ignore: qdrant.PtrOf(false),
Rescore: qdrant.PtrOf(true),
Oversampling: qdrant.PtrOf(2.0),
},
},
},
)
ignore — 검색 과정에서 양자화된 벡터를 무시할지 여부를 정합니다. 기본적으로 Qdrant는 양자화된 벡터가 있으면 사용해요.
rescore — Qdrant가 원본 벡터를 사용해 top-k 검색 결과를 재평가할 수 있습니다. 이렇게 하면 검색 품질이 좋아질 수 있지만, 특히 원본 벡터가 디스크에 저장된 경우 검색 속도가 느려질 수 있어요. 그런 경우에는 리스코어링을 비활성화하는 것을 권장합니다. 기본적으로 리스코어링은 이진 양자화, TurboQuant 1 Bit, TurboQuant 1.5 Bit, TurboQuant 2 Bit의 네 가지 양자화 방법에서만 활성화됩니다. 나머지 양자화 방법은 기본적으로 리스코어링을 하지 않아요.
v1.3.0부터 사용 가능
oversampling — 양자화된 인덱스로 얼마나 많은 추가 벡터를 사전 선택한 다음 원본 벡터로 재점수(re-score)할지를 정의합니다. 예를 들어 oversampling이 2.4이고 limit이 100이면, 양자화된 인덱스로 240개 벡터를 사전 선택하고, 재점수 후 상위 100개를 반환해요. 오버샘플링은 쿼리 시점에 검색 속도와 검색 품질 사이의 트레이드오프를 조절하고 싶을 때 유용합니다.
양자화 팁
정확도 튜닝
이 절에서는 검색 정밀도를 튜닝하는 방법을 다룰게요. 양자화가 검색 품질에 미치는 영향을 가장 빨리 이해하는 방법은, 양자화를 켠 결과와 끈 결과를 비교하는 거예요.
양자화를 비활성화하려면 검색 요청에서 ignore를 true로 설정하면 됩니다.
POST /collections/{collection_name}/points/query
{
"query": [0.2, 0.1, 0.9, 0.7],
"params": {
"quantization": {
"ignore": true
}
},
"limit": 10
}
from qdrant_client import QdrantClient, models
client = QdrantClient(url="http://localhost:6333")
client.query_points(
collection_name="{collection_name}",
query=[0.2, 0.1, 0.9, 0.7],
search_params=models.SearchParams(
quantization=models.QuantizationSearchParams(
ignore=True,
)
),
)
import { QdrantClient } from "@qdrant/js-client-rest";
const client = new QdrantClient({ host: "localhost", port: 6333 });
client.query("{collection_name}", {
query: [0.2, 0.1, 0.9, 0.7],
params: {
quantization: {
ignore: true,
},
},
});
use qdrant_client::qdrant::{
QuantizationSearchParamsBuilder, QueryPointsBuilder, SearchParamsBuilder,
};
use qdrant_client::Qdrant;
let client = Qdrant::from_url("http://localhost:6334").build()?;
client
.query(
QueryPointsBuilder::new("{collection_name}")
.query(vec![0.2, 0.1, 0.9, 0.7])
.limit(3)
.params(
SearchParamsBuilder::default()
.quantization(
QuantizationSearchParamsBuilder::default().ignore(true),
),
),
)
.await?;