[PostgreSQL] pgvector

pgvector๋Š” PostgreSQL์˜ vector ๊ฒ€์ƒ‰์šฉ ํ™•์žฅ์ด๋‹ค.
PostgreSQL์˜ ํ•ต์‹ฌ ๋„๊ตฌ ์ค‘ ํ•˜๋‚˜์ด๋ฉฐ, AWS RDS๋ฅผ ํฌํ•จํ•œ ๋งŽ์€ ์ œ๊ณต ์„œ๋น„์Šค๋“ค์—์„œ๋„ ๊ธฐ๋ณธ์œผ๋กœ ์„ค์น˜๊ฐ€ ๋˜์–ด์žˆ๋‹ค.

์—ฌ๊ธฐ์„œ๋Š” pgvector ์ž์ฒด์˜ ๊ธฐ๋ณธ ์‚ฌ์šฉ๊ตฌ์กฐ๋งŒ ๋‹ค๋ฃฌ๋‹ค.




์„ค์น˜ (Ubuntu)

์ง์ ‘ ๋ฐ›์•„์„œ make๋กœ ๋นŒ๋“œํ•ด๋„ ๋˜๊ณ , ํŒจํ‚ค์ง€ ๋งค๋‹ˆ์ €์— ์žˆ์œผ๋ฉด ๊ทธ๋ƒฅ ๋ฐ›์•„์„œ ์จ๋„ ๋œ๋‹ค.

sudo apt-get install postgresql-16-pgvector

๊ทธ๋ฆฌ๊ณ  psql์— ๋“ค์–ด๊ฐ€์„œ ํ™•์žฅ์„ ํ™œ์„ฑํ™”ํ•ด์ฃผ๋ฉด ๋์ด๋‹ค.

CREATE EXTENSION vector;




ํ…Œ์ด๋ธ” ์ƒ์„ฑ

vector๋ผ๋Š” ํŠน์ˆ˜ํ•œ ํƒ€์ž…์„ ํ†ตํ•ด์„œ ๋ฒกํ„ฐ ํƒ€์ž…์„ ์ •์˜ํ•œ๋‹ค.
๋ฒกํ„ฐ๋“ค์€ ๊ธธ์ด๊ฐ€ ๊ณ ์ •๋œ ๋ฐฐ์—ด์ด๊ธฐ ๋•Œ๋ฌธ์—, ํƒ€์ž…์„ ์„ ์–ธํ• ๋•Œ๋ถ€ํ„ฐ ๊ธธ์ด๋ฅผ ์ง€์ •ํ•ด์ค˜์•ผ ํ•œ๋‹ค.

๋‹ค์Œ์€ ๊ธธ์ด๊ฐ€ 10์งœ๋ฆฌ์ธ ๋ฒกํ„ฐ ํƒ€์ž…์„ ์ •์˜ํ•œ ๊ฒƒ์ด๋‹ค.

CREATE TABLE vector_items (
    id serial8 PRIMARY KEY,
    embedding vector(10)
);

๊ทธ๋ฆฌ๊ณ  ๋ฌธ์ž์—ด ๋‚ด์˜ ์ˆซ์ž ๋ฐฐ์—ด์„ ํ†ตํ•ด ๋ฒกํ„ฐ ๋ฐ์ดํ„ฐ๋ฅผ ์ •์˜ํ•œ๋‹ค. ์ด๋Ÿฐ ์‹์ด๋‹ค.

INSERT INTO vector_items (embedding) VALUES
('[1,5,1,1,1,1,1,1,1,1]'),
('[1,1,1,4,1,4,1,1,1,1]'),
('[1,1,1,1,3,3,1,1,1,1]'),
('[1,1,1,1,1,3,3,3,1,1]'),
('[1,1,2,1,1,1,4,1,1,1]');




๊ธฐ๋ณธ ์‚ฌ์šฉ๋ฒ•

vector ๋ฐ์ดํ„ฐ๋“ค์€ ๊ธฐ๋ณธ์ ์œผ๋กœ ์œ ์‚ฌ๋„ ๊ธฐ๋ฐ˜์˜ ๊ฒ€์ƒ‰์„ ํ–‰ํ• ๋•Œ ์ฃผ๋กœ ์‚ฌ์šฉํ•œ๋‹ค.
๊ทธ๋ž˜์„œ ์ผ์น˜ ๊ฒ€์ƒ‰๋ณด๋‹ค๋Š” ์œ ์‚ฌ๋„๊ฐ€ ๋†’์€ ์ˆœ์„œ๋Œ€๋กœ ๊ฐ€์ ธ์˜ค๋Š” ํ–‰์œ„๊ฐ€ ์ผ๋ฐ˜์ ์ด๋‹ค.

๊ทธ๋ž˜์„œ pgvector์—์„œ๋„ ์ •๋ ฌ์กฐ๊ฑด์˜ ํ˜•ํƒœ๋กœ ๋ฒกํ„ฐ ๊ฒ€์ƒ‰์„ ์ˆ˜ํ–‰ํ•œ๋‹ค.
order by๋กœ ์œ ์‚ฌ์„ฑ์ด ๋†’์€ ์ˆœ์„œ๋Œ€๋กœ ์ •๋ ฌํ•˜๊ณ , LIMIT์„ ๊ฑธ์–ด์„œ ์ƒ์œ„ ๋ฐ์ดํ„ฐ๋งŒ ๊ฐ€์ ธ์˜ค๋Š” ์‹์ด๋‹ค.

