pg_vectorsearch: pgvector의 IVFFlat·HNSW보다 빠른 인덱스

Pg_vectorsearch: An index that is faster than pgvector's IVFFlat and HNSW

github.com/timescale ▲ 190 댓글 49 jascha_eng

요약

타임스케일이 pgvector보다 빠르다는 PostgreSQL 벡터 검색 확장 pg_vectorsearch를 내놓았습니다.

PostgreSQL용 벡터 확장 pgvectorscale을 만들었던 타임스케일이 새로 공개한 오픈소스 확장입니다. 벡터를 여러 구역으로 나눠 찾는 PRISM 인덱스를 써서 1억 개 넘는 벡터 검색을 겨냥했습니다.

왜 중요한가

  • 램 가격이 오르면서 메모리를 덜 쓰는 벡터 인덱스 경쟁이 붙었고, 여기에 새 선택지가 생겼습니다.
  • 기존 pgvector의 vector·halfvec 열에 인덱스만 새로 만들면 되므로 데이터를 옮기지 않고 바꿔 볼 수 있습니다.

핵심 내용

  • 1억 개 데이터에서 HNSW와 같은 재현율(실제 이웃을 찾아낸 비율)을 내면서, 메모리가 4분의 1인 서버에서 더 빨랐다고 밝혔습니다.
  • PRISM은 벡터를 계층형 중심점 트리로 묶어 두고, 검색할 때는 가까운 구역만 살펴봅니다.
  • RaBitQ 양자화(벡터를 짧은 코드로 압축하는 기법)로 후보를 추린 뒤, 원본 벡터로 다시 순위를 매깁니다.
  • PostgreSQL 18 이상이 필요하고, 알파 단계라 버전을 올릴 때 인덱스를 지우고 다시 만들어야 할 수 있습니다.
  • 데이터가 쌓여도 구역이 저절로 나뉘지 않아 REINDEX나 prism_rebalance로 정리해 줘야 합니다.

HN 반응

  • 벡터 차원이 1968개로 제한되고 관리형 클라우드에서 아직 쓸 수 없어 당장 도입하기 어렵다는 지적이 나왔습니다.
  • pgvector에 기여하지 않은 이유를 묻자, 개발진은 pgvector 쪽이 기존 인덱스에 집중하길 원했고 앞선 그래프 방식은 재현율이 들쭉날쭉했다고 답했습니다.

댓글

