본문 바로가기

AI

PrivateGPT - local 문서 기반 채팅 시스템 구축하기

  프라이빗 챗 GPT의 개념

  • private chat gpt는 특정 기업이나 조직에서만 사용하는 기업용 챗 GPT 입니다.
  • 최근 기업의 내부 데이터를 활용한 채팅 시스템이 많이 나오고 있습니다.
    • openai에서는 ChatGPT Enterprise 버전을 출시했습니다.
      • gpt4를 무제한으로 사용할 수 있으며, 보안이 보장되어있습니다.
    • MS에서도 애저 오픈AI 서비스로 프라이빗 챗 gpt서비스를 출시했습니다.
  • 고객의 프롬프트나 데이터를 교육에 사용하지 않고 사전 학습된 모델에만 의존하여 데이터 유출에 민감한 서비스의 경우 100% private하게 사용 가능하다는 이점이 있습니다.
  • 위와 같은 유료 서비스를 이용하면 보안, 속도, 무제한 컨텍스트와 같은 이점이 있지만, 비용 측면에서 빅테크 모델들은 큰 부담이므로 자체적으로 LLM을 개발하거나, 무료 오픈 소스 모델(라마, 알파카) 등을 활용하여 기업 채팅 서비스를 구축하려는 경향이 있습니다.

 

  PrivateGPT 오픈소스 소개

github: https://github.com/imartinez/privateGPT

 

GitHub - imartinez/privateGPT: Interact with your documents using the power of GPT, 100% privately, no data leaks

Interact with your documents using the power of GPT, 100% privately, no data leaks - imartinez/privateGPT

github.com

목적

  • 100% 프라이빗한 LLM 프로젝트 구축을 위한 api 제공

특징

  • 인터넷 연결없이 개인 문서들을 LLM에 로딩하고 그에 대해 질문가능
  • LangChain + GPT4All + LlamaCPP + Chroma + SentenceTransformers 활용
  • 문서폴더에 파일 넣고 ingest.py 실행
    • csv, doc, eml(이메일), enex(에버노트), epub, html, md, msg(아웃룩), odt, pdf, ppt, txt

제공

RAG파이프라인 구현을 위한 4가지 API를 제공합니다.

  • ingestion
    • 문서를 텍스트로 변환, 구문 분석, 청크 단위로 나누고 메타 데이터를 추출, 임베딩 생성 및 저장
  • chat
    • 이전 대화 맥락을 기억하면서 질문과 관련있는 컨텍스트를 저장된 문서에서 검색 및 해당 정보 활용한 llm 응답
  • embedding
    • 사용자가 지정한 임베딩 모델을 활용하여 임베딩 생성
    • 사용자가 지정한 벡터데이터베이스에 임베딩 저장
      • 지원되는 vectorDB: pgvector, chroma, qdrant
  • context chunks
    • 쿼리가 주어지면 수집된 문서에서 가장 관련성 높은 텍스트 청크를 반환

구조

  • fastAPI 기반 앱, openAI의 API 스키마를 따름
  • RAG 파이프라인은 LlamaIndex를 기반으로 함

 

  설치 및 사용

1. 소스 코드 다운로드

$ git clone https://github.com/imartinez/privateGPT
$ cd privateGPT

2. python 3.11 버전의 가상환경 생성

$ python3.11 -m venv .venv
$ source .venv/bin/activate

3. 의존성 관리를 위해 poetry 설치

$ pip install --upgrade pip poetry
$ poetry install

4. 설정에 따른 프로젝트 셋팅

$ poetry run python scripts/setup

 

settings.yaml 의 설정을 따르며 local 모드에서 llm, embedding, vectorstore는 아래와 같이 셋팅되어있습니다.

llm:
  mode: local
  # Should be matching the selected model
  max_new_tokens: 512
  context_window: 3900
  tokenizer: mistralai/Mistral-7B-Instruct-v0.2

embedding:    
  mode: local
  ingest_mode: simple

vectorstore:
  database: qdrant

qdrant:
  path: local_data/private_gpt/qdrant

