원래 MS MARCO 데이터셋은 microsoft에서 retrieval 학습을 위해서 고안된 데이터셋인데, question, natural language generation, passage ranking, keyphrase extraction, crawling, conversational search 데이터셋을 포함하는 데이터셋이라 크기도 크고 데이터 양이 많아요.
근데! Searching for Best Practices in Retrieval-Augmented Generation (EMNLP 2024) 논문을 읽다가 임베딩 evaluation에 사용한 데이터셋을 찾아버렸단 말이죠.
논문링크: https://aclanthology.org/2024.emnlp-main.981/
데이터셋 링크는 요기.
https://huggingface.co/datasets/namespace-Pt/msmarco
약 7천개로 이루어진 영문 데이터셋이고, query와 해당 쿼리에 대한 정보를 가지는 문장/문단 리스트로 구성된 페어 데이터셋이에요.
"query" : "honesty or integrity definition",
"positive" : [
'- honesty. n, pl-ties. 1. the condition of being honest. 2. sincerity or fairness. 3. virtue or respect.',
'- hence, a white lie in some cases, is a result of integrity. integrity is the value and morals of a individual in relation or in addition to honesty. honestly is frankness and as the other guy said, adherence to facts.'
]
살짝 이런식이죵. 근데 저는 영어가 아니라 한글 임베딩 모델을 테스트 해보고 싶었단 말이죠?
그래서 GPT-4o mini 모델을 사용해서 번역을 진행했습니다.
{"role":"system",
"content": "You are a helpful assistant.\
You will get query and chunk pair. You have to translate both into natural Korean.\
Ensure that the output sentence does not contain the escape string.\
Escape strings should be converted in to the corresponding string.\
If there are broken encoding string, be sure to restore and print.\
And the ouput should be in the form of {\"Query\": [translated query],\"Chunk\": [translated chunk]}"},
프롬프트는 다음과 같이 system 프롬프트 설정해서 사용하고, query와 positives를 같이 input으로 사용했답니다.
총 데이터 개수는 6,980개였네요~
{
"trn_query": "포토샵 색상 오버레이",
"trn_positive": [
"- 포토샵: 색상 오버레이. 제 햇빛 보정 튜토리얼에서,\
사진에 색상을 추가하면서 동시에 약간의 향상을 주는 방법을 보여드렸습니다.\
하지만 때때로 사진은 약간의 색상이 필요할 수 있지만,\
그 추가적인 향상이 필요하지 않을 수도 있습니다.\
또는 사소한 밝기 조정이 필요할 수도 있습니다.\
이 간단한 색상 오버레이는 사진을 과도하게 편집한 것처럼 보이지 않으면서 색상을 추가하는 훌륭한 방법입니다.\
또는 흑백 사진에 약간의 생명을 불어넣는 데 사용할 수 있습니다.\
참고: 이 방법은 포토샵에서와 마찬가지로 엘리먼트에서도 동일하게 작동합니다."
]
},
데이터 예시인데 가로스크롤 때문에 보기가 불편해서 줄바꿈만 좀 추가해봤어요.
그럼 retrieval을 통해서 임베딩 모델의 성능평가를 해봐야겠죠?
huggingface에서 불러올 수 있는 모델들이랑, GPT embedding model을 비교해봤어요.
사용한 임베딩 모델들은 다음과 같아요. 벡터 검색에는 faiss 모델을 사용했습니다!
한글(번역) 임베딩 데이터셋 평가 모델
from huggingface: BAAI/bge-m3, upskyy/bge-m3-korean, dragonkue/BGE-m3-ko, jinaai/jina-embeddings-v3, bespin-global/klue-sroberta-base-continue-learning-by-mnr, intfloat/multilingual-e5-large-instruct, sentence-transformers/paraphrase-multilingual-mpnet-base-v2
openAI: text-embedding-3-small, text-embedding-3-large
Keyword based: Okapi BM25
평가지표: 데이터 임베딩 시간 (약 7,000개), 파라미터 수, HitRate, Recall, MAP(Mean Average Precision), NDCG(Normalized Discounted Cumulative Gain), MRR (Mean Reciprocal Rank)
환경은 Colab A100 GPU, 데이터 임베딩 batch size는 모두 32로 설정하고 실험했습니다!
Model | HitRate @1(5) |
Recall @1(5) |
MAP @1(5) |
NDCG @1(5) |
MRR @1(5) |
Time(sec.) | # of Params |
intfloat/multilingual-e5-large-instruct | 0.795 (0.942) |
0.795 (0.942) |
0.795 (0.891) |
0.795 (0.900) |
0.795 (0.856) |
60.95 | 560M |
sentence-transformers/paraphrase-multilingual-mpnet-base-v2 | 0.533 (0.707) |
0.533 (0.707) |
0.533 (0.622) |
0.533 (0.641) |
0.533 (0.601) |
19.24 | 278M |
bespin-global/klue-sroberta-base-continue-learning-by-mnr | 0.711 (0.873) |
0.711 (0.873) |
0.711 (0.873) |
0.711 (0.819) |
0.711 (0.777) |
18.58 | 110M |
jinaai/jina-embeddings-v3 | 0.910 (0.979) |
0.910 (0.979) |
0.910 (0.977) |
0.910 (0.973) |
0.910 (0.940) |
9.99 | 572M |
BAAI/bge-m3 | 0.912 (0.976) |
0.912 (0.976) |
0.912 (0.977) |
0.912 (0.972) |
0.912 (0.939) |
60.97 | 568M |
upskyy/bge-m3-korean | 0.898 (0.971) |
0.898 (0.971) |
0.898 (0.966) |
0.898 (0.963) |
0.898 (0.930) |
61.02 | 568M |
dragonkue/BGE-m3-ko | 0.908 (0.975) |
0.908 (0.975) |
0.908 (0.973) |
0.908 (0.969) |
0.908 (0.936) |
61.00 | 568M |
OpenAI/text-embedding-3-small | 0.785 (0.907) |
0.785 (0.907) |
0.785 (0.865) |
0.785 (0.872) |
0.785 (0.835) |
- | - |
OpenAI/ text-embedding-3-large | 0.877 (0.964) |
0.877 (0.964) |
0.877 (0.950) |
0.877 (0.949) |
0.877 (0.914) |
- | - |
Okapi BM25 | 0.509 (0.649) |
0.509 (0.649) |
0.509 (0.581) |
0.509 (0.597) |
0.509 (0.563) |
- | - |
Top K가 1인 경우는 쿼리별로 첫번째에 정답 문장을 검색하면 지표가 1 아니면 0이기 때문에 모든 지표의 값이 다 똑같아요. 그리고 OpenAI는 API로 임베딩을 가져오기 때문에 같은 환경세팅이 아니라서 시간과 파라미터 수는 기입하지 않았어요.
한글로 번역한 평가는 jina-embedding-v3와 bge-m3 기반 모델들이 엄청 좋네요. 물론 embedding 시간을 보면 jina embedding 압승..!
multi-lingual인데 이렇게 좋은 성능을 낸다니 정말 놀랍죠? OpenAI 임베딩 모델들이 생각보다 성능이 안나온게 좀 의외인 포인트..
그럼 이제 번역 전에 원본 데이터셋도 평가해 봐야겠죠?
영문 데이터셋 평가 모델
from huggingface: BAAI/bge-m3, jinaai/jina-embeddings-v3, sentence-transformers/paraphrase-multilingual-mpnet-base-v2, intfloat/multilingual-e5-large-instruct
openAI: text-embedding-3-small, text-embedding-3-large
Keyword based: Okapi BM25
Model | HitRate @1(5) |
Recall @1(5) |
MAP @1(5) |
NDCG @1(5) |
MRR @1(5) |
Time(sec.) | # of Params |
BAAI/bge-m3 | 0.767 (0.903) |
0.767 (0.903) |
0.767 (0.865) |
0.767 (0.870) |
0.767 (0.822) |
52.50 | 568M |
jinaai/jina-embeddings-v3 | 0.752 (0.887) |
0.752 (0.887) |
0.752 (0.850) |
0.752 (0.855) |
0.752 (0.807) |
10.02 | 572M |
sentence-transformers/paraphrase-multilingual-mpnet-base-v2 | 0.492 (0.679) |
0.492 (0.679) |
0.492 (0.595) |
0.492 (0.613) |
0.492 (0.565) |
16.78 | 278M |
intfloat/multilingual-e5-large-instruct | 0.745 (0.892) |
0.745 (0.892) |
0.745 (0.848) |
0.745 (0.855) |
0.745 (0.805) |
53.02 | 560M |
OpenAI/text-embedding-3-small | 0.294 (0.442) |
0.294 (0.442) |
0.294 (0.365) |
0.294 (0.383) |
0.294 (0.350) |
- | - |
OpenAI/ text-embedding-3-large | 0.715 (0.866) |
0.715 (0.866) |
0.715 (0.817) |
0.715 (0.825) |
0.715 (0.775) |
- | - |
Okapi BM25 | 0.033 (0.044) |
0.033 (0.044) |
0.033 (0.039) |
0.033 (0.040) |
0.033 (0.037) |
- | - |
Colab VRAM이 작은 관계로 MTEB SOTA 모델들은 비교를 못해씁니다...
영어에서는 bge-m3가 압도적이었네요! 그럼에도 역시 jina-embedding의 속도는 대단하죠?
한글 대비 영어 임베딩 평가에서 모델들이 더 어려워하는 걸 볼 수 있었는데요, 아무래도 번역과정에서 쉬운 말로 번역이 된 건 아닐까 싶네요. 하지만, 임베딩을 평가할 수 있는 데이터셋을 구축해두었으니 오케이 아닐까요?!
언젠가(아마도 곧..) 이 데이터셋을 쓸 날이 오겠죠?