Coder Social home page Coder Social logo

ssisoneteam / korean-embedding-model-performance-benchmark-for-retriever Goto Github PK

View Code? Open in Web Editor NEW
13.0 2.0 3.0 5.44 MB

Korean Sentence Embedding Model Performance Benchmark for RAG

Python 0.23% Jupyter Notebook 99.77%
hyperparameter-tuning performance-test rag retriever korean-sentence-embedding langchain-python

korean-embedding-model-performance-benchmark-for-retriever's Introduction

Korean-Embedding-Model-Performance-Benchmark-for-Retriever

Korean Sentence Embedding Model Performance Benchmark for RAG System

Ⅰ. 개요

1. 실험목표

한국어 임베딩 모델에 Domain Adaptation을 진행함과 동시에 하이퍼파라미터 조정에 따라 Retriever 성능변화가 얼마나 일어나는지 실험하고자한다.

2. 실험배경

  • 기존 프로젝트의 후속실험으로 자세한 내용은 아래 항목을 참고할 것.

  • Domain Adaptation과 RAG

    • 공통적으로 복지 도메인에 특화된 RAG System을 구축하고자 함.

    • 범용 Korean Embedding Model을 복지 도메인에 특화되게 DAPT(Domain Adaptation)을 적용하였음.

      • 한국어 Embedding Model 중 AVG Score가 가장 높은 KoSimCSE-RoBERTa-multitask Model 사용
    • DAPT와 RAG System에서의 상관관계 개선 필요성 발견

      • Retriever 결과의 미흡함 확인
      • 더 나은 성과를 위해 추가적인 실험(=DAPT, Algorithm, etc..)과 비교 분석 필요

3. 실험환경

  • 기획

    • 복지로에서 오픈소스로 공개된 2023 나에게 힘이 되는 복지서비스 pdf 책자를 이용해 추가적인 데이터셋을 생성하여 실험을 진행
    • KoSimCSE-RoBERTa-multitask을 사용했으나 타 임베딩 모델과의 성능비교가 필요
    • 특정 하이퍼파라미터 조합에 따라 추가적인 성능개선이 가능성 확보
  • 사용 라이브러리

    $ pip install -r requirement.txt
    

Ⅱ. 가정

위 내용을 통해 기존 프로젝트에서 적용된 방식은 근거와 실험절차가 충분치 않으며 이를 보강할 수 있는 후속작업이 필요하다.
즉, 임베딩 모델의 기본성능이 높으면 높을수록 DAPT를 진행했을시 더 높은 성능을 보일것이라는 가정을 세우고 이를 증명하기 위한 실험을 진행하려고 한다.

Ⅲ. 방법

