색인 만들기 및 벡터 쿼리

이 페이지에서는 저장된 임베딩을 사용하여 색인을 생성하고 PostgreSQL용 AlloyDB에서 ScaNN, IVF, IVFFlat, HNSW 색인을 사용하여 임베딩을 쿼리하는 방법을 설명합니다. 임베딩 저장에 관한 자세한 내용은 벡터 임베딩 저장을 참고하세요.

시작하기 전에

색인을 만들기 전에 다음 기본 요건을 완료해야 합니다.

  • AlloyDB 데이터베이스의 임베딩 벡터가 테이블에 추가됩니다.

  • AlloyDB용으로 Google에서 확장한 pgvector를 기반으로 하며 vector 확장 프로그램 버전 0.5.0 이상이 설치됩니다.

    CREATE EXTENSION IF NOT EXISTS vector;
    
  • ScaNN 색인을 생성하려면 vector 확장 프로그램 외에도 alloydb_scann 확장 프로그램을 설치합니다.

    CREATE EXTENSION IF NOT EXISTS alloydb_scann;
    

색인 만들기

데이터베이스의 테이블에 다음 색인 유형 중 하나를 만들 수 있습니다.

ScaNN 색인 만들기

AlloyDB alloydb_scann: Google에서 개발한 PostgreSQL 확장 프로그램으로, ScaNN 알고리즘을 기반으로 하는 매우 효율적인 최근접 이웃 색인을 구현합니다.

ScaNN 색인은 근사 최근접 이웃 검색을 위한 트리 기반 양자화 색인입니다. HNSW에 비해 색인 빌드 시간이 짧고 메모리 사용량이 적습니다. 또한 워크로드에 따라 HNSW보다 빠른 QPS를 제공합니다.

2단계 트리 ScaNN 색인

저장된 벡터 임베딩이 포함된 열에 ScaNN 알고리즘을 사용하여 2단계 트리 색인을 적용하려면 다음 DDL 쿼리를 실행합니다.

CREATE INDEX INDEX_NAME ON TABLE
  USING scann (EMBEDDING_COLUMN DISTANCE_FUNCTION)
  WITH (num_leaves=NUM_LEAVES_VALUE);

다음을 바꿉니다.

  • INDEX_NAME: 만들려는 색인의 이름입니다(예: my-scann-index). 색인 이름은 데이터베이스 전체에서 공유됩니다. 각 색인 이름이 데이터베이스의 각 테이블에 고유해야 합니다.

  • TABLE: 색인을 추가할 테이블입니다.

  • EMBEDDING_COLUMN: vector 데이터를 저장하는 열입니다.

  • DISTANCE_FUNCTION: 이 색인과 함께 사용할 거리 함수입니다. 다음 중 하나를 선택합니다.

    • L2 거리: l2

    • 내적: dot_product

    • 코사인 거리: cosine

  • NUM_LEAVES_VALUE: 이 색인에 적용할 파티션 수입니다. 1~1048576 사이의 값으로 설정합니다. 이 값을 결정하는 방법에 관한 자세한 내용은 ScaNN 색인 조정을 참고하세요.

3단계 트리 ScaNN 색인

저장된 벡터 임베딩이 포함된 열에 ScaNN 알고리즘을 사용하여 3단계 트리 색인을 만들려면 다음 DDL 쿼리를 실행합니다.

CREATE INDEX INDEX_NAME ON TABLE
  USING scann (EMBEDDING_COLUMN DISTANCE_FUNCTION)
  WITH (num_leaves=NUM_LEAVES_VALUE, max_num_levels = MAX_NUM_LEVELS);

다음을 바꿉니다.

  • MAX_NUM_LEVELS: K-means 클러스터링 트리의 최대 수준 수입니다. 2단계 트리 기반 정규화의 경우 1(기본값)로, 3단계 트리 기반 정규화의 경우 2로 설정합니다.

색인을 만든 후 지정된 텍스트로 최근접 이웃 쿼리 작성의 안내에 따라 색인을 활용하는 최근접 이웃 검색 쿼리를 실행할 수 있습니다.

색인 매개변수는 QPS와 검색 결과 사이의 적절한 균형을 맞추도록 설정해야 합니다. ScaNN 색인 튜닝에 관한 자세한 내용은 ScaNN 색인 튜닝을 참고하세요.

vector 대신 real[] 데이터 유형을 사용하는 임베딩 열에 이 색인을 만들려면 열을 vector 데이터 유형으로 변환합니다.

