pgvector를 사용하여 임베딩 저장 및 쿼리 수행

Completed

Tip

자세한 내용은 텍스트 및 이미지 탭을 참조하세요.

벡터 임베딩은 텍스트, 이미지 및 기타 콘텐츠를 의미를 포착하는 숫자 표현으로 변환합니다. Azure Database for PostgreSQL은 pgvector 확장을 통해 이러한 포함을 저장하고 쿼리하도록 지원하므로 별도의 벡터 저장소를 관리하지 않고도 기존 PostgreSQL 데이터베이스에 벡터 검색 기능을 추가할 수 있습니다.

이 단원에서는 pgvector 확장을 사용하도록 설정하고, 벡터 스토리지에 대한 스키마를 디자인하고, 포함을 삽입 및 업데이트하고, 기본 유사성 쿼리를 수행하는 방법에 대해 설명합니다. 이러한 기본 작업은 AI 애플리케이션에서 의미 체계 검색 및 검색 기능을 빌드하기 위한 기초를 형성합니다.

pgvector 확장 활성화

pgvector 확장은 PostgreSQL에 벡터 데이터 형식 및 유사성 검색 연산자를 추가합니다. embeddings를 저장하려면 먼저 데이터베이스에서 확장을 사용하도록 설정해야 합니다. Azure Database for PostgreSQL은 지원되는 확장 중 하나로 pgvector를 포함하므로 추가 설치 없이 사용할 수 있습니다.

pgvector를 사용하도록 설정하려면 데이터베이스에 연결하고 명령을 실행합니다 CREATE EXTENSION . 일반적으로 서버 관리자 또는 역할이 있는 사용자에게 azure_pg_admin 부여되는 확장을 만들려면 적절한 권한이 필요합니다.

CREATE EXTENSION IF NOT EXISTS vector;

확장을 사용하도록 설정한 후 설치된 확장을 쿼리하여 사용할 수 있는지 확인할 수 있습니다.

SELECT * FROM pg_extension WHERE extname = 'vector';

pgvector 확장은 임베딩을 단정밀도 부동 소수점 숫자의 배열로 저장하는 vector 데이터 형식을 도입합니다. 각 벡터에는 열을 만들 때 지정하는 고정된 수의 차원이 있습니다. 또한 확장은 빠른 유사성 검색을 위해 벡터와 인덱스 형식 간의 거리를 계산하는 연산자를 제공합니다.

벡터 스토리지에 대한 스키마 디자인

벡터 스토리지를 위한 효과적인 스키마 디자인은 임베딩을 애플리케이션에서 필터링 및 표시하는 데 필요한 메타데이터와 결합합니다. 벡터 열을 정의할 때 구문을 사용하여 vector(n) 차원 수를 지정합니다. 여기서 n 포함 모델의 출력 차원과 일치해야 합니다.

일반적인 포함 차원은 모델에 따라 다릅니다. 문장 변환기 모델은 일반적으로 384차원 벡터를 생성합니다. OpenAI의 text-embedding-ada-002 모델은 1,536차원을 출력하고, text-embedding-3-large는 최대 3,072차원을 생성할 수 있습니다. 잘못된 차원 수를 사용하면 삽입 오류가 발생하므로 테이블을 만들기 전에 모델의 출력 차원을 확인합니다.

다음 예제에서는 필터링 및 표시에 유용한 메타데이터와 함께 포함되는 법적 문서를 저장하는 테이블을 만듭니다.

CREATE TABLE documents (
    id SERIAL PRIMARY KEY,
    title TEXT NOT NULL,
    content TEXT,
    category TEXT,
    practice_area TEXT,
    created_at TIMESTAMPTZ DEFAULT NOW(),
    updated_at TIMESTAMPTZ DEFAULT NOW(),
    embedding vector(1536)
);

이 스키마는 문서 포함을 메타데이터와 동일한 행에 저장합니다. 이 방법은 유사한 문서와 해당 세부 정보를 모두 검색하기 위해 조인이 필요하지 않으므로 쿼리를 간소화합니다. 큰 콘텐츠 필드의 경우 전체 텍스트를 별도의 테이블에 저장하고 주 테이블에 요약 또는 제목만 유지하여 유사성 검색 중에 전송되는 데이터를 줄이는 것이 좋습니다.

여러 포함 모델을 디자인하거나 다양한 콘텐츠 형식(예: 제목 및 전체 콘텐츠)을 포함할 때 여러 벡터 열을 추가할 수 있습니다.

CREATE TABLE documents (
    id SERIAL PRIMARY KEY,
    title TEXT NOT NULL,
    content TEXT,
    title_embedding vector(384),
    content_embedding vector(1536)
);

삽입 및 임베딩 업데이트

스키마를 만든 후 표준 SQL INSERT 문을 사용하여 포함을 삽입합니다. 벡터는 배열 형식의 문자열 리터럴로 표시되고 형식으로 vector 캐스팅됩니다. 애플리케이션 코드는 포함 API(예: Azure OpenAI)를 사용하여 포함을 생성하고 매개 변수로 데이터베이스에 전달합니다.

INSERT INTO documents (title, content, category, practice_area, embedding)
VALUES (
    'Corporate Merger Agreement Template',
    'This agreement outlines the terms and conditions for the merger of...',
    'contracts',
    'corporate',
    '[0.0123, -0.0456, 0.0789, -0.0321, ...]'::vector
);

큰 데이터 세트를 로드할 때 일괄 삽입의 경우 성능을 향상시키려면 다중 행 INSERT 문 또는 COPY 명령을 사용합니다.

