Giter Site home page Giter Site logo

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

View Code? Open in Web Editor NEW
12.0 12.0 3.0 5.44 MB

Korean Sentence Embedding Model Performance Benchmark for RAG

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

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

Watchers

 avatar  avatar

Forkers

ash-hun okletsgo

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

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)

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

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

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

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

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

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

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

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.