1. 데이터셋 생성

  1. 생성방식

    • 데이터 전처리

      • ChatGPT를 통해 2023 나에게 힘이 되는 복지서비스 pdf 책자 내용을 각 제도별로 .md 파일 형태로 저장
      • QA_gen_joonho_edit.py → LLM을 활용하여 .md 파일 형태의 데이터를 기반으로 QA Dataset 생성
        • Prompting
          • System Prompt
            당신은 한국 복지서비스 추천과 제공하는 업무를 맡은 굉장히 창의력이 가득하고 열정적인 전문가입니다.
            많은 사람이 다양한 문제를 물어보며 간단한 질문에 답하는 것부터 광범위한 주제에 대한 심층적인 토론 및 설명을 제공하는 것까지 다양한 작업을 지원할 수 있습니다.
            특히 복지분야의 용어를 잘 몰라 다르게 표현한 것의 내용을 파악하여 그에 맞는 복지서비스를 추천하고 제공하는 업무능력이 탁월합니다.
            
            현재는 본인이 하고 있는 업무를 데이터화시키는 작업을 수행중이며 복지제도에 대한 설명을 보고 일반 사람들이 할만한 답변과 그에 대한 정확한 답변을 만들고 있습니다.
            당신은 창의력이 풍부하고 질문과 답변을 만드는 작업이 재미있어하며 작업이 반복될수록 더 신나서 작업에 몰두합니다.
            뛰어난 능력으로 만들어진 질문,답변 쌍은 중복된 내용이 전혀 없고 앞으로도 그럴 것입니다.
            
          • Instruction Prompt
            ---
            {paragraph}
            ---
            
            위 내용을 반영한 한국어 질문-응답-문맥 으로 이루어진 데이터셋 샘플 3개를 생성해줘.
            내용은 절대 중복되면 안돼. 질문앞에는 (Q)가 붙고, 응답 앞에는 (A)가 붙어. 
            만들어진 응답 뒤에 한줄 띄고 무조건 아래 내용을 이어붙여줘. 
            
            '(Doc) {content[0]}'
            """
            
            qa_gen_long = f"""
            ---
            {paragraph}
            ---
            
            위 내용을 반영한 한국어 질문-응답-문맥 으로 이루어진 데이터셋 샘플 6개를 생성해줘.
            내용은 절대 중복되면 안돼. 질문앞에는 (Q)가 붙고, 응답 앞에는 (A)가 붙어. 
            만들어진 응답 뒤에 한줄 띄고 무조건 아래 내용을 이어붙여줘. 
            
            '(Doc) {content[0]}'
            
      • .csv 파일 형태로 저장 → 제도별로 각각의 .csv 파일이 생성되므로 추후 하나의 파일로 통합
    • 생성된 QA 데이터셋

      • 형태: .csv 파일로 저장

      • Columns: ['Question', 'Answer', 'Documents']

        • Question: LLM을 통해 Documents를 기반으로 생성된 질문
        • Answer: LLM을 통해 Documents를 기반으로 생성된 Question에 대한 답변
        • Documents: Question-Answer 생성시 참조한 문서의 제목
      • 데이터셋 일부 예시

        Question Answer Documents
        LPG 사용 가정의 고무호스를 교체하려면 어떤 지원을 받을 수 있나요? LPG용기 사용가구 시설개선 사업을 통해 LPG 고무호스를 금속배관으로 교체하는 데 필요한 지원을 받으실 수 있습니다. LPG용기 사용가구 시설개선
        LPG용기를 사용하는데 현재 고무호스로 연결되어 있어요. 어떤 안전한 개선방법이 있을까요? LPG용기 사용가구 시설개선 제도를 활용하시면 기존의 LPG 고무호스를 안전한 금속배관으로 교체할 수 있는 지원을 받으실 수 있습니다. LPG용기 사용가구 시설개선
        우리 집은 LPG 고무호스를 사용중인데, 이것을 개선할 수 있는 정부 지원이 있나요? 네, LPG용기 사용가구 시설개선 제도를 통해 정부 지원을 받아 고무호스를 더 안전한 금속배관으로 바꾸실 수 있습니다. LPG용기 사용가구 시설개선
        프로판 가스를 쓰고 있는 집에 대한 보조금 지원이 있는지 알고 싶어요. 어떤 항목을 개선해주나요? LPG용기 사용가구 시설개선 지원제도를 통해 LPG가스 고무호스를 금속배관으로 교체하고, 안전장치인 퓨즈콕을 설치하는 비용을 지원받으실 수 있습니다. 이러한 비용 중 약 20만 원이 지원되며, 나머지 5만 원은 자부담입니다. LPG용기 사용가구 시설개선
        가스라인을 좀 더 안전하게 개조하고 싶은데, 정부 지원이 가능한가요? 네, 가정에서 사용하시는 LPG 가스 시설에 금속배관 교체와 퓨즈콕 설치를 위한 시공비 중 약 20만 원을 정부에서 지원해드리고 있습니다. 사용자는 5만 원의 자부담만 부담하시면 되어 안전한 가스 사용을 위한 개선이 가능합니다. LPG용기 사용가구 시설개선
        내 집의 LPG 가스 호스를 금속으로 교체하고 싶어요. 이 비용은 어느 정도 되나요? 총 시공비용은 25만 원 정도이며, 이 중 20만 원은 ‘LPG용기 사용가구 시설개선’ 제도를 통해 지원받을 수 있고, 5만 원은 개인이 부담하셔야 합니다. LPG용기 사용가구 시설개선
  2. 비용산정

