본문 바로가기

server/system design

[3] 이력서 챗봇 만들기 - postgreSQL pg_vector

 

 

LLM에서 출력되는 벡터를 저장하고 검색하기 위해서 postgreSQL을 사용하여 벡터 검색을 하려 한다.

먼저 postgreSQL은 RDS를 사용할것이다! (1년간 무료!)
접속은 ec2에서만 접근가능하도록 퍼블릭 연결은 차단한다.

1. 설치

 

ec2에서 먼서 postgreSQL 패키지 설치를 해야 한다.

pgvector extension를 ec2에 설치 후 해당 설치 파일을 postgreSQL에 설치하는 방식이다.

$ sudo apt update
$ sudo apt install postgresql postgresql-contrib


### pgvector 직접 설치
$ sudo apt install postgresql-server-dev-16
$ cd /tmp
$ git clone --branch v0.8.0 https://github.com/pgvector/pgvector.git
$ cd pgvector
$ make
$ make install

 

 

postgreSQL에 접속

$ sudo -i -u postgres psql

 

설치 전에는 다음과 같이 extensions에 아무것도 나오지 않는다.

postgres=# SELECT * FROM pg_available_extensions WHERE name = 'vector';
 name | default_version | installed_version | comment
------+-----------------+-------------------+---------
(0 rows)

 

 

pg_vector extension 설치

postgres=# CREATE EXTENSION vector;
CREATE EXTENSION

 

설치 다시 확인

postgres=# SELECT * FROM pg_available_extensions WHERE name = 'vector';
  name  | default_version | installed_version |                       comment
--------+-----------------+-------------------+------------------------------------------------------
 vector | 0.8.0           | 0.8.0             | vector data type and ivfflat and hnsw access methods
(1 row)

 

 


 

2. 벡터 테스트

 

임시 테이블 생성

(칼럼 속성이 vector이며 3차원을 의미한다. 참고로 나중에 벡터 검색을 위해선 모델마다 정확한 벡터 크기를 알고 디비에 설정해줘야 한다. )

postgres=# CREATE TABLE items (
    id SERIAL PRIMARY KEY,
    name TEXT,
    embedding vector(3)
);
CREATE TABLE

 

 

데이터 삽입

INSERT INTO items (name, embedding) 
VALUES 
    ('item1', '[0.1, 0.2, 0.3]'),
    ('item2', '[0.5, 0.6, 0.7]'),
    ('item3', '[0.9, 0.8, 0.7]');

 

 

코사인 유사도 벡터 검색

<=> 연산자는 pg_vector에서 제공하는 거리 계산 연산자로, 기본적으로 L2 거리 (유클리드 거리)를 사용한다.

 

[벡터 차원이 작아서 L2 거리 (유클리드 거리)가 코사인유사도 보다 더 정확하게 나올수도 있음!!] (아래를 보면 item2가 더 유사한것으로 나옴)

SELECT id, name, 1 - (embedding <=> '[0.2, 0.1, 0.3]') AS similarity
FROM items
ORDER BY similarity DESC
LIMIT 5;

-------------------------------------
 id | name  |     similarity
----+-------+--------------------
  2 | item2 | 0.9428472539087849
  1 | item1 | 0.9285714475780119
  3 | item3 | 0.9018471910389302
(3 rows)

 

 

3. 추가

대량 데이터를 처리할 때 속도를 높이려면 HNSW(힐베르트 커브 기반 근사 최근접 탐색) 인덱스를 추가

vector_l2_ops는 L2 거리 기반 인덱스으로 HNSW 인덱스는 빠르게 최근접 벡터를 찾을 수 있도록 최적화된다.
단, HNSW 인덱스는 근사값을 제공하므로 완전히 정밀한 검색이 필요하다면 ORDER BY를 활용한 정확한 거리 정렬이 필요하다.

CREATE INDEX ON items USING hnsw (embedding vector_l2_ops);

 

 

 

 

 

 

참고

https://github.com/pgvector/pgvector

https://stackoverflow.com/questions/56724622/how-to-fix-postgres-h-file-not-found-problem