11P by neo 16일전 | favorite | 댓글 1개
  • AI 애플리케이션을 구축하려는 엔지니어링 팀을 괴롭히는 메시지 : "임베딩이 다시 동기화되지 않았습니다"
  • 간단한 벡터 검색 구현은 모니터링, 동기화 및 문제 해결의 복잡한 오케스트라로 발전함
  • 벡터 데이터베이스로 AI 시스템을 구축하는 엔지니어링 팀과 이야기를 나눈 결과, 벡터 데이터베이스의 잘못된 추상화와 오늘날 사용 방식의 결함을 발견함

"RAG 시스템을 구축하는 공통적인 사례"

  • Pinecone을 벡터 데이터베이스로 사용하여 임베딩을 저장하고 검색함
  • 텍스트 데이터가 Pinecone의 메타데이터에 잘 맞지 않아 DynamoDB로 블롭과 애플리케이션 데이터를 처리함
  • 어휘 검색을 위해 OpenSearch가 필요했음
  • 이제 3개의 시스템을 연결하고 동기화하는 것이 악몽임

소스 문서를 삭제할 때 다음을 수행해야 함:

  1. boto3를 실행하여 DynamoDB에서 레코드 제거
  2. Pinecone을 업데이트하여 임베딩이 삭제되었는지 확인
  3. 어휘 검색 인덱스를 업데이트하기 위해 POST 요청 필요
  • 모든 소스 문서 업데이트, 추가 또는 삭제에 대해 이를 수행해야 함
  • 구성 관리는 지저분할 뿐만 아니라 위험함
  • 4개월 전에 삭제했어야 할 인덱스에 대해 한 달에 $2,000를 지불한 팀도 있음
  • 잘못되거나 오래된 데이터를 사용자에게 반환할 위험이 있음

벡터 데이터베이스는 잘못된 추상화에 구축됨

  • 벡터 데이터베이스는 임베딩을 파생 데이터가 아닌 독립적인 데이터로 취급함
  • 임베딩을 독립적인 데이터로 취급함으로써 불필요한 복잡성을 만듦

더 나은 방법: "Vectorizer" 추상화

  • 임베딩을 데이터베이스 인덱스와 같이 취급하는 "벡터라이저" 추상화를 제안함
  • 이 접근 방식은 임베딩을 소스 데이터와 자동으로 동기화하여 유지 관리 비용을 제거함
  • CREATE INDEX 명령에 해당하는 벡터라이저는 다음과 같음:
SELECT ai.create_vectorizer(  
    'public.blogs'::regclass,  
    embedding => ai.embedding_openai('text-embedding-3-small', 1536),  
    chunking => ai.chunking_recursive_character_text_splitter('content')  
);  
  • 이 명령은 블로그 테이블의 모든 항목에 대한 임베딩을 생성하고 테이블의 데이터가 변경될 때 임베딩을 계속 업데이트함

벡터 데이터베이스(및 벡터 데이터 유형)의 문제점

  • 벡터 데이터베이스는 텍스트, 이미지 및 멀티모달 데이터에 대한 대량의 벡터 임베딩을 처리하기 위해 개발됨
  • PostgreSQL, MySQL, MongoDB, Oracle과 같은 범용 데이터베이스도 벡터 검색 지원을 추가함
  • 그러나 독립형 시스템 또는 기존 데이터베이스에 추가된 벡터 검색 기능의 추상화에는 치명적인 결함이 있음
  • 임베딩이 데이터베이스에 삽입되면 임베딩되는 비정형 데이터와 벡터 임베딩 자체 간의 연결이 끊어짐
  • 이 연결이 없으면 임베딩은 파생 데이터가 아닌 개발자가 관리해야 하는 독립적인 데이터 원자로 잘못 취급됨
  • 임베딩을 파생 데이터로 재구성하면 임베딩이 소스 데이터와 연결되지 않은 현재 벡터 데이터베이스 추상화의 부조리함이 분명해짐

