Voyage AI 임베딩 모델은 유연한 차원과 양자화를 지원 벡터 기반 애플리케이션의 저장 및 검색 비용을 최적화하는 데 도움이 됩니다. 이 페이지에서는 이러한 기능을 사용하여 높은 검색 품질을 유지하면서 비용을 줄이는 방법에 대해 설명합니다.
Google Colab의대화형 튜토리얼을 통해 유연한 차원과 양자화에 대해 알아보세요.
개요
대규모 리포지토리에 대한 코드 검색과 같은 대규모 벡터 검색 애플리케이션으로 작업할 때는 저장 및 계산 비용이 상당할 수 있습니다. 이러한 비용은 다음 요인에 따라 선형적으로 확장하다 .
차원 포함: 각 벡터의 차원 수
정밀도: 벡터의 각 숫자를 인코딩하는 데 사용되는 비트 수
이러한 요소 중 하나 또는 둘 다를 줄이면 검색 품질에 큰 영향을 주지 않고 비용을 크게 낮출 수 있습니다. Voyage AI 모델은 이를 달성하기 위해 두 가지 보완 기술을 지원 .
마트료시카 임베딩: 더 적은 차원으로 잘라내어 더 작은 버전의 임베딩을 사용할 수 있습니다.
양자화:임베딩에 포함된 각 숫자의 정밀도를 32비트 부동소수점에서 정밀도가 낮은 형식으로 줄입니다.
이러한 기술은 차원이 축소되거나 양자화된 값을 사용해도 품질을 유지하도록 모델을 훈련하는 마트료시카 학습 및 양자화 인식 교육 통해 구현됩니다.
마트료시카 임베딩
마트료시카 임베딩은 단일 벡터 내에 중첩된 크기가 다른 유효한 임베딩을 여러 개 포함하는 특수한 유형의 벡터 임베딩입니다. 이를 통해 성능과 비용 요구 사항의 균형을 가장 잘 맞추는 차원을 유연하게 선택할 수 있습니다.
최신 Voyage 임베딩 모델은 마트료시카 임베딩을 생성하고 매개변수를 통해 직접 여러 출력 차원을 지원 output_dimension . 자세한 학습 은 모델 개요를 참조하세요.
마트료시카 임베딩의 작동 방식
마트료시카 학습을 사용하면 단일 임베딩에 다양한 길이의 중첩된 임베딩 패밀리가 포함됩니다. 예시 들어 2048차원의 보야지 임베딩에는 더 짧은 길이의 유효한 임베딩이 여러 개 포함되어 있습니다.
첫 번째 256 차원은 유효한 256차원 임베딩을 형성합니다.
첫 번째 512 차원은 유효한 512차원 임베딩을 형성합니다.
첫 번째 1024 차원은 유효한 1024차원 임베딩을 형성합니다.
모든 2048 차원이 완전 충실도 임베딩을 형성합니다.
길이가 짧은 버전은 전체 임베딩보다 검색 품질이 약간 낮지만 저장 과 계산 리소스가 덜 필요합니다.
마트료시카 임베딩을 잘라내는 방법
차원의 선행 하위 집합을 유지하여 마트료시카 임베딩을 자릅니다. 다음 예시 1024차원 벡터를 256 차원으로 자르는 방법을 보여 줍니다.
import voyageai import numpy as np def embd_normalize(v: np.ndarray) -> np.ndarray: # Normalize rows of a 2D array to unit vectors row_norms = np.linalg.norm(v, axis=1, keepdims=True) if np.any(row_norms == 0): raise ValueError("Cannot normalize rows with a norm of zero.") return v / row_norms vo = voyageai.Client() # Generate 1024-dimensional embeddings embd = vo.embed(['Sample text 1', 'Sample text 2'], model='voyage-4-large').embeddings # Truncate to 256 dimensions and normalize short_dim = 256 resized_embd = embd_normalize(np.array(embd)[:, :short_dim]).tolist()
양자화
양자화는 고정밀 부동 소수점 숫자를 정밀도가 낮은 형식으로 변환하여 임베딩의 정밀도를 줄입니다. 이 프로세스 강력한 검색 품질을 유지하면서 저장 및 계산 비용을 크게 줄일 수 있습니다.
최신 Voyage 임베딩 모델은 양자화 인식 교육 사용하여 교육되므로, 양자화하더라도 높은 검색 품질을 유지합니다. 자세한 학습 은 모델 개요를 참조하세요.
참고
MongoDB 포함하여 벡터 저장 및 검색을 지원 하는 많은 데이터베이스가 양자화된 임베딩도 지원 . MongoDB Vector Search의 양자화에 대해 자세히 학습 벡터 양자화를 참조하세요.
양자화 작동 방식
양자화는 표준 32비트 부동 소수점 형식보다 적은 수의 비트로 각 차원을 표현하여 임베딩의 정밀도를 줄입니다. 양자화된 임베딩은 차원당 4 바이트를 사용하는 대신 다음을 사용합니다.
비트8정수(차원당 바이트): 저장 만큼 줄입니다.1 4
바이너리(차원당1 비트): 저장 32x만큼 줄입니다.
이처럼 크기가 크게 감소했음에도 불구하고, 보이지(Voyage)와 같은 양자화 인식 학습 모델은 높은 검색 품질을 유지합니다. 지원되는 Voyage 모델을 사용하면 output_dtype 매개 변수를 사용하여 출력 데이터 유형 지정하여 양자화 활성화 .
데이터 유형 | 설명 |
|---|---|
| 반환된 각 임베딩은 32비트(4바이트) 단정밀도 부동 소수점 숫자 목록입니다. 이는 기본값 이며 가장 높은 정밀도와 검색 정확도를 제공합니다. |
| 반환된 각 임베딩은 각각 -128 ~ 127 및 0 ~ 255 범위의 8비트(1바이트) 정수 목록입니다. |
| 반환된 각 임베딩은 비트로 채워진 8양자화된 단일 비트 임베딩 값을 나타내는 비트 정수 |
예시
이진 양자화 이해
다음과 같은 임베딩 값을 고려하세요.
-0.0396, 0.0062, -0.0745, -0.0390, 0.0046, 0.0003, -0.0850, 0.0399 이진 양자화는 다음 규칙을 사용하여 각 값을 단일 비트로 변환합니다.
0보다 작은 값은0(으)로 변환됩니다.0보다 크거나 같은 값은1(으)로 변환됩니다.
0, 1, 0, 0, 1, 1, 0, 1 8비트는 하나의 8비트 정수로 압축됩니다:
01001101. 이 정수는 10진수로77로 변환됩니다.최종 출력 유형으로 변환하려면 다음 변환을 적용 .
출력 유형변환 방법결과ubinaryuint8: 값을 부호 없는 정수로 직접 사용합니다.77binaryint8: 를 빼서 오프셋 이진법을128적용합니다.-51(77 - 128과 동일)
오프셋 바이너리
오프셋 바이너리는 부호가 있는 정수를 바이너리 형식으로 표현하는 방법입니다. Voyage AI 출력 유형에 이 메서드를 사용하여 binary 비트 팩 바이너리 임베딩을 부호 있는 정수()로int8 인코딩합니다.
오프셋 바이너리 메서드는 오프셋 값을 더하거나 빼는 방식으로 작동합니다.
바이너리로 변환하는 경우:
128인코딩하기 전에 부호가 있는 정수에 를 추가합니다.바이너리에서 변환할 때:
128디코딩 후 정수에서 빼기
8비트 부호 있는 정수(-128 ~ 127 범위 )의 경우 오프셋은 항상 128입니다.
예시
부호 있는 정수를 이진수로
-32 을 8비트 이진수로 나타내려면 다음을 수행합니다.
오프셋(
128)을-32에 추가하면96가 됩니다.96를 바이너리로 변환합니다:01100000.
예시
이진법에서 부호 있는 정수로
8비트 이진수 01010101에서 부호가 있는 정수를 확인하려면 다음을 수행합니다.
정수로 직접 변환합니다:
85.85에서 오프셋(128)을 빼면-43가 됩니다.
Voyage AI 로 양자화를 사용하는 방법
부동 소수점 임베딩을 수동으로 바이너리 형식으로 변환하거나 바이너리 임베딩을 개별 비트로 다시 언팩할 수 있습니다. 다음 예제에서는 두 작업을 모두 보여줍니다.
import numpy as np import voyageai vo = voyageai.Client() # Generate float embeddings embd_float = vo.embed('Sample text 1', model='voyage-4-large', output_dimension=2048).embeddings[0] # Compute 512-dimensional bit-packed binary and ubinary embeddings from 2048-dimensional float embeddings embd_binary_calc = (np.packbits(np.array(embd_float) > 0, axis=0) - 128).astype(np.int8).tolist() # Quantize, binary offset embd_binary_512_calc = embd_binary_calc[0:64] # Truncate. Binary is 1/8 length of embedding dimension. embd_ubinary_calc = (np.packbits(np.array(embd_float) > 0, axis=0)).astype(np.uint8).tolist() # Quantize, binary offset embd_ubinary_512_calc = embd_ubinary_calc[0:64] # Truncate. Binary is 1/8 length of embedding dimension.
import numpy as np import voyageai vo = voyageai.Client() # Generate binary embeddings embd_binary = vo.embed('Sample text 1', model='voyage-4-large', output_dtype='binary', output_dimension=2048).embeddings[0] embd_ubinary = vo.embed('Sample text 1', model='voyage-4-large', output_dtype='ubinary', output_dimension=2048).embeddings[0] # Unpack bits embd_binary_bits = [format(x, f'08b') for x in np.array(embd_binary) + 128] # List of (bits) strings embd_binary_unpacked = [bit == '1' for bit in ''.join(embd_binary_bits)] # List of booleans embd_ubinary_bits = [format(x, f'08b') for x in np.array(embd_ubinary)] # List of (bits) strings embd_ubinary_unpacked = [bit == '1' for bit in ''.join(embd_ubinary_bits)] # List of booleans