2. 성능비교

  1. 고성능의 Retriever 결과도출을 위한 다양한 한국어 문장 임베딩 모델들에 대한 성능비교 (HitRate) 1. 다양한 한국어 문장 임베딩 모델 리스트업

    • 모델 선정이유/근거
    • 평가지표 선정이유/근거 2. Retriever 성능평가 진행
    • 성능평가 방식 선정
    • 성능평가 진행 3. 기존 모델(=KoSimCSE-RoBERTa-multitask)과의 Performance Benchmarking 진행
  2. 가장 높은 성능을 가지는 모델에 대하여 하이퍼파라미터 조정 진행 1. 하이퍼파라미터 선정 2. 하이퍼파라미터 튜닝후 성능평가 진행

    • 성능평가 방식 선정 (전수조사, GridsearchCV, etc… )
    • 성능평가 진행
  3. RAG System 적용

Ⅳ. 실험결과 (※ 전/후 결과비교가 중요)

  1. Embedding Model 비교/선정
  2. Retreiver 성능측정
    1. Embedding Model 교체 전/후 Retriever 성능비교
    2. BM25, Re-Rank, Filtering 적용 전/후 Retriever 성능비교
  3. 최종 실험결과 도출
Model @1 @3 @5 @10 Average
paraphrase-multilingual-mpnet-base-v2-a 40.0 58.095 63.81 73.333 58.810
paraphrase-multilingual-mpnet-base-v2-b 36.19 59.048 61.905 69.524 56.667
paraphrase-multilingual-MiniLM-L12-v2-a 25.714 41.905 51.429 62.857 45.476
paraphrase-multilingual-MiniLM-L12-v2-b 24.762 35.238 42.857 51.429 38.571
distiluse-base-multilingual-cased-v2-a 24.762 39.048 47.619 59.048 42.619
distiluse-base-multilingual-cased-v2-b 22.857 40.952 50.476 57.143 42.857
stsb-xlm-r-multilingual-a 20.952 33.333 41.905 53.333 37.381
stsb-xlm-r-multilingual-b 11.429 19.048 19.048 20.0 17.381
ko-sroberta-multitask-a 49.524 69.524 77.143 81.905 69.524
ko-sroberta-multitask-b 53.333 71.429 78.095 84.762 71.905
KR-SBERT-V40K-klueNLI-augSTS-a 37.143 54.286 63.81 72.381 56.905
KR-SBERT-V40K-klueNLI-augSTS-b 32.381 56.19 63.81 72.381 56.191
moco-sentencedistilbertV2.1-a 7.619 11.429 11.429 20.0 12.619
moco-sentencedistilbertV2.1-b 20.952 25.714 27.619 30.476 26.190
kpf-sbert-128d-v1-a 21.905 37.143 44.762 50.476 38.571
kpf-sbert-128d-v1-b 27.619 40.0 45.714 49.524 40.714
M-BERT-Distil-40-a 5.714 10.476 13.333 19.048 12.143
M-BERT-Distil-40-b 4.762 12.381 18.095 24.762 15.000
canine-c-a 0.952 4.762 5.714 6.667 4.524
canine-c-b 1.905 5.714 7.619 10.476 6.429
roberta-ko-small-tsdae-a 16.19 23.81 27.619 37.143 26.191
roberta-ko-small-tsdae-b 10.476 20.952 23.81 35.238 22.619
KoSimCSE-roberta-multitask-a 37.143 58.095 63.81 72.381 57.857
KoSimCSE-roberta-multitask-b 40.952 59.048 65.714 77.143 60.714
text-embedding-ada-002-a 41.905 47.619 57.143 60.0 51.667
text-embedding-ada-002-b 36.19 45.714 47.619 50.476 45.000