30개 표시 · 전체 49개
  1. devy HN

    기존 pgvector의 HNSW 인덱싱을 이 확장으로 바꿔 볼 생각이라면 참고할 만한 예비 조사 결과가 몇 가지 있습니다.

    • pg_vectorsearch는 PRISM이라는 양자화 IVF 인덱스를 씁니다. PRISM은 벡터 차원이 최대 1968까지입니다. 기존 HNSW 인덱스의 차원이 이보다 크면 방법이 없습니다(적어도 이 문제가 고쳐지기 전까지는).

    • pg_vectorsearch는 Postgres 18 이상이 필요합니다. 그보다 낮은 PG 버전을 쓴다면 먼저 데이터베이스를 마이그레이션해야 합니다. 레거시 PG 운영 환경 중에는 PG 14나 15처럼 한참 낡은 버전이 많고, 그냥 한번 써 보려고 마이그레이션하기에는 비용이 너무 큽니다.

    • pg_vectorsearch는 어제 출시됐고 누가 봐도 알파 단계입니다. Timescale 바깥의 운영 환경에서는 검증된 적이 없습니다. 게다가 너무 새로워서 Azure의 허용 확장 목록에도, 다른 하이퍼스케일러의 관리형 PG 인스턴스 허용 목록에도 없습니다. 알파에서 벗어나 성숙하려면 시간이 걸립니다. 그러니 하이퍼스케일러 클라우드의 관리형 PG 인스턴스를 쓴다면 방법이 없고(적어도 이 확장이 해당 생태계에 자리 잡기 전까지는), PG 18 셀프 호스팅으로 옮겨야 합니다.

  2. Arch485 HN

    최대 차원 문제에 대해: 인덱스용으로만 입력 벡터를 잘라 쓰면 됩니다. 쿼리할 때도 잘라낸 벡터로 인덱스를 조회하고, 그 뒤에 전체 길이 벡터로 한 번 더 비교하면 됩니다.

    예시입니다(지금 진행 중인 프로젝트에서 가져왔습니다).

    
    SELECT *
    
    FROM report_embeddings a
    
    INNER JOIN report_embeddings b
    
    
    ON (
    

    subvector(a.embedding, 1, 768)::vector(768) <->

    
    subvector(b.embedding, 1, 768)::vector(768)
    
    
    ) < $1
    

    AND b.id != a.id

    
    WHERE a.id = $2
    
    
    AND a.embedding <-> b.embedding < $1
    
    
    

    이 예시에서는 인덱스와 조회에 쓰려고 임베딩을 768차원으로 잘랐지만(INNER JOIN 부분 참고), 전체 벡터 비교도 추가로 합니다(WHERE 절).

    이렇게 하면 인덱스에서 빠르지만 덜 정확한 조회를 먼저 하고, 거기서 걸린 결과에 대해서만 인덱스를 타지 않는 전체 벡터 검사를 합니다.

  3. sroussey HN

    그건 MRL 임베딩에서만 통합니다.

  4. zX41ZdbW HN

    여기서 보듯이 아다마르 변환으로 회전시킨 임베딩에서도 꽤 잘 통합니다: https://embeddings.info/

  5. curious_cat_163 HN

    저는 Azure DB에서 pgvector를 써 봤습니다. "그럭저럭" 괜찮게 동작했어요. HNSW와 PRISM에 대해 잘 아는 건 아니지만, 전부 하위 호환이 된다는데 왜 pgvector 쪽에 PR을 보내지 않았는지 궁금합니다.

    완전히 새로운 걸 만들게 된 설계 과정을 더 알고 싶어요. 가볍게 내린 결정은 아니었으리라 생각하지만, 위에 나온 번거로움을 감수하고 이걸 써야 하는 이유에 대해서는 README에 설명이 너무 빈약합니다. 적어도 만들게 된 경위만이라도요.

  6. mfreed HN

    좋은 질문입니다. 저희가 첫 벡터 확장인 pgvectorscale을 만들 때, pgvector 작성자에게 먼저 연락해서 인덱스 유형을 추가로 지원할 의향이 있는지 물어봤습니다(당시에는 DiskANN 기반이었죠). 저희 작업물을 pgvector에 바로 기여하려는 생각이었습니다. 그때 그쪽은 기존 인덱스 유형에 집중하고 프로젝트를 그 방향으로 넓히지는 않겠다는 입장으로 보였습니다. 저희는 그 결정을 존중해서 별도의 확장으로 진행했습니다.

    그런데 오픈소스와 PostgreSQL 확장 구조의 좋은 점이 바로 이런 프로젝트들이 공존할 수 있다는 것입니다! pg_vectorsearch는 pgvector의 기존 데이터 타입을 그대로 쓸 수 있어서, 개발자는 어느 쪽 인덱스든 골라 쓸 수 있습니다.

  7. enordstr HN

    pg_vectorsearch의 주 기여자입니다. 단순히 "PR을 보내는" 게 말처럼 쉽지 않은 이유가 여러 가지 있습니다.

    회사로서 저희는 다른 속도로 움직이고 싶고, pgvector 같은 프로젝트가 받아들이기 어려운 것들(그럴 만한 이유가 있죠)도 시도해 보고 싶습니다. pg_vectorsearch는 알파 수준의 소프트웨어이고 pgvector는 안정 버전입니다. 일찍 공개하는 건 커뮤니티가 더 빨리 쓸 수 있게 하고 피드백도 받으려는 방법입니다.

    거기에 기술적인 이유도 여러 가지 있습니다. 아키텍처가 다르고 구현상의 선택도 다릅니다. 새로운 걸 시도하고 완전히 다른 방향으로 갈 자유도 있고요.

  8. surister HN

    "그냥 PR 보내면 되잖아"가 말처럼 쉬운 게 아닙니다.

  9. vovavili HN

    2번과 3번은 요즘 나오는 흥미로운 최신 Postgres 확장 대부분에 해당할 겁니다.

  10. mfreed HN

    [Tiger Data CTO입니다]

    오늘 pg_vectorsearch에 대해 좋은 질문과 피드백이 많이 올라왔고, 벌써 PR 기여도 들어왔습니다. 그중 일부에 답하려고 PRISM 인덱스 아키텍처에 대한 짧은 기술 심층 분석 글을 썼는데, 공유드립니다.

    https://www.linkedin.com/pulse/inside-pgvectorsearch-architecture-prism-vector-index-freedman-owukc/

  11. EgregiousCube HN

    저는 지금 VectorChord를 쓰고 있는데 아주 마음에 듭니다. 빠른 디스크를 받쳐 주면 Postgres 비용이 절반으로 줄었어요. 저메모리용 벡터 인덱스 도구에서 경쟁이 생기니 반갑습니다. RAMageddon 때문에 요즘 NVMe 드라이브가 얼마나 빠른지를 활용할 방법을 더 찾게 되는 분위기네요!

  12. enordstr HN

    pg_vectorsearch의 주 기여자입니다. 둘 다 써 보시면 경험이 어땠는지, 저희가 어떻게 개선하면 좋을지 알려 주세요.

  13. Rapzid HN

    그런데 필터링은 지원하나요?

    수정: 사후 필터링만 되네요.

    이런 인덱스로 테넌트/사용자/권한 범위를 다들 어떻게 효율적으로 구현하는지 모르겠습니다.

  14. 3abiton HN

    메모 확인해 보니, 클라이언트별, 사용자별, 프로젝트별... 등등 데이터베이스를 하나씩 둡니다.

  15. qeternity HN

    파티셔닝은 쉬운 부분이고 Postgres에서는 자연스럽게 따라오는 거라고 생각합니다.

    그런데 벡터 데이터베이스에서 최신성 가중(recency biasing)은 다들 어떻게 하나요?

    저희가 써 본 방법은 전부 비용이 많이 들거나 엄청 억지스럽습니다.

  16. enordstr HN

    멀티테넌트 테이블용 다중 컬럼 인덱스는 이후 릴리스에서 지원할 계획입니다.

  17. arunmu HN

    이 사람들이 pgvectorscale도 만들지 않았나요? 지금은 유지보수가 안 되는 것 같던데요. 새 인덱스를 만들 게 아니라 pgvectorscale에 추가하거나 개선하면 되지 않았을까요?

  18. cevian HN

    (pgvectorscale 작성자입니다)

    그 부분은 블로그 글에서 직접 다뤘습니다: https://www.tigerdata.com/blog/announcing-pg_vectorsearch-scalable-open-source-vector-search-postgresql

    요약하면, pgvectorscale의 들쭉날쭉한 재현율 성능이 마음에 들지 않았고(문헌을 뒤져도 고칠 방법을 찾지 못했습니다), 그래프 알고리즘에서 파티션 기반 알고리즘으로 옮겨 가는 것이 장기적으로 더 나은 접근이라고 판단했습니다.

  19. arunmu HN

    감사합니다. 재현율이 왜, 어느 규모에서 나빴는지 더 자세히 써 주셨다면 지금 쓰는 사람들도 자기 문제를 알아볼 수 있었을 텐데 아쉽습니다. 그리고 새 인덱스는 메모리 기반이고 디스크 자료구조로 만들어지지 않아서 메모리가 작은 머신에서는 확장이 안 되는 것 같은데, 맞나요?

  20. ilumanty HN

    SQLite가 이런 걸 지원하면 정말 좋을 텐데요.

  21. vikrantrathore HN

    SQLite 위에서 paxos를 쓰는 프로젝트 두 개를 확인해 보세요. SQLite의 FTS와 sqlite-vec 확장 위에 상호 순위 결합(RRF)과 분포 기반 결합 점수(DBSF)를 구현한 것들입니다.

    프로젝트 zaxonlite: https://github.com/insanai/zaxonlite

    프로젝트 sqlodin: https://github.com/insanai/sqlodin

    다만 SQLite는 한 번에 쓰기 작업자가 하나만 허용된다는 점을 기억해야 하고, 두 프로젝트 모두 이 제약 안에서 써야 합니다. PostgreSQL은 MVCC를 쓰니까 여러 클라이언트의 동시 쓰기 성능은 더 나을 수 있습니다. 벤치마크는 해 보지 않아서 단정할 수는 없습니다.

  22. ethagnawl HN

    참고로 DuckDB는 지원합니다. 여기를 보세요: https://duckdb.org/docs/current/core_extensions/vss

  23. veonik HN

    몇 가지 있어요. Vec1이라는 공식 확장도 있고요.

  24. trnvll HN

    빨리 써 보고 싶네요. 속도가 중요한 프로젝트가 있는데, 모든 걸 Postgres 안에서 해결하는 깔끔하고 단순한 개발 경험(DX)도 포기하고 싶지 않거든요.

  25. alexpadula HN

    PRISM의 어두운 면이네요! 저장소의 이미지는 핑크 플로이드의 Dark Side of The Moon에서 100% 영감을 받은 거죠.

  26. skim HN

    SynthID로 확인하면 AI가 생성한 이미지라고 나오는데요.

  27. swe_dima HN

    클라우드 업체가 관리형 Postgres에서 제공하지 않으면 쓸 수 있는 사람이 많지 않다는 게 아쉽네요...

  28. jascha_eng HN

    관리형으로 쓰고 싶으면 언제든 Tiger Cloud로 옮기시면 됩니다 :) 그리고 이건 저희 pg_textsearch처럼 PostgreSQL 라이선스라서, pg_textsearch는 이미 Google의 AlloyDB와 마이크로소프트의 HorizonDB에 채택됐으니 희망은 있습니다!

  29. potomushto HN

    흥미롭네요. 훨씬 빠르고 저장 효율도 좋다고 하는 비트 정밀도와 해밍 거리 연산자 지원에 대한 언급은 보이지 않네요.

  30. dmix HN

    pg_search와는 어떻게 비교되는지 궁금합니다. https://www.paradedb.com/blog/introducing-search

Hacker News에서 보기 ↗