์•„๋ž˜๋Š” L2 distance๋กœ ์œ ์‚ฌ๋„๋ฅผ ์ธก์ •ํ•ด์„œ ์ƒ์œ„ 5๊ฐœ๋งŒ ์ฐพ์•„์˜ค๋Š” ์ฟผ๋ฆฌ๋‹ค.

SELECT *
FROM vector_items
ORDER BY embedding <-> '[1,1,1,1,1,1,1,1,1,1]'
LIMIT 5;

์ด๊ฑด ์œ ํด๋ฆฌ๋“œ distance๋ผ๊ณ ๋„ ๋ถ€๋ฅธ๋‹ค.
์ƒ์„ธํ•œ ์›๋ฆฌ๋Š” ๊ตณ์ด ์—ฌ๊ธฐ์„œ ๋‹ค๋ฃจ์ง„ ์•Š๊ฒ ๋‹ค. ๊ธธ์–ด์ง„๋‹ค.

์ด์™ธ์—๋„ ๋‹ค์–‘ํ•œ ์œ ์‚ฌ๋„ ๊ฒ€์ƒ‰ ์—ฐ์‚ฐ์ž๋“ค์„ ์ œ๊ณตํ•œ๋‹ค.
์˜ˆ๋ฅผ ๋“ค์–ด <#>๋Š” inner product๋กœ ๋ฒกํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๊ณ 

SELECT *
FROM vector_items
ORDER BY embedding <#> '[1,1,1,1,1,1,1,1,1,1]'
LIMIT 5;

<=>๋Š” cosine distance๋กœ ๋ฒกํ„ฐ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜จ๋‹ค.

SELECT *
FROM vector_items
ORDER BY embedding <=> '[1,1,1,1,1,1,1,1,1,1]'
LIMIT 5;

๊ฐ™์€ ๋ฐ์ดํ„ฐ๋ผ๋„ ๊ฒ€์ƒ‰ ๋ฐฉ์‹์— ๋”ฐ๋ผ์„œ ๊ฐ€์ ธ์˜ค๋Š” ํ•ญ๋ชฉ๊ณผ ์ˆœ์„œ๊ฐ€ ๋‹ค๋ฅธ ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.




์ธ๋ฑ์Šค

๊ทธ๋ƒฅ ๋ฌด์‹ํ•˜๊ฒŒ ์ฟผ๋ฆฌ๋งŒ ๋‚ ๋ฆฌ๋ฉด ๋ญํ•˜๊ฒ ๋Š”๊ฐ€?
๋ฒกํ„ฐ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ํ•ต์‹ฌ ์ค‘ ํ•˜๋‚˜๋Š” ์ด๋Ÿฐ ๋ณต์žกํ•œ ๊ทผ์‚ฌ์น˜ ๊ฒ€์ƒ‰์—์„œ์˜ ์•ˆ์ •์ ์ธ ์„ฑ๋Šฅ์ด๋‹ค.

pgvector๋Š” ์œ ์‚ฌ๋„ ๊ฒ€์ƒ‰์—์„œ ์ธ๋ฑ์Šค๋ฅผ ํ†ตํ•ด ๋น ๋ฅธ ๊ฒ€์ƒ‰์ด ์ด๋ค„์งˆ ์ˆ˜ ์žˆ๋„๋ก, ์ „์šฉ ์ธ๋ฑ์Šค ํ˜•์‹๋“ค์„ ์ œ๊ณตํ•œ๋‹ค.
์˜ˆ๋ฅผ ๋“ค์–ด, ๋‹ค์Œ์€ l2 distance์— ๋งž๊ฒŒ ๋™์ž‘ํ•˜๋Š” hnsw ์•Œ๊ณ ๋ฆฌ์ฆ˜ ๊ธฐ๋ฐ˜์˜ ์ธ๋ฑ์Šค๋ฅผ ์ƒ์„ฑํ•œ๋‹ค.

CREATE INDEX vector_items_idx ON vector_items USING hnsw (embedding vector_l2_ops);

vector_l2_ops๋Š” l2 distance์— ๋Œ€ํ•ด์„œ ๋™์ž‘ํ•œ๋‹ค๋Š” ๋œป์ด๊ณ , hnsw์ด ์ธ๋ฑ์Šค ํƒ€์ž…์ด๋‹ค.

hnsw์€ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๊ฝค ๋งŽ์ด ์‚ฌ์šฉํ•˜๋Š” ๋Œ€์‹  ์„ฑ๋Šฅ์€ ๋น ๋ฅธ ํŽธ์ด๋‹ค.
์ธ๋ฑ์Šค ํƒ€์ž…์œผ๋กœ๋Š” HNSW์™€ IVFFlat 2๊ฐ€์ง€๊ฐ€ ์ œ๊ณต๋˜๋Š”๋ฐ, ์„œ๋กœ trace-off๊ฐ€ ํ™•์‹คํ•˜๋‹ˆ ์‚ฌ์šฉ์‚ฌ๋ก€์— ๋งž์ถฐ์„œ ์ž˜ ์„ ํƒํ•˜๋ฉด ๋œ๋‹ค.



์ฐธ์กฐ
https://github.com/pgvector/pgvector