개발 팀은 다음을 관리해야 함:

  • 복잡한 ETL(추출-로드-변환) 파이프라인

  • 임베딩용 벡터 데이터베이스, 메타데이터 및 앱 데이터용 다른 데이터베이스, 어휘 검색 인덱스

  • 데이터 동기화 서비스

  • 업데이트 및 동기화를 위한 큐잉 시스템

  • 데이터 드리프트를 잡고 임베딩 서비스의 속도 제한 등을 처리하는 모니터링 도구

  • 검색이 오래된 결과를 반환할 때 알림 시스템

  • 모든 시스템에 대한 검증 확인

  • 새로운 임베딩 모델로 업그레이드하거나 다른 청킹 방법을 시도하려면 사용자 정의 코드를 작성하고 여러 데이터 서비스 및 데이터베이스에서 변경 사항을 조정해야 함

  • 이러한 작업은 개발 팀에게 임베딩이 소스 데이터가 변경됨에 따라 시기적절하게 생성되도록 보장하는 부담을 줌

  • 그렇지 않으면 임베딩이 자주 오래되어 사용자에게 더 나쁜 애플리케이션 경험을 제공할 위험이 있음

더 나은 방법: 데이터베이스가 복잡성을 처리하도록 하기

  • 임베딩을 파생 데이터로 재구성하면 기본 데이터가 변경됨에 따라 임베딩을 생성하고 업데이트할 책임을 데이터베이스 관리 시스템에 맡길 수 있음
  • 이 변경으로 개발자는 수동으로 임베딩을 소스 데이터와 동기화된 상태로 유지해야 하는 부담에서 벗어남
  • 이 구분은 RAG에 대해 일회성 데이터 가져오기를 수행하는 간단한 애플리케이션에는 중요하지 않을 수 있음
  • 그러나 대부분의 실제 애플리케이션에서 데이터는 지속적으로 변경됨
  • 임베딩 기반 의미론적 검색을 사용하는 전자상거래 플랫폼이나 최신 제품 정보로 최신 상태를 유지해야 하는 제품 어시스턴트 RAG 앱을 고려하십시오.
  • 이러한 변경 사항을 수동으로 추적하고 임베딩을 다시 생성하는 것은 노동 집약적이고 오류가 발생하기 쉬울 뿐만 아니라 개발자가 핵심 비즈니스 목표에 집중하는 것을 방해함
  • 데이터베이스 시스템이 자동으로 처리할 수 있는데 왜 개발 시간을 낭비하는가?

벡터라이저: 인덱스로서의 벡터 임베딩

  • 벡터 임베딩을 독립적인 테이블이나 데이터 유형이 아닌 임베딩된 데이터에 대한 특수한 인덱스로 개념화하는 것이 더 효과적인 추상화임
  • 벡터 임베딩은 전통적인 의미에서 인덱스가 아님
  • 대신에 벡터 임베딩은 임베딩에 기반하여 데이터의 가장 관련성 있는 부분을 검색하는 인덱싱 메커니즘으로 작동함
  • 우리는 이 새로운 인덱스와 유사한 추상화를 "벡터라이저"라고 부를 수 있음

벡터라이저 추상화의 주요 이점:

자동 동기화

  • 데이터베이스의 인덱싱의 주요 이점 중 하나는 기본 데이터와 인덱스를 자동으로 동기화된 상태로 유지하는 것
  • 열의 데이터가 변경되면 인덱스가 그에 따라 업데이트됨
  • 벡터 임베딩을 인덱싱의 한 형태로 취급함으로써 이와 동일한 자동 동기화를 활용할 수 있음
  • 시스템은 벡터 임베딩이 항상 최신 데이터로 최신 상태를 유지하도록 보장하여 수동 업데이트의 필요성을 제거하고 오류 위험을 줄임

강화된 데이터-임베딩 관계

  • 벡터가 독립적으로 저장되면 원래 데이터와의 관계를 잃어버리기 쉬움
  • 이 벡터는 데이터의 최근 업데이트에서 생성되었는가? 아니면 이전 임베딩 모델의 오래된 벡터인가?
  • 이러한 질문은 중요하며 여기서 혼동되면 심각한 오류가 발생할 수 있음
  • 벡터 임베딩을 인덱스로 데이터에 직접 연결함으로써 관계가 명확해지고 자동으로 유지됨

