AlloyDB AI를 사용하여 생성형 AI 애플리케이션 빌드

이 섹션에서는 pgvector 확장 프로그램을 사용하여 예측을 호출하고 임베딩을 쿼리하고 색인을 생성하는 방법을 설명합니다. 이러한 머신러닝 기반 AI 기능은 머신러닝 (ML) 모델의 시맨틱 및 예측 기능을 데이터에 적용할 수 있는 PostgreSQL용 AlloyDB 기능 모음인 AlloyDB AI를 통해 사용할 수 있습니다.

AlloyDB AI에 대해 자세히 알아보려면 https://cloud.google.com//alloydb/docs/ai를 참고하세요.

예측 호출

Vertex AI를 AlloyDB Omni와 통합하고 Vertex AI에 저장된 모델에서 예측을 실행하려면 다음 단계를 따르세요.

시작하기 전에

  1. GDC에서 Vertex AI 온라인 예측을 사용 설정합니다.
  2. 다음 명령어를 실행하여 이전 단계에서 다운로드한 서비스 계정 키를 기반으로 Kubernetes 보안 비밀을 만듭니다. Kubernetes 보안 비밀은 DBCluster 리소스와 동일한 네임스페이스에 만들어야 합니다.

    kubectl create secret generic SECRET_NAME \
    --from-file=PATH_TO_SERVICE_ACCOUNT_KEY/private-key.json \
    -n NAMESPACE

    다음을 바꿉니다.

    • SECRET_NAME: AlloyDB Omni가 Distributed Cloud AI 기능에 액세스할 수 있도록 DBCluster 매니페스트를 만들 때 사용되는 보안 비밀의 이름입니다. 예를 들면 vertex-ai-key-alloydb입니다.

    • PATH_TO_SERVICE_ACCOUNT_KEY: private-key.json 서비스 계정 키를 다운로드한 위치의 경로입니다.

    • NAMESPACE: 데이터베이스 클러스터의 네임스페이스입니다.

  3. 데이터베이스 엔진 유형 선택 및 데이터베이스 클러스터 만들기에 나와 있는 단계에 따라 AlloyDB Omni 연산자를 설치합니다.

  4. AlloyDB AI로 데이터베이스 클러스터를 만들고 vertexAIKeyRef를 이전 단계에서 DBCluster 매니페스트의 googleMLExtension 필드에 만든 Kubernetes 보안 비밀로 설정합니다.

    apiVersion: v1
    kind: Secret
    metadata:
      name: db-pw-DBCLUSTER_NAME
      namespace: USER_PROJECT
    type: Opaque
    data:
      DBCLUSTER_NAME: "BASE64_PASSWORD"
    ---
    apiVersion: DBENGINE_NAME.dbadmin.gdc.goog/v1
    kind: DBCluster
    metadata:
      name: DBCLUSTER_NAME
      namespace: USER_PROJECT
    spec:
      primarySpec:
        adminUser:
          passwordRef:
            name: db-pw-DBCLUSTER_NAME
        features:
          googleMLExtension:
            config:
              vertexAIKeyRef: SECRET_NAME
        version: "DB_VERSION"
        resources:
          memory: DB_MEMORY
          cpu: DB_CPU
          disks:
          - name: DataDisk
            size: DB_DATA_DISK
    

    다음 변수를 바꿉니다.

    • DBCLUSTER_NAME: 데이터베이스 클러스터의 이름입니다.
    • USER_PROJECT: 데이터베이스 클러스터가 생성될 사용자 프로젝트의 이름입니다.
    • BASE64_PASSWORD: 데이터베이스 관리자 비밀번호의 base64 인코딩입니다.
    • DBENGINE_NAME: 데이터베이스 엔진의 이름입니다. alloydbomni로 설정합니다.
    • DB_VERSION: 데이터베이스 엔진의 버전입니다.
    • DB_MEMORY: 데이터베이스 클러스터에 할당된 메모리 양입니다(예: 5Gi).
    • DB_CPU: 데이터베이스 클러스터에 할당된 CPU 양입니다(예: 2).
    • DB_DATA_DISK: 데이터베이스 클러스터에 할당된 공간의 양입니다(예: 10 Gi).

    매니페스트를 적용합니다.

    kubectl apply -f DB_CLUSTER_YAML

    다음을 바꿉니다.

    • DB_CLUSTER_YAML: 이 데이터베이스 클러스터 매니페스트 파일의 이름입니다(예: alloydb-omni-db-cluster.yaml).
  5. google_ml_integration 확장 프로그램을 설치합니다.

    CREATE EXTENSION google_ml_integration CASCADE;
    

예측 호출