local:
  prompt_style: "mistral"
  llm_hf_repo_id: TheBloke/Mistral-7B-Instruct-v0.2-GGUF
  llm_hf_model_file: mistral-7b-instruct-v0.2.Q4_K_M.gguf
  embedding_hf_model_name: BAAI/bge-small-en-v1.5

scripts/setup 스크립트를 수행하면 위 설정의 모델들이 models 폴더에 다운받아집니다.

 

5. 서버 start

$ poetry run python -m private_gpt

http://127.0.0.1:8001/ 에 접속하면 gradio기반의 ui를 확인할 수 있습니다.

 

예시로 최근 공부했던 논문을 업로드 해 보았습니다. cpu only 모드라서 속도가 느리기 때문에 테스트를 진행할 것이면 작은 파일을 업로드 하는 것을 추천합니다. 저는 10페이지 짜리의 문서로 테스트하였습니다.

문서를 업로드하는 중에 로그를 확인해보면 페이지 수 만큼 두 가지 작업을 진행합니다.
먼저 문서를 파싱하고 임베딩을 생성하여 저장합니다. 파싱된 문서는 각각 docstore.json, graph_store.json, index_store.json 에 저장되고 벡터는 설정한대로 qdrant의 컬렉션에 저장됩니다.

 

문서 파싱은 llama_index.node_parser의 SentenceWindowNodeParser 로 수행하며 window_size=3으로 기준 문장의 앞뒤로 3문장씩, 총 7문장을 하나의 청크로 저장하게 됩니다.

 

💬 테스트

What is token type embedding?

논문에서 나온 토큰 타입 임베딩이 뭔지 물어봤습니다. 그러면 먼저 벡터 스토어에서 top 2개의 유사 노드를 가져옵니다. 그런데 왜 두 개를 같은 걸 가져오는 건지는 아직 더 확인해봐야할 것 같습니다. 노드의 아이디는 다르긴 합니다.

17:05:21.685 [DEBUG   ] llama_index.vector_stores.qdrant - > Top 2 nodes:
17:05:21.687 [DEBUG   ] llama_index.indices.utils - > Top 2 nodes:
> [Node 7f73c64d-aa4b-4aa5-9601-cd19c63847de] [Similarity score:             0.817385] We
denote the word token embedding by A∈R𝑉𝑤×𝑑, where𝑉𝑤
is the number of words in our vocabulary a...
> [Node b94295de-1e9d-4be3-9ff7-6740536c4a81] [Similarity score:             0.817385] We
denote the word token embedding by A∈R𝑉𝑤×𝑑, where𝑉𝑤
is the number of words in our vocabulary a...

가져온 정보를 컨텍스트로 넣어서 프롬프트가 구성됩니다.

** Prompt: **
<s>[INST] Context information is below.
--------------------
The target of Recformer is to understand
the model input 𝑋from both language understanding and sequen-
tial patterns in recommendations.  The key idea in our work is to
combine the embedding layers from language models [ 6,21] and
self-attentive sequential recommenders [ 14,27].  Hence, Recformer
contains four embeddings as follows:
•Token embedding represents the corresponding tokens.  We
denote the word token embedding by A∈R𝑉𝑤×𝑑, where𝑉𝑤
is the number of words in our vocabulary and 𝑑is the embed-
ding dimension.  Recformer does not have item embeddings
as previous sequential recommenders and hence Recformer
understands items in interaction sequences mainly based on
these token embeddings.  The size of token embeddings is a
constant for different recommendation scenarios; hence, our
model size is irrelevant to the number of items.

The target of Recformer is to understand
the model input 𝑋from both language understanding and sequen-
tial patterns in recommendations.  The key idea in our work is to
combine the embedding layers from language models [ 6,21] and
self-attentive sequential recommenders [ 14,27].  Hence, Recformer
contains four embeddings as follows:
•Token embedding represents the corresponding tokens.  We
denote the word token embedding by A∈R𝑉𝑤×𝑑, where𝑉𝑤
is the number of words in our vocabulary and 𝑑is the embed-
ding dimension.  Recformer does not have item embeddings
as previous sequential recommenders and hence Recformer
understands items in interaction sequences mainly based on
these token embeddings.  The size of token embeddings is a
constant for different recommendation scenarios; hence, our
model size is irrelevant to the number of items.
--------------------
You can only answer questions about the provided context.  If you know the answer but it is not based in the provided context, don't provide  the answer, just state the answer is not in the context provided. [/INST]</s>[INST] What is token type embedding? [/INST]