INSERT INTO documents (title, content, category, embedding)
VALUES
    ('Document 1', 'Content...', 'legal', '[...]'::vector),
    ('Document 2', 'Content...', 'legal', '[...]'::vector),
    ('Document 3', 'Content...', 'legal', '[...]'::vector);

문서 콘텐츠가 변경되면 새 의미 체계 의미를 반영하도록 포함을 업데이트합니다.

UPDATE documents
SET content = 'Updated document content...',
    embedding = '[0.0234, -0.0567, ...]'::vector,
    updated_at = NOW()
WHERE id = 42;

자주 업데이트되는 애플리케이션의 경우 콘텐츠 변경 시 임베딩을 동기적으로 업데이트하는 대신 비사용 시간대에 임베딩 재생성을 일괄 처리하는 것이 좋습니다. 이 방법은 콘텐츠 업데이트에 대한 대기 시간을 줄이고 포함 API에 대한 호출을 통합합니다.

거리 연산자를 사용하여 벡터 쿼리

pgvector 확장은 벡터 간의 유사성을 측정하기 위한 3개의 거리 연산자를 제공합니다. 각 연산자는 서로 다른 유형의 거리를 계산하고 올바른 연산자를 선택하는 것은 포함 모델 및 사용 사례에 따라 달라집니다.

L2 거리(유클리드 거리) 는 포함 공간에 있는 두 벡터 사이의 직선 거리를 측정합니다. 연산자 <->를 사용하여 L2 거리를 계산합니다. 값이 작을수록 더 유사한 벡터가 표시됩니다. 이 메트릭은 벡터의 크기가 의미를 지니고 있을 때 잘 작동합니다.

SELECT id, title, embedding <-> '[0.0123, -0.0456, ...]'::vector AS distance
FROM documents
ORDER BY distance
LIMIT 10;

코사인 거리는 두 벡터 사이의 각도를 측정하여 크기를 무시합니다. 코사인 거리를 위해 <=> 연산자를 사용합니다. 값의 범위는 0(동일한 방향)에서 2(반대 방향)입니다. 코사인 거리는 벡터 길이가 아닌 의미 방향에 중점을 두기 때문에 텍스트 포함에 가장 일반적인 선택입니다.

SELECT id, title, embedding <=> '[0.0123, -0.0456, ...]'::vector AS distance
FROM documents
ORDER BY distance
LIMIT 10;

음의 내적은 두 벡터의 내적을 계산한 후 값을 음수로 변환합니다. 연산자를 <#> 사용합니다. 이 메트릭은 최대 내적 검색에 유용하며, 더 큰 내적 값은 더 유사한 벡터를 나타냅니다. 부정은 다른 연산자의 동작과 일치하여 더 작은 값이 더 나은 거리로 변환합니다.

SELECT id, title, embedding <#> '[0.0123, -0.0456, ...]'::vector AS distance
FROM documents
ORDER BY distance
LIMIT 10;

OpenAI의 포함을 포함한 대부분의 포함 모델은 코사인 유사성에 최적화되어 있습니다. 포함 모델의 설명서를 확인하여 권장되는 거리 메트릭을 확인합니다.

벡터 데이터 형식 및 정밀도

pgvector 확장은 각각 다른 스토리지 및 성능 특성을 가진 벡터를 저장하기 위한 세 가지 데이터 형식을 제공합니다.

벡터 형식은 요소를 단정밀도(32비트) 부동 소수점 숫자로 저장합니다. 대부분의 사용 사례에 대한 표준 형식이며 정밀도와 스토리지 효율성의 적절한 균형을 제공합니다. 1536차원 벡터는 약 6KB의 스토리지를 사용합니다.

하프벡 형식은 요소를 반정밀도(16비트) 부동 소수점 숫자로 저장합니다. 이 형식은 vector에 비해 스토리지를 절반으로 줄이면서도 대부분의 유사성 검색 작업에 필요한 충분한 정밀도를 유지합니다. 스토리지가 문제가 될 때 사용 halfvec 하며 정밀도 감소가 검색 품질에 큰 영향을 미치지 않는지 확인했습니다.

CREATE TABLE documents_compact (
    id SERIAL PRIMARY KEY,
    title TEXT NOT NULL,
    embedding halfvec(1536)
);

sparsevec 형식은 대부분의 요소가 0인 스파스 벡터를 저장합니다. 모든 차원을 저장하는 대신 0이 아닌 값과 해당 위치만 저장합니다. 이 형식은 특정 문서 표현과 같은 스파스 포함을 생성하는 모델에 유용합니다. 열을 만들 때 최대 차원 수를 지정합니다.

CREATE TABLE sparse_documents (
    id SERIAL PRIMARY KEY,
    title TEXT NOT NULL,
    embedding sparsevec(10000)
);

비고

열의 sparsevec HNSW 인덱스는 0이 아닌 요소를 최대 1,000개까지 지원합니다. 스파스 벡터가 이 제한을 초과하는 경우 차원 감소 또는 대체 인덱싱 전략을 고려합니다.

OpenAI 또는 문장 변환기와 같은 모델의 조밀한 포함을 사용하는 대부분의 AI 애플리케이션의 경우 표준 vector 형식을 사용합니다. 벤치마킹을 통해 특정 사용 사례에 대해 반정밀도가 허용 가능한 검색 품질을 제공한다는 것을 확인한 후에만 고려 halfvec 해 보세요.