다음 ml_predict_row() SQL 함수를 실행하여 Vertex AI 모델 엔드포인트를 사용하여 온라인 예측을 호출합니다.

  SELECT ml_predict_row('PREDICTION_ENDPOINT/PROJECT_NAMESPACE/ORGANIZATION/ZONE/DNS/DNS_SUFFIX', '{ "instances": [ INSTANCES ], "parameters":
  PARAMETERS');

다음을 바꿉니다.

  • PREDICTION_ENDPOINT: Vertex AI 엔드포인트 정규화된 이름

  • PROJECT_NAMESPACE: Vertex AI 엔드포인트가 배포된 네임스페이스

  • ORGANIZATION: Vertex AI 엔드포인트가 배포된 조직의 이름입니다.

  • ZONE: Vertex AI 엔드포인트가 배포된 영역

  • DNS: 조직의 DNS

  • DNS_SUFFIX: DNS 객체의 서픽스

  • INSTANCES: JSON 형식의 예측 호출의 입력

  • PARAMETERS: JSON 형식의 예측 호출의 매개변수

pgvector를 사용하여 임베딩 쿼리 및 색인 생성

pgvector PostgreSQL 확장 프로그램을 사용하면 데이터베이스에서 텍스트 임베딩을 저장, 색인 생성, 쿼리할 때 벡터별 연산자와 함수를 사용할 수 있습니다. AlloyDB는 pgvector를 사용할 수 있도록 최적화되어 있으므로 임베딩을 포함하는 특정 쿼리를 가속화할 수 있는 색인을 만들 수 있습니다.

AlloyDB를 LLM으로 사용하고 https://cloud.google.com/alloydb/docs/ai/work-with-embeddings#index에서 LLM을 기반으로 벡터 임베딩을 생성하고 저장하는 방법을 자세히 알아보세요.

ScaNN을 사용하여 색인 생성 및 벡터 쿼리

이 섹션에서는 저장된 임베딩을 사용하여 색인을 생성하고 임베딩을 쿼리하는 방법을 보여줍니다. AlloyDB를 사용하여 ScaNN 색인을 만들 수 있습니다.

시작하기 전에

색인 생성을 시작하려면 다음 기본 요건을 완료해야 합니다.

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

  • Google에서 AlloyDB용으로 확장한 pgvector 기반 vector 확장 프로그램 버전 0.5.0 이상을 설치해야 합니다.

    CREATE EXTENSION IF NOT EXISTS vector;
    
  • ScaNN 색인을 생성하려면 vector 확장 프로그램 외에 postgres_ann 확장 프로그램을 설치하세요.

    CREATE EXTENSION IF NOT EXISTS postgres_ann;
    

ScaNN 색인 만들기

데이터베이스의 테이블에 ScaNN 색인을 만들 수 있습니다.

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

ScaNN 색인은 근사 최근접 이웃 검색을 위한 트리 기반 양자화 색인입니다. 색인 빌드 시간이 짧고 메모리 사용 공간이 작습니다. 또한 워크로드에 따라 빠른 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 사이의 값으로 설정합니다.

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-평균 클러스터링 트리의 최대 수준 수. 2단계 트리 기반 양자화의 경우 1(기본값)로 설정하고 3단계 트리 기반 양자화의 경우 2로 설정합니다.

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

색인 파라미터는 QPS와 재현율 간의 적절한 균형을 유지하도록 설정해야 합니다.

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를 임베딩 열의 차원 너비로 바꿉니다.

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

SELECT * FROM pg_stat_progress_create_index;

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

쿼리 실행

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

임베딩 벡터의 의미론적 최근접 이웃을 찾으려면 색인 생성 중에 사용한 것과 동일한 거리 함수를 설정하는 다음 예시 쿼리를 실행하면 됩니다.

  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() 함수를 사용해 텍스트를 벡터로 변환할 수도 있습니다. 이 벡터를 pgvector 최근접 이웃 연산자 중 하나인 <->(L2 거리)에 적용하여 의미상 가장 유사한 임베딩이 있는 데이터베이스 행을 찾습니다. 이 함수를 사용하려면 먼저 텍스트 임베딩 Gecko 모델을 등록해야 합니다.

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

  CREATE EXTENSION google_ml_integration;
  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을 사용하는 경우 textembedding-gecko@003를 모델 ID로 지정합니다. 이는 Distributed Cloud가 텍스트 임베딩에 사용할 수 있는 클라우드 기반 모델입니다.

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

    Vertex AI에 textembedding-gecko 영어 모델 중 하나를 사용하는 경우 예를 들어 textembedding-gecko@003와 같은 버전 태그를 지정하세요.

    버전 태그를 지정하는 것이 좋습니다. 버전 태그를 지정하지 않으면 AlloyDB는 항상 최신 모델 버전을 사용하게 되며, 이로 인해 예기치 않은 결과가 발생할 수 있습니다.

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

벡터 색인 측정항목

이 섹션에서는 AlloyDB에서 생성된 벡터 색인과 관련된 측정항목을 보여줍니다. 이러한 측정항목은 postgres_ann 확장 프로그램을 설치했을 때 사용할 수 있는 pg_stat_ann_indexes 보기를 통해 확인할 수 있습니다.

사용성 측정항목

사용성 측정항목에는 색인 구성, 색인 스캔 수와 같은 측정항목을 사용하여 색인 활용 상태를 파악하는 데 도움이 되는 측정항목이 포함됩니다.

측정항목 이름 데이터 유형 설명
relid OID 벡터 색인이 포함된 테이블의 고유 식별자입니다.
indexrelid OID 벡터 색인의 고유 식별자입니다.
schemaname NAME 색인이 속한 스키마의 이름입니다.
relname NAME 색인이 포함된 테이블의 이름입니다.
indexrelname NAME 색인의 이름입니다.
indextype NAME 색인 유형. 이 값은 항상 postgres_ann으로 설정됩니다.
indexconfig TEXT[] 색인 생성 시 정의된 구성(예: 리프 수, 양자화기)
indexsize TEXT 색인의 크기입니다.
indexscan BIGINT 색인에서 시작된 색인 스캔 횟수입니다.

조정 측정항목

조정 측정항목은 현재 색인 최적화에 대한 인사이트를 제공하여, 더 빠른 쿼리 성능을 위해 권장사항을 적용할 수 있도록 합니다.

측정항목 이름 데이터 유형 설명
insertcount BIGINT 색인에 대한 삽입 작업 수입니다. 이 측정항목에는 색인이 생성되기 전에 존재했던 행 수도 포함됩니다.
updatecount BIGINT 색인에 대한 업데이트 작업 수입니다. 이 측정항목은 HOT 업데이트를 고려하지 않습니다.
deletecount BIGINT 색인에 대한 삭제 작업 수입니다.
distribution JSONB 색인의 모든 파티션에 걸친 벡터 분포입니다.

분포 필드의 세부정보는 다음과 같습니다.
  • maximum (INT8): 모든 파티션 중 최대 벡터 수입니다.
  • minimum (INT8): 모든 파티션 중 최소 벡터 수입니다.
  • average (FLOAT) : 모든 파티션의 평균 벡터 수입니다.
  • outliers (INT8[]): 모든 파티션의 상위 이상점입니다. 이 값은 상위 20개의 이상점을 보여줍니다.

참고: K-평균 클러스터링 알고리즘의 고유한 특성으로 인해 색인이 처음 생성될 때도 파티션 간 벡터 분포에 일정 수준의 분산이 발생하는 것이 정상입니다.

측정항목을 기반으로 한 조정 추천

변형
insertcount, updatecount, deletecount 측정항목은 색인의 벡터에 있는 변경사항이나 변형을 함께 보여줍니다.
색인은 특정 개수의 벡터와 파티션으로 생성됩니다. 벡터 색인에서 삽입, 업데이트, 삭제와 같은 작업을 실행하면, 이는 벡터가 있는 초기 파티션 집합에만 영향을 줍니다. 그 결과 시간이 지남에 따라 각 파티션의 벡터 수가 변동되고, 이는 재현율, QPS 또는 두 가지 모두에 영향을 줄 수 있습니다.
시간이 지남에 따라 ANN 검색 쿼리에서 QPS가 낮거나 재현율이 좋지 않은 등 속도 또는 정확도 문제가 발생하는 경우 이러한 측정항목을 검토해 보세요. 전체 벡터 수에 비해 변동 횟수가 많다면 색인 재생성이 필요하다는 신호일 수 있습니다.
배포
distribution 측정항목은 모든 파티션에 걸친 벡터 분포를 보여줍니다.
색인을 만들 때, 색인은 특정 개수의 벡터와 고정된 파티션 수로 생성됩니다. 파티셔닝 프로세스와 그 이후의 분포는 이 고려사항을 기반으로 이루어집니다. 이후 벡터가 추가되면 이들은 기존 파티션에 분배되며, 그 결과 색인 생성 시점의 분포와는 다른 분포가 형성됩니다. 최종 분포는 모든 벡터를 동시에 고려하지 않으므로 재현율, QPS 또는 두 가지 모두에 영향을 줄 수 있습니다.
ANN 검색 쿼리에서 응답 시간이 느려지거나 결과 정확도가 떨어지는(QPS 또는 재현율로 측정) 등 성능이 점진적으로 저하되는 현상이 관찰된다면, 이 측정항목을 확인하고 색인을 다시 생성하는 것이 좋습니다.