단순화된 데이터 관리

  • 개발자는 종종 데이터 동기화를 수동으로 관리할 때 어려움에 직면함
  • 예를 들어, 기본 데이터가 삭제될 때 이전 임베딩 모델의 데이터를 삭제하는 것을 잊으면 불일치가 발생할 수 있음
  • 벡터라이저 추상화는 이러한 관계를 관리하는 것을 시스템의 책임으로 만들어 개발자의 인지 부하를 줄이고 실수 가능성을 최소화함

벡터라이저는 핵심 DBMS 약속의 자연스러운 진화

  • 벡터라이저 개념은 현대 데이터베이스 관리 시스템(DBMS) 기능의 자연스러운 진화임
  • 오늘날의 DBMS는 인덱스, 트리거, 물질화된 뷰와 같은 선언적 구조를 통해 데이터 변환 및 동기화를 관리하는 데 이미 능숙함
  • 벡터라이저 추상화는 벡터 임베딩 관리의 점점 더 중요해지는 작업을 처리하기 위한 새로운 도구를 제공하여 이 패러다임에 잘 맞음
  • 이 기능을 DBMS에 직접 포함함으로써 데이터베이스 시스템의 궁극적인 약속을 실현하는 데 더 가까워짐
  • 사용자가 애플리케이션 구축, 데이터 분석 및 혁신 주도에 가장 잘하는 일에 집중할 수 있도록 복잡성을 추상화하는 방식으로 데이터를 관리함

PostgreSQL용 벡터라이저 구현: pgai Vectorizer

  • 개발자의 부담을 가볍게 하겠다는 약속에 동기를 부여받아 Timescale의 AI 엔지니어링 팀은 PostgreSQL용 벡터라이저를 구현했음
  • pgai Vectorizer라고 하며 현재 Early Access에 있음
  • PGAI 프로젝트의 일부로 PostgreSQL을 AI 시스템에 더 적합하게 만들고 PostgreSQL에 익숙한 개발자에게 AI 개발을 쉽게 하기 위한 프로젝트임
  • pgai Vectorizer가 PostgreSQL의 데이터에 대한 벡터 임베딩을 자동으로 생성하고 업데이트하는 방법을 보려면 데모 비디오를 확인하세요

pgai Vectorizer 작동 방식

  • SQL에서 벡터라이저를 정의하고 생성함
  • 다음 쿼리는 벡터라이저를 생성하고 작용하는 테이블,벡터화할 열, 사용할 임베딩 모델, 임베딩할 소스 데이터에 포함할 다른 정보에 대한 추가 서식을 지정함
-- blogs 테이블의 데이터를 자동으로 임베드하는 벡터라이저 생성  
SELECT ai.create_vectorizer(  
   'public.blogs'::regclass  
   -- OpenAI text-embedding-3-small 모델 사용  
 , embedding=>ai.embedding_openai('text-embedding-3-small', 1536, api_key_name=>'OPENAI_API_KEY')  
   -- 테이블에 100k 행이 있을 때 StreamingDiskANN 인덱스 자동 생성  
 , indexing => ai.indexing_diskann(min_rows => 100000, storage_layout => 'memory_optimized'),  
   -- content 열에 재귀적 청킹 적용  
 , chunking=>ai.chunking_recursive_character_text_splitter('content')  
   -- 더 나은 검색을 위해 다른 열의 메타데이터를 임베딩에 추가  
 , formatting=>ai.formatting_python_template('Blog title: $title url: $url blog chunk: $chunk')  
);  
-- 벡터라이저는 소스 테이블이 변경될 때 임베딩을 업데이트함   
-- 다른 사용자 작업은 필요하지 않음  
  • 또한 긴 텍스트를 임베딩 모델 토큰 제한에 맞는 여러 개의 작은 청크로 분할해야 하므로 기본 청킹 함수를 정의함

소스 데이터 변경 사항 추적

  • pgai Vectorizer는 내부적으로 소스 테이블의 수정(삽입, 업데이트, 삭제)을 확인하고 벡터 임베딩을 비동기식으로 생성하고 업데이트함
  • 자체 호스팅 및 Timescale Cloud에서 완전 관리형의 두 가지 배포 유형에 대해 pgai Vectorizer를 구축함
  • pgai Vectorizer의 클라우드 호스팅 구현에서는 Timescale Cloud 플랫폼의 클라우드 기능을 사용하여 임베딩 생성
  • pgai Vectorizer의 오픈 소스 버전에서는 외부 작업자를 실행하여 임베딩 생성
  • pgai Vectorizer는 구성 및 카탈로그 정보를 데이터베이스 내부의 주요 내부 부기 데이터와 함께 저장함