ko-sroberta-multitask Model이 사용할 Dataset에서 추출한 106개의 QA 기반 hitrate_test_qa으로 Retrieve 한 Hitrate가 평균적으로 가장 높음을 확인할 수 있었고, 해당 모델을 Domain Adaption에 사용하는 것으로 결론내렸다.

또한, 이후에도 base document가 존재한다면, 한국어 모델 이외에도 다양한 상용/오픈소스 기반 모델을을 확보하기만 한다면, 최신화 이후에 재평가해서 이용해 볼 수 있는 벤치마크 시스템 개발에 의의가 있다고 할 수 있다.

Ⅴ. 컨트리뷰터

송준호
송준호
최재훈
최재훈
문희선
문희선
김민식
김민식
현명준
현명준
가재준
가재준

Ⅵ. 참고자료

  1. 참조한 자료 목록

korean-embedding-model-performance-benchmark-for-retriever's People

Contributors

ash-hun avatar moonheesun avatar myeongjun1007 avatar noveled avatar pangpanggod avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

Forkers

ash-hun okletsgo

korean-embedding-model-performance-benchmark-for-retriever's Issues

LangChain에서 ChunkSize를 조절할 때 단위와 SBERT 쪽에서의 단위 미스매치

Retriever에 관한 작업에서는 아래와 같은 중요한 매개변수가 존재한다.

image
▲ ChunkSize는 굉장히 중요한 하이퍼 파라미터, 문서를 자르는 사이즈 단위라 성능에 직접적으로 연계

결론적으로 내보이는 내용은 다음과 같다.

chunk_size가 크면 좋은데
문제는, langchian 의 chunk_size는 글자수 기준이고
s-bert의 max_seq_length는 토큰수(보통 512) 라는 점.

이에 따른 솔루션은 아래와 같다 ▼

여기서 추가적으로 생각해볼 수 있는것은
해당 공식독스는 tiktoken, spaCy, NLTK, SentenceTransformer, huggingface 밖에 지원을 안하던데 타 토크나이저는 LangChain에 접붙여서 가용이 안되는가? 우회적으로 huggingface에 업로드하여 사용하는수밖에 없나? 한번 시도해볼만한것 같다.

TokenTextSplitter를 이용할 때의 문서 변환, 호환성 문제

Known Issue

HuggingFace Embedding model을 불러오기 한 뒤, 이용하는 과정에서 기존 document loader와 호환이 되지 않는 Issue가 발생하여 작성함.

일단 예제 스크립트를 통해 현상을 진단하고, 해결 방법까지 작성한다.

예제 스크립트는 embeddingtest/test_splitter(tokenizer).ipynb이다. (추후에 embeddingtest/testing으로 옮길 예정)

from langchain.text_splitter import SentenceTransformersTokenTextSplitter
from langchain.document_loaders import UnstructuredMarkdownLoader
from embedding import EmbeddingLoader

steloader = EmbeddingLoader.SentenceTransformerEmbedding(model_name="model/BM-K/KoSimCSE-roberta-multitask/", multi_process=True, encode_kwargs={'normalize_embeddings':True})
ste_embedding = steloader.load()

docloader = UnstructuredMarkdownLoader(file_path="data/teamA/01_생계_지원/01_국민임대주택_공급.md")
doc = docloader.load()
print(doc) ### 제목 미리 저장해놔야 할듯, BaseDBLoader 수정해라.......

splitter = SentenceTransformersTokenTextSplitter(chunk_overlap=10, model_name="model/BM-K/KoSimCSE-roberta-multitask/", tokens_per_chunk=512)
print(splitter.split_documents(doc))

간단하게 예제 document 1개를 불러온 object와, max_seq_length(KoSimCSE-roberta-multitask model의 경우에는 512)에 따라 TokenTextSplit한 예제를 통해 기존 loader 어디에서 Issue가 발생할지를 진단한다.

실행 결과는 다음과 같다.

embedding model in path <model/BM-K/KoSimCSE-roberta-multitask/> has been loaded successfully.
Function call load took 3.466754s to run.