CREATE INDEX INDEX_NAME ON TABLE
  USING scann (CAST(EMBEDDING_COLUMN AS vector(DIMENSIONS)) DISTANCE_FUNCTION)
  WITH (num_leaves=NUM_LEAVES_VALUE, max_num_levels = MAX_NUM_LEVELS);

DIMENSIONS를 임베딩 열의 차원 너비로 바꿉니다. 크기를 찾는 방법에 관한 자세한 내용은 벡터 함수vector_dims 함수를 참고하세요.

색인 생성 진행 상황을 보려면 pg_stat_progress_create_index 뷰를 사용하세요.

SELECT * FROM pg_stat_progress_create_index;

phase 열에는 색인 생성의 현재 상태가 표시되며 색인이 생성된 후에는 building index: tree training 단계가 사라집니다.

타겟 검색 결과 및 QPS 균형을 위해 색인을 조정하려면 ScaNN 색인 조정을 참고하세요.

쿼리 실행

데이터베이스에 임베딩을 저장하고 색인을 생성한 후 pgvector 쿼리 기능을 사용하여 쿼리를 시작할 수 있습니다. alloydb_scann 확장 프로그램을 사용하여 일괄 검색 쿼리를 실행할 수 없습니다.

임베딩 벡터의 가장 가까운 의미론적 이웃을 찾으려면 다음 쿼리 예시를 실행하면 됩니다. 여기서 색인 생성 중에 사용한 것과 동일한 거리 함수를 설정합니다.

  SELECT * FROM TABLE
    ORDER BY EMBEDDING_COLUMN DISTANCE_FUNCTION_QUERY ['EMBEDDING']
    LIMIT ROW_COUNT

다음을 바꿉니다.

  • TABLE: 텍스트를 비교할 임베딩이 포함된 테이블입니다.

  • INDEX_NAME: 사용할 색인의 이름입니다(예: my-scann-index).

  • EMBEDDING_COLUMN: 저장된 임베딩이 포함된 열입니다.

  • DISTANCE_FUNCTION_QUERY: 이 쿼리와 함께 사용할 거리 함수입니다. 색인을 만들 때 사용된 거리 함수에 따라 다음 중 하나를 선택합니다.

    • L2 거리: <->

    • 내적: <#>

    • 코사인 거리: <=>

  • EMBEDDING: 저장된 의미론적 이웃 중 가장 가까운 이웃을 찾으려는 임베딩 벡터입니다.

  • ROW_COUNT: 반환할 행의 개수입니다.

    가장 일치하는 값을 하나만 원하는 경우 1을 지정합니다.

다른 쿼리 예시를 보려면 쿼리를 참고하세요.

embedding() 함수를 사용하여 텍스트를 벡터로 변환할 수도 있습니다. 벡터를 L2 거리의 pgvector 최근접 이웃 연산자 <-> 중 하나에 적용하여 의미상 가장 유사한 임베딩이 있는 데이터베이스 행을 찾습니다.

embedding()에서 real 배열을 반환하므로 pgvector 연산자와 함께 이러한 값을 사용하려면 embedding() 호출을 vector으로 명시적으로 변환해야 합니다.

  CREATE EXTENSION IF NOT EXISTS google_ml_integration VERSION '1.2';
  CREATE EXTENSION IF NOT EXISTS vector;

  SELECT * FROM TABLE
    ORDER BY EMBEDDING_COLUMN::vector
    <-> embedding('MODEL_IDVERSION_TAG', 'TEXT')
    LIMIT ROW_COUNT

다음을 바꿉니다.

  • MODEL_ID: 쿼리할 모델의 ID입니다.

    Vertex AI Model Garden을 사용하는 경우 text-embedding-005을 모델 ID로 지정합니다. AlloyDB에서 텍스트 임베딩에 사용할 수 있는 클라우드 기반 모델입니다. 자세한 내용은 텍스트 임베딩을 참고하세요.

  • 선택사항: VERSION_TAG: 쿼리할 모델의 버전 태그입니다. 태그 앞에 @를 추가합니다.

    Vertex AI에서 text-embedding-005 영어 모델 중 하나를 사용하는 경우 모델 버전에 나열된 버전 태그 중 하나(예: text-embedding-005)를 지정합니다.

    항상 버전 태그를 지정하는 것이 좋습니다. 버전 태그를 지정하지 않으면 AlloyDB는 항상 최신 모델 버전을 사용하므로 예상치 못한 결과가 발생할 수 있습니다.

  • TEXT: 벡터 임베딩으로 변환할 텍스트입니다.

다음 단계