답변이 나왔습니다.

** Completion: **
 In the given context, a token embedding refers to an embedding matrix A ∈ R𝑉𝑤×𝑑, where 𝑉𝑤 is the number of words in the vocabulary and 𝑑 is the embedding dimension. It represents the embeddings for each word token in the input sequence. The context does not mention anything about token type embeddings specifically.

key-value 쌍의 토큰에 대한 임베딩이라는 점을 언급해주면 좋았을 텐데 그리 좋은 답변은 아니었습니다.

 

 

  아키텍처 분석

프로젝트의 구조를 살펴보겠습니다. 소스코드는 크게 ui, server, componenets로 이루어져있습니다.

  • front: ui
    • 이 프로젝트의 핵심은 아니므로 넘어가겠습니다.
  • backend: server, component
    • ingest, embeddings, chat, chunks 등 프로그램이 제공하는 api들이 폴더별로 모여있습니다.
├── components
│   ├── ingest
│   ├── embedding
│   ├── llm
│   ├── node_store
│   └── vector_store
├── server
│   ├── ingest
│   ├── embeddings
│   ├── chat
│   ├── chunks
│   ├── completions
│   ├── health
│   └── utils
  • component 와 server를 구분한 이유는?
    • server는 웹 서비스와 직접적으로 연결된 것입니다.
    • component는 웹 서비스가 가져다 쓰는 요소들의 실제 구현을 제공하는 부분으로 분리해 놓은 것으로 보입니다.
  • server 패키지에서도 각 api는 사용을 위한 엔드포인트(router)와 서비스 구현(service) 이 분리되어 있습니다.
  • 즉 router에서는 각 service를 호출하고 -> service는 component를 사용하여 구현됩니다.
  • 누구나 API와 RAG 구현을 쉽게 확장하고 조정할 수 있도록 하기 위해 해당 방식으로 설계했다고 합니다.
├── server
│   ├── chat
│   │   ├── chat_router.py
│   │   ├── chat_service.py
│   │   ├── __init__.py
│   ├── chunks
│   │   ├── chunks_router.py
│   │   ├── chunks_service.py
│   │   ├── __init__.py
│   ├── embeddings
│   │   ├── embeddings_router.py
│   │   ├── embeddings_service.py
│   │   ├── __init__.py
│   ├── ingest
│   │   ├── ingest_router.py
│   │   ├── ingest_service.py
│   │   ├── ingest_watcher.py
│   │   ├── __init__.py
│   │   └──model.py

 

  결론

PrivateGPT는 기업 내에서 안전하게 사용할 수 있는 100% 프라이빗한 Language Model을 구현하기 위한 오픈 소스 프로젝트입니다. 이를 사용하면 인터넷 연결 없이 기업 내 문서를 활용하여 질문에 답할 수 있으며, 높은 수준의 보안을 제공합니다. 이 글에서는 PrivateGPT의 개념, 목표, 제공 기능, 사용법, 그리고 프로젝트의 아키텍처에 대해 살펴보았습니다.

PrivateGPT는 LangChain, GPT4All, LlamaCPP, Chroma, SentenceTransformers 등 다양한 라이브러리를 활용하여 개발되었습니다. 제공되는 API는 Ingestion, Chat, Embedding, Retriever로 나뉘며, 문서를 텍스트로 변환하고, 컨텍스트를 기억하며 질문에 답하고, 임베딩을 생성하여 저장하며, 쿼리에 대한 관련 문서를 반환합니다.

PrivateGPT를 사용하면 기업은 민감한 정보를 안전하게 활용하면서 자체적인 챗봇 서비스를 구현할 수 있으며, 프로젝트의 아키텍처를 분석하면서 그 확장성과 유연성을 확인할 수 있었습니다. 보안, 비용, 속도 등 다양한 이점을 고려할 때, PrivateGPT는 기업용 챗봇 서비스를 구현하는데 유용한 오픈 소스 프로젝트로 주목받을 만한 가치가 있다고 평가됩니다.