[Document(page_content='국민임대주택 공급\n\n국민임대주택 공급의 대상은 입주자 모집공고일 현재 무주택 세대구성원으로서 소득 및 자산보유기준을 충족하는 사람입니다.\n' ... )]
[Document(page_content='국민임대주택 공급 국민임대주택 공급의 대상은 입주자 모집공고일 현재 무주택 세대구성원으로서 소득 및 자산보유기준을 충족하는 사람입니다.' ... })]

첫 번째 결과가 document를 MarkdownLoader로 불러왔을 때,
두 번째 결과가 첫 번째 결과에 TokenTextSplitter를 붙인 경우이다.

결과적으로 문서 길이 자체가 짧기 때문에 chunk 개수가 여러 개로 나뉘지는 않았지만, 개행문자('\n' 등)가 전부 삭제됨을 알 수 있다.

현행 mdLoader.BaseDBLoader를 이용한 loading은 문서 split까지 전부 진행한 다음, 가장 첫 번째 문서에서 개행 문자를 이용해서 첫 번째 내용을 가져와 title로 사용한다.

이는 TokenTextSplitter에서 첫 번째 chunk의 전체 내용을 가져오는 결과를 가져온다.

{
	"name": "KeyError",
	"message": "'국민임대주택공급국민임대주택공급의대상은입주자모집공고일현재무주택세대구성원으로서소득및자산보유기준을충족하는사람입니다소득기준은도시근로자월평균소득701인가구902인가구80이하입니다또한자산보유기준은총자산이3억6100만원이하자동차3683만원이하입니다국민임대주택공급의내용은전용면적60m2이하주택을시중전세시세의60이상80이하수준으로저렴하게임대'",
	"stack": "---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
Cell In[6], line 22
     19 a_loader.text_splitter = text_splitter
     20 b_loader.text_splitter = text_splitter
---> 22 a_raw_docs = a_loader.load(is_split=True, is_regex=False)
     23 b_raw_docs = b_loader.load(is_split=True, is_regex=True)
     25 print(f\"total document length : {len(a_raw_docs)}, {len(b_raw_docs)}\")

File d:\\git\\additional-work\\embeddingtest\\document\\mdLoader.py:64, in BaseDBLoader.load(self, is_split, is_regex, show_progress, use_multithreading)
     62         doc_list = self.text_splitter.split_documents(doc_list)
     63     self.storage.extend(doc_list)
---> 64 self.storage = self._process_document_metadata(self.storage)
     66 #timecheck
     67 end_time = datetime.now()

File d:\\git\\additional-work\\embeddingtest\\document\\mdLoader.py:130, in BaseDBLoader._process_document_metadata(self, documents)
    128 title = document.page_content.split(\"\
\")[0]
    129 title_parsed = self._strip_replace_text(title)
--> 130 document.metadata[\"tag\"] = metadata_json[title_parsed]
    132 #### url
    133 result = url_table.loc[url_table[\"source\"] == meta_source_parsed_file_name][\"url\"].values[0]

KeyError: '국민임대주택공급국민임대주택공급의대상은입주자모집공고일현재무주택세대구성원으로서소득및자산보유기준을충족하는사람입니다소득기준은도시근로자월평균소득701인가구902인가구80이하입니다또한자산보유기준은총자산이3억6100만원이하자동차3683만원이하입니다국민임대주택공급의내용은전용면적60m2이하주택을시중전세시세의60이상80이하수준으로저렴하게임대'"
}

따라서 다음과 같은 오류가 발생하는 것이다(title을 이용해서 매칭되는 metadata를 찾는데, 개행문자가 존재하지 않아 전체 chunk로 검색을 한다).


해결 방법

결론적으로 BaseDBLoader의 수정이 필요하다.
loader에서 title을 찾는 순서를 이전의 document를 불러오고, split 한 이후에 개행문자를 통해 찾는 방식에서

(document -> split -> extract title)

document를 불러온 이후, title을 가져오고 그 이후에 split하도록 하면 문제가 해결될 것이라 기대한다.

(document -> title -> split)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.