임베딩을 실제로 생성하는 곳은?

  • 실제 임베딩 프로세스는 데이터베이스 외부의 외부 프로세스에서 발생함
  • 이는 데이터베이스 서버의 부하를 줄이고 벡터라이저가 애플리케이션 쿼리를 처리하는 데이터베이스의 기능에 영향을 미치지 않음을 의미함
  • 또한 다른 데이터베이스 작업과 독립적으로 임베딩 작업을 쉽게 확장할 수 있음
  • 이 프로세스는 먼저 데이터베이스를 읽어 수행해야 할 작업이 있는지 확인
  • 있는 경우 데이터베이스에서 데이터를 읽고, 청킹 및 포맷팅을 수행하고, OpenAI와 같은 임베딩 모델 제공업체에 호출하여 임베딩을 생성하고, 결과를 다시 데이터베이스에 씀

프로세스 사용자 정의

  • pgai Vectorizer는 유연함: 임베딩을 만드는 데 사용되는 청킹 및 포맷 규칙을 지정할 수 있음
  • 특히 벡터화할 소스 테이블의 열과 소스 데이터가 임베딩 토큰 제한 내에 맞고 관련 데이터가 각 임베딩에 포함되도록 하는 청킹 및 포맷팅 규칙을 구성할 수 있음
  • pgai Vectorizer의 Early Access 릴리스에서는 OpenAI 임베딩 모델 선택, 텍스트를 더 작은 청크로 분할하는 청킹 전략, 각 청크에 추가 컨텍스트를 주입하는 포맷팅 옵션, 자동 인덱스 생성 및 성능 튜닝을 위한 사용자 정의 인덱싱 구성을 사용자 정의할 수 있음
  • 곧 사용자가 자신의 Python 코드를 제출하여 청킹, 임베딩 및 포맷팅을 완전히 사용자 정의할 수 있도록 하여 이를 더욱 유연하게 만들 계획

예를 들어 다음은 HTML 소스 파일을 재귀적으로 분할하고 소스 데이터에서 OpenAI 임베딩을 만들도록 구성된 벡터라이저임. 코드, 문서, 마크다운 등 애플리케이션 데이터에 맞게 청킹과 포맷팅을 구성할 수 있음

-- 고급 벡터라이저 구성   
SELECT ai.create_vectorizer(  
   'public.blogs'::regclass,  
   destination => 'blogs_embedding_recursive',  
   embedding => ai.embedding_openai('text-embedding-3-small', 1536),  
   -- HTML 콘텐츠에 대해 지정된 설정으로 재귀 청킹 적용  
   chunking => ai.chunking_recursive_character_text_splitter(  
       'content',  
       chunk_size => 800,  
       chunk_overlap => 400,  
       -- HTML 인식 구분 기호, 우선 순위가 가장 높은 것부터 가장 낮은 순서로 정렬  
       separator => array[  
           E'</article>', -- 주요 문서 섹션에서 분할   
           E'</div>',    -- div 경계에서 분할  
           E'</section>',  
           E'</p>',      -- 단락에서 분할  
           E'<br>',      -- 줄 바꿈에서 분할  
           E'</li>',     -- 목록 항목에서 분할  
           E'. ',        -- 문장 경계로 대체   
           ' '          -- 최후의 수단: 공백에서 분할  
       ]  
   ),  
   formatting => ai.formatting_python_template('title: $title url: $url $chunk')  
);  

