[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๊ฐ ํ์คํ๋ ์ฌ์ฉ์ฌ๋ก์ ๋ง์ถฐ์ ์ ์ ํํ๋ฉด ๋๋ค.