티스토리 뷰
RAG(Retireval-Augmented Generation)
할루시네이션 현상 및 최신 정보 미 반영 등 사전 학습 모델은 문제가 많다.
따라서 RAG로 질문을 주고, 질문 관련 검색된 문서의 내용을 참고해서 답변하게 된다.
RAG의 특징 벡터
샘플을 잘 설명하는 특징이 좋은 특징이다.
머리 색, 머리 결, 피부 색, 키, 사진 지역 등
특징이 비슷하면 비슷한 사람이라고 할 수 있다. 그렇기에 유사도를 기반으로 매핑한다.
글자 뿐만이 아니라 문장도 특징 벡터로 만들 수 있다.
문자로는 비교할 수 없는 유사도나 거리, 관계 등을 알 수 있다.
TF-IDF를 사용하고, BM25로 TF-IDF의 스코어를 보완하기 위한 파라미터를 추가한다.
단어 qj의 IDF를 기반으로 파라미터를 쓴다.
k1이 0이면 뒤에가 다 무시된다.
k1가 커질수록 위쪽의 TF(가 영향을 더 미친다.
평균보다 문서가 기냐 짧냐에 따라서 어느정도 영향을 더 준다고 볼 수 있다.
거리
L2 Norm (점과 점 사이의 직선거리)
L1 Norm(맨하튼 거리.직각으로 돌어가는 거리)
좋은 데이터 = 한국어 위키 데이터
RAG를 이용하면, 모르는 것에 대해 모든다고 대답한다.
Sentence Transformer
동일한 BERT를 이용해서 두 문장 A,B의 특징 벡터 u,v를 각각 획득한다.
만약 u,v가 비슷하면, cosine-simi(u,v)가 커져야 두 문장의 유사도가 커진다.
두 벡터의 유사도가 높아지도록 학습하는 게 Sentence Transformer이다.
Negative Sample을 함께 넣어서 성능 향상이 가능하다.
DPR(Dense Passage Retrieval)
BERTq를 이용해서 질문의 특징 벡터 hq 획득한다.
BERTp를 이용해서 문저의 특징 벡터 hp를 획득한다.
두 벡터 ℎ𝑞,ℎ𝑝의 유사도가 높아지도록 학습
Negative Sample을 함께 넣어서 성능 향상이 가능하다.
질문 q가 들어가면 Question encoder에서 질문 특징 벡터 hq가 나온다.
문서 p가 들어가면 passage encoder에서 문서 특징 벡터 hp가 나온다.
그러면 similarity score를 dot product로 해서 sim(q,p) = hq^T * hp를 구한다.
위키백과 데이터
https://ko.wikipedia.org/wiki/%EC%9C%84%ED%82%A4%EB%B0%B1%EA%B3%BC:%EB%8D%B0
%EC%9D%B4%ED%84%B0%EB%B2%A0%EC%9D%B4%EC%8A%A4_%EB%8B%A4%EC%9A%B4%E
B%A1%9C%EB%93%9C
한국어 위키 덤프 : https://dumps.wikimedia.org/kowiki/
최신버전 다운로드 : https://dumps.wikimedia.org/kowiki/latest/kowiki-latest-pages-meta current.xml.bz2
영어 위키 덤프 : https://dumps.wikimedia.org/
WikiExtractor
위키 덤프 파일에서 필요 없는 파일을 정리하고 텍스트를 추출하는 파이썬 라이브러리이다.
!python -m wikiextractor.WikiExtractor \
--json \
--out {WORKSPACE}/data/kowiki \
{WORKSPACE}/data/kowiki-latest-pages-meta-current.xml.bz2
RAG 문서 DB 구축
위키 문서 대략 150만개
chunk_db.json 파일을 생성한다.
문서 관리를 위해서 별도의 json 파일을 생성한다. 여기서는 70개 문서만 사용
실제로 할 때는 검색량이 많아지면 검색에 대한 튜닝도 해야 한다.
각 문서의 길이가 다르므로 띄어쓰기 기준 128 단어를 포함하는 라인 단위로 분할(chunk) 후
chunk_db.json 파일에 저장한다.
각 chunk의 첫 시작은 문서의 제목으로 시작한다. 최종 347개의 chunk가 저장될 것이다.
문서 검색
BM25 문서를 검색한다.
Komoran 형태소 분석기를 사용해서, 각 chunk를 형태소 단위로 분절
분절 시 조사 등 불필요하다고 판단되는 형태소는 제거가 가능하다.
BM25Okapi 클래스를 이용해서 분절된 chunk들의 BM25 값을 계산한다.
검색을 위한 질문인 query 역시 동일한 방식으로 형태소 단위로 분절한다.
BM25Okapi 클래스를 이용해서 가장 유사도가 높은 10개의 문장을 반환한다.
BM25 검색은 글자 기반의 검색이다. 가령 빨강과 빨간이 있으면, 다르게 보는 것이다.
BM25는 단어 레벨에서 비교,
Sentence Tranformer는 문장과 질문을 벡터 레벨로 바꿔서 비교한다.
Sentence Tranformer 문서 검색
사전 학습된 파라미터를 이용해서 SentenceTranformer 로딩을 한다.
https://huggingface.co/snunlp/KR-SBERT-V40K-klueNLI-augSTS
chunk_embeddings 문장의 특징 벡터
query_embdding 질문 특징 벡터
query_embedding과 chunk_embeddings의 유사도를 계싼 후 가장 높은 10개의 문장을 반환한다.
유사도는 dot-product를 사용한다.
프롬프트 구성
답변을 얻고자 하는 질문인 query를 이용해서 문서를 검색한다.
검색 방법은 BM25, SentenceTransformer 중 선택한다.
지시문, 검색문장 5개, 질문을 사용한 적절한 프롬프트를 구성한다.
구성된 프롬프트를 SLLM에 입력 및 답변 출력할 수 있게 만든다.
RAG를 사용하지 않으면 아직 알려지지 않았다고 한다.
RAG 성능 개선을 위한 조언
더 큰 파라미터를 가진 SLLM 사용 (https://huggingface.co/google/gemma 1.1 7b it)
띄어쓰기 단위가 아닌 의미단위의 chunk 분할(gpt-4 활용해서, 문서를 주고 분할해달라고 하는 것)
향상된 검색기능 활용 (DPR 또는 DPR+BM25)
벡터 DB 사용(많은 문서 저장 가능(
GPT-4를 이용해 질문에 대한 답변을 생성하고, 이에 대한 샘플들을 선별해서 사용해 fine-tuning
- 최소 1000개
- 데이터 품질에 따라서 성능을 좌우한다.
- 상용화의 경우는 라이센스 검토가 필요하다.