GN⁺의 의견

  • pgai Vectorizer는 임베딩 관리를 크게 단순화할 수 있는 강력하고 혁신적인 도구로 보임. 벡터라이저 추상화는 개발자가 임베딩을 수동으로 관리해야 하는 부담을 덜어주고 임베딩이 소스 데이터와 동기화되도록 보장.
  • 특히 임베딩 모델 업그레이드 또는 청킹 전략 변경과 같은 변경 사항을 적용할 때 매우 유용할 것 같음. 기존의 벡터 데이터베이스에서는 이러한 변경으로 인해 여러 시스템에서 사용자 정의 코드를 작성하고 조정해야 하는 복잡한 프로세스가 발생할 수 있지만, pgai Vectorizer를 사용하면 벡터라이저 구성만 업데이트하면 됨.
  • 또한 PostgreSQL과 같은 범용 데이터베이스에서 임베딩을 관리하면 여러 전문 시스템을 오케스트레이션해야 하는 문제를 피할 수 있음. 이는 애플리케이션 개발을 크게 단순화할 수 있음.
  • 한 가지 고려해야 할 점은 외부 Python 프로세스에서 실제 임베딩이 생성된다는 것. 이는 데이터베이스 성능에 영향을 미치지 않도록 하는 좋은 설계 선택이지만, 임베딩 생성 프로세스를 별도로 모니터링하고 관리해야 함을 의미함.
  • 궁극적으로 pgai Vectorizer는 AI 애플리케이션을 위한 임베딩 관리 방식에 상당한 발전을 나타냄. 더 많은 팀이 이를 도입하고 피드백을 제공함에 따라 이 강력한 도구가 더욱 발전할 것으로 기대됨. Postgres와 같은 친숙한 도구에 임베딩 관리를 통합하면 더 많은 개발자가 첨단 AI 기능을 활용할 수 있게 될 것임.
Hacker News 의견
  • 데이터 동기화의 오버헤드를 과대평가하고 있으며, 대부분의 임베딩 기반 워크플로우는 업데이트나 삭제가 많지 않음. 작은 데이터 집합에서도 일관성 문제를 인식하기 어려움. 하지만 데이터 동기화 걱정이 필요 없다는 점은 여전히 멋짐

    • Postgres 데이터베이스에 임베딩을 저장할 때 가장 큰 단점은 워크로드가 매우 다르다는 것임. HNSW 인덱스는 많은 리소스를 소모하며, 리소스 경쟁 문제를 일으킬 수 있음. 데이터베이스를 이동시키면 일관성 문제가 다시 발생함
    • 필터링과의 상호작용에 대한 질문이 있음. 부분 인덱스를 활용할 수 있는지, pgvector의 HNSW 구현의 제한 사항이 여전히 존재하는지 궁금함
  • Elastic 직원으로서, Elasticsearch가 최근에 semantic_text라는 데이터 타입을 추가했음을 언급함. 이는 텍스트를 자동으로 청크로 나누고 임베딩을 계산하여 저장함. 쿼리도 간소화되어 I/O가 줄어들고 클라이언트 코드가 간단해짐

  • PostgreSQL 도구를 소개하며, 벡터 임베딩을 데이터베이스 인덱스로 재구상함. 현재 OpenAI만 지원하지만, 곧 로컬 및 OSS 모델 지원을 계획 중임. 피드백과 반응을 기대함

  • FAISS를 단일 데이터베이스로 사용하는 것에 대한 의문을 제기함. 이는 벡터 임베딩을 위한 sqlite와 같으며, 메타데이터와 벡터를 함께 저장하여 관계를 유지할 수 있음

  • Postgres에 벡터를 사용하는 것에 대해 긍정적이며, SQL 쿼리에서 벡터 검색과 논리를 포함할 때 필터링 순서에 대한 의문을 제기함. pg_vector의 DX를 좋아하지만, 벡터 검색 후 필터링이 속도를 저하시킬 수 있음

  • 원시 임베딩을 벡터 데이터베이스에 저장하는 것은 텍스트의 원시 n-그램을 데이터베이스에 저장하는 것과 같다고 언급함. 문서를 저장하는 것이 더 합리적임

  • sqlite-vec과 FTS5를 SQLite에서 사용 중이며, 매우 유용하다고 언급함

  • PostgreSQL ORM을 Node.js에서 구축하여 벡터 필드를 포함한 코드를 작성할 수 있게 함. 이는 데이터나 임베딩 콘텐츠를 쿼리할 수 있으며, 모델의 필드를 임베딩으로 저장하는 방법을 정의할 수 있음

  • Materialized Views가 좋다고 언급함

  • 캐릭터 기반 청크를 사용하는 AI 앱은 PoC 단계를 넘지 않았다고 언급함