OpenAI는 최근 최신 세대 임베딩 모델 임베딩 v3의 출시를 발표했습니다. 그들은 이 모델이 더 높은 다국어 성능을 갖춘 가장 성능이 뛰어난 임베딩 모델이라고 주장합니다. 이 모델 배치는 더 작은 text-embeddings-3-small과 더 강력하고 더 큰 text-embeddings-3-large의 두 가지 유형으로 나뉩니다.
이러한 모델이 어떻게 설계되고 학습되는지에 대한 정보는 거의 공개되지 않으며 모델은 유료 API를 통해서만 액세스할 수 있습니다. 그렇다면 오픈소스 임베딩 모델이 많이 있습니다. 그러나 이러한 오픈소스 모델은 OpenAI 폐쇄소스 모델과 어떻게 비교됩니까?
이 기사에서는 이러한 새로운 모델의 성능을 오픈 소스 모델과 실증적으로 비교할 것입니다. 우리는 사용자의 쿼리를 기반으로 코퍼스에서 가장 관련성이 높은 문서를 찾는 것이 핵심 작업인 데이터 검색 워크플로를 구축할 계획입니다.
저희 코퍼스는 현재 검증 단계에 있는 유럽 인공지능법입니다. 이 코퍼스는 인공지능과 관련된 세계 최초의 법적 프레임워크이며 24개 언어로 제공된다는 점에서 독특합니다. 이를 통해 다양한 언어 배경에서 데이터 검색의 정확성을 비교할 수 있으며, 인공 지능의 문화 간 적용에 중요한 지원을 제공합니다.
다국어 텍스트 코퍼스를 사용하여 맞춤형 합성 질문/답변 데이터 세트를 만들고 이 데이터 세트를 사용하여 OpenAI와 최첨단 오픈 소스 임베딩 모델의 정확성을 비교할 계획입니다. 우리의 접근 방식이 다른 데이터 모음에 쉽게 적용될 수 있으므로 전체 코드를 공유하겠습니다.
먼저 사용자 정의 질문 및 답변(Q/A) 데이터 세트를 생성하여 시작할 수 있습니다. 이렇게 하면 데이터 세트가 다음과 같이 보장된다는 장점이 있습니다. MTEB와 같은 벤치마크 참조에서 발생할 수 있는 상황과 유사한 상황을 피하기 위해 모델 교육 편향 요인의 일부가 되지 않습니다. 또한 사용자 지정 데이터 세트를 생성하면 평가 프로세스를 특정 데이터 코퍼스에 맞게 조정할 수 있으며 이는 RAG(검색 증강 애플리케이션)와 같은 시나리오에 중요할 수 있습니다.
Llama Index 문서에 제안된 간단한 프로세스를 따르겠습니다. 먼저, 말뭉치를 덩어리로 나눕니다. 다음으로, 각 블록에 대해 LLM(대형 언어 모델)을 사용하여 일련의 합성 질문을 생성하여 답변이 해당 블록에 있는지 확인합니다.
Llama Index와 같은 LLM 데이터 프레임을 사용하여 이 전략을 구현하는 것은 아래 코드에 표시된 것처럼 매우 간단합니다.
from llama_index.readers.web import SimpleWebPageReader from llama_index.core.node_parser import SentenceSplitter language = "EN" url_doc = "https://eur-lex.europa.eu/legal-content/"+language+"/TXT/HTML/?uri=CELEX:52021PC0206" documents = SimpleWebPageReader(html_to_text=True).load_data([url_doc]) parser = SentenceSplitter(chunk_size=1000) nodes = parser.get_nodes_from_documents(documents, show_progress=True)
말뭉치는 EU 인공지능법의 영어 버전으로, 이 공식 URL을 사용하여 웹에서 직접 얻을 수 있습니다. 최종 버전은 아직 모든 유럽 언어로 제공되지 않으므로 이 문서에서는 2021년 4월의 초안 버전을 사용합니다. 따라서 우리가 선택한 버전은 URL의 언어를 다른 23개의 공식 EU 언어 중 하나로 대체하여 다양한 언어(불가리아어용 BG, 스페인어용 ES, 체코어용 CS 등)로 텍스트를 검색할 수 있습니다.
SentenceSplitter 개체를 사용하여 문서를 각각 1000개의 토큰 청크로 분할합니다. 영어의 경우 약 100개의 청크가 생성됩니다. 그런 다음 각 청크는 다음 프롬프트(Llama Index 라이브러리에서 제안된 기본 프롬프트)에 대한 컨텍스트로 제공됩니다.
prompts={} prompts["EN"] = """\ Context information is below. --------------------- {context_str} --------------------- Given the context information and not prior knowledge, generate only questions based on the below query. You are a Teacher/ Professor. Your task is to setup {num_questions_per_chunk} questions for an upcoming quiz/examination. The questions should be diverse in nature across the document. Restrict the questions to the context information provided." """
이 프롬프트는 각 청크에 대해 생성할 질문 수와 함께 문서 청크에 대한 질문을 생성할 수 있습니다. 데이터 청크는 "num_questions_per_chunk" 매개변수로 전달되며 이를 2로 설정합니다. 그런 다음 Llama Index 라이브러리에서 generate_qa_embedding_pairs를 호출하여 질문을 생성할 수 있습니다.
from llama_index.llms import OpenAI from llama_index.legacy.finetuning import generate_qa_embedding_pairs qa_dataset = generate_qa_embedding_pairs(llm=OpenAI(model="gpt-3.5-turbo-0125",additional_kwargs={'seed':42}),nodes=nodes,qa_generate_prompt_tmpl = prompts[language],num_questions_per_chunk=2 )
我们依靠OpenAI的GPT-3.5-turbo-0125来完成这项任务,结果对象' qa_dataset '包含问题和答案(块)对。作为生成问题的示例,以下是前两个问题的结果(其中“答案”是文本的第一部分):
- What are the main objectives of the proposal for a Regulation laying down harmonised rules on artificial intelligence (Artificial Intelligence Act) according to the explanatory memorandum?
- How does the proposal for a Regulation on artificial intelligence aim to address the risks associated with the use of AI while promoting the uptake of AI in the European Union, as outlined in the context information?
评估函数也是遵循Llama Index文档:首先所有答案(文档块)的嵌入都存储在VectorStoreIndex中,以便有效检索。然后评估函数循环遍历所有查询,检索前k个最相似的文档,并根据MRR (Mean Reciprocal Rank)评估检索的准确性,代码如下:
def evaluate(dataset, embed_model, insert_batch_size=1000, top_k=5):# Get corpus, queries, and relevant documents from the qa_dataset objectcorpus = dataset.corpusqueries = dataset.queriesrelevant_docs = dataset.relevant_docs # Create TextNode objects for each document in the corpus and create a VectorStoreIndex to efficiently store and retrieve embeddingsnodes = [TextNode(id_=id_, text=text) for id_, text in corpus.items()]index = VectorStoreIndex(nodes, embed_model=embed_model, insert_batch_size=insert_batch_size)retriever = index.as_retriever(similarity_top_k=top_k) # Prepare to collect evaluation resultseval_results = [] # Iterate over each query in the dataset to evaluate retrieval performancefor query_id, query in tqdm(queries.items()):# Retrieve the top_k most similar documents for the current query and extract the IDs of the retrieved documentsretrieved_nodes = retriever.retrieve(query)retrieved_ids = [node.node.node_id for node in retrieved_nodes] # Check if the expected document was among the retrieved documentsexpected_id = relevant_docs[query_id][0]is_hit = expected_id in retrieved_ids # assume 1 relevant doc per query # Calculate the Mean Reciprocal Rank (MRR) and append to resultsif is_hit:rank = retrieved_ids.index(expected_id) + 1mrr = 1 / rankelse:mrr = 0eval_results.append(mrr) # Return the average MRR across all queries as the final evaluation metricreturn np.average(eval_results)
嵌入模型通过' embed_model '参数传递给评估函数,对于OpenAI模型,该参数是一个用模型名称和模型维度初始化的OpenAIEmbedding对象。
from llama_index.embeddings.openai import OpenAIEmbedding embed_model = OpenAIEmbedding(model=model_spec['model_name'],dimensinotallow=model_spec['dimensions'])
dimensions参数可以缩短嵌入(即从序列的末尾删除一些数字),而不会失去嵌入的概念表示属性。OpenAI在他们的公告中建议,在MTEB基准测试中,嵌入可以缩短到256大小,同时仍然优于未缩短的text-embedding-ada-002嵌入(大小为1536)。
我们在四种不同的嵌入模型上运行评估函数:
两个版本的text-embedding-3-large:一个具有最低可能维度(256),另一个具有最高可能维度(3072)。它们被称为“OAI-large-256”和“OAI-large-3072”。
OAI-small:text-embedding-3-small,维数为1536。
OAI-ada-002:传统的文本嵌入text-embedding-ada-002,维度为1536。
每个模型在四种不同的语言上进行评估:英语(EN),法语(FR),捷克语(CS)和匈牙利语(HU),分别涵盖日耳曼语,罗曼语,斯拉夫语和乌拉尔语的例子。
embeddings_model_spec = { } embeddings_model_spec['OAI-Large-256']={'model_name':'text-embedding-3-large','dimensions':256} embeddings_model_spec['OAI-Large-3072']={'model_name':'text-embedding-3-large','dimensions':3072} embeddings_model_spec['OAI-Small']={'model_name':'text-embedding-3-small','dimensions':1536} embeddings_model_spec['OAI-ada-002']={'model_name':'text-embedding-ada-002','dimensions':None} results = [] languages = ["EN", "FR", "CS", "HU"] # Loop through all languages for language in languages: # Load datasetfile_name=language+"_dataset.json"qa_dataset = EmbeddingQAFinetuneDataset.from_json(file_name) # Loop through all modelsfor model_name, model_spec in embeddings_model_spec.items(): # Get modelembed_model = OpenAIEmbedding(model=model_spec['model_name'],dimensinotallow=model_spec['dimensions']) # Assess embedding score (in terms of MRR)score = evaluate(qa_dataset, embed_model) results.append([language, model_name, score]) df_results = pd.DataFrame(results, columns = ["Language" ,"Embedding model", "MRR"])
MRR精度如下:
嵌入尺寸越大,性能越好。
围绕嵌入的开源研究也是非常活跃的,Hugging Face 的 MTEB leaderboard会经常发布最新的嵌入模型。
为了在本文中进行比较,我们选择了一组最近发表的四个嵌入模型(2024)。选择的标准是他们在MTEB排行榜上的平均得分和他们处理多语言数据的能力。所选模型的主要特性摘要如下。
e5-mistral-7b-instruct:微软的这个E5嵌入模型是从Mistral-7B-v0.1初始化的,并在多语言混合数据集上进行微调。模型在MTEB排行榜上表现最好,但也是迄今为止最大的(14GB)。
multilingual-e5-large-instruct(ML-E5-large):微软的另一个E5模型,可以更好地处理多语言数据。它从xlm-roberta-large初始化,并在多语言数据集的混合上进行训练。它比E5-Mistral小得多(10倍),上下文大小也小得多(514)。
BGE-M3:该模型由北京人工智能研究院设计,是他们最先进的多语言数据嵌入模型,支持100多种工作语言。截至2024年2月22日,它还没有进入MTEB排行榜。
nomic-embed-text-v1 (Nomic- embed):该模型由Nomic设计,其性能优于OpenAI Ada-002和text-embedding-3-small,而且大小仅为0.55GB。该模型是第一个完全可复制和可审计的(开放数据和开源训练代码)的模型。
用于评估这些开源模型的代码类似于用于OpenAI模型的代码。主要的变化在于模型参数:
embeddings_model_spec = { } embeddings_model_spec['E5-mistral-7b']={'model_name':'intfloat/e5-mistral-7b-instruct','max_length':32768, 'pooling_type':'last_token', 'normalize': True, 'batch_size':1, 'kwargs': {'load_in_4bit':True, 'bnb_4bit_compute_dtype':torch.float16}} embeddings_model_spec['ML-E5-large']={'model_name':'intfloat/multilingual-e5-large','max_length':512, 'pooling_type':'mean', 'normalize': True, 'batch_size':1, 'kwargs': {'device_map': 'cuda', 'torch_dtype':torch.float16}} embeddings_model_spec['BGE-M3']={'model_name':'BAAI/bge-m3','max_length':8192, 'pooling_type':'cls', 'normalize': True, 'batch_size':1, 'kwargs': {'device_map': 'cuda', 'torch_dtype':torch.float16}} embeddings_model_spec['Nomic-Embed']={'model_name':'nomic-ai/nomic-embed-text-v1','max_length':8192, 'pooling_type':'mean', 'normalize': True, 'batch_size':1, 'kwargs': {'device_map': 'cuda', 'trust_remote_code' : True}} results = [] languages = ["EN", "FR", "CS", "HU"] # Loop through all models for model_name, model_spec in embeddings_model_spec.items(): print("Processing model : "+str(model_spec)) # Get modeltokenizer = AutoTokenizer.from_pretrained(model_spec['model_name'])embed_model = AutoModel.from_pretrained(model_spec['model_name'], **model_spec['kwargs']) if model_name=="Nomic-Embed":embed_model.to('cuda') # Loop through all languagesfor language in languages: # Load datasetfile_name=language+"_dataset.json"qa_dataset = EmbeddingQAFinetuneDataset.from_json(file_name) start_time_assessment=time.time() # Assess embedding score (in terms of hit rate at k=5)score = evaluate(qa_dataset, tokenizer, embed_model, model_spec['normalize'], model_spec['max_length'], model_spec['pooling_type']) # Get duration of score assessmentduration_assessment = time.time()-start_time_assessment results.append([language, model_name, score, duration_assessment]) df_results = pd.DataFrame(results, columns = ["Language" ,"Embedding model", "MRR", "Duration"])
결과는 다음과 같습니다.
BGE-M3가 가장 좋은 성능을 보였으며, ML-E5-Large, E5-mistral-7b 및 Nomic-Embed가 그 뒤를 이었습니다. BGE-M3 모델은 아직 MTEB 순위에서 벤치마킹되지 않았으며, 우리의 결과는 다른 모델보다 순위가 더 높을 수 있음을 나타냅니다. BGE-M3는 다국어 데이터에 최적화되어 있지만 영어에서도 다른 모델보다 성능이 더 좋습니다.
오픈 소스 모델은 일반적으로 로컬에서 실행해야 하기 때문에 각 임베디드 모델의 처리 시간도 의도적으로 기록했습니다.
E5-mistral-7b는 다른 모델보다 10배 이상 크기 때문에 가장 느린 것은 보통입니다
모든 결과를 요약해 드립니다
최고 성능은 오픈 소스 모델을 사용하여 달성되었으며 BGE-M3 모델이 가장 잘 수행되었습니다. 이 모델은 OpenAI 모델과 동일한 컨텍스트 길이(8K)를 가지며 크기는 2.2GB입니다.
OpenAI의 대형(3072), 소형, ada 모델의 성능은 매우 유사합니다. 대형(256)의 임베딩 크기를 줄이면 성능 저하가 발생하며 OpenAI가 말하는 ada만큼 좋지 않습니다.
거의 모든 모델(ML-E5-large 제외)은 영어로 가장 잘 작동합니다. 체코어, 헝가리어 등의 언어에서는 훈련할 데이터가 적기 때문에 성능에 상당한 차이가 있습니다.
OpenAI 구독 비용을 지불해야 합니까, 아니면 오픈 소스 내장 모델을 호스팅해야 합니까?
OpenAI의 최근 가격 조정으로 API가 더욱 저렴해졌으며 현재 토큰 백만 개당 0.13달러의 비용이 듭니다. 매월 백만 개의 쿼리를 처리하는 경우(각 쿼리에 약 1,000개의 토큰이 포함된다고 가정) 비용은 약 $130입니다. 따라서 실제 요구 사항에 따라 오픈 소스 임베딩 모델을 호스팅할지 여부를 선택할 수 있습니다.
물론 가성비만 고려하는 것은 아닙니다. 대기 시간, 개인 정보 보호, 데이터 처리 워크플로 제어와 같은 다른 요소도 고려해야 할 수 있습니다. 오픈 소스 모델은 완전한 데이터 제어, 향상된 개인 정보 보호 및 사용자 정의라는 이점을 제공합니다.
지연 시간에 관해 말하자면, OpenAI의 API에도 지연 시간 문제가 있어 응답 시간이 길어지는 경우가 있으므로 OpenAI의 API가 반드시 가장 빠른 선택은 아닙니다.
결론적으로, 오픈 소스 모델과 OpenAI와 같은 독점 솔루션 중에서 선택하는 것은 간단한 대답이 아닙니다. 오픈 소스 임베딩은 성능과 데이터에 대한 더 강력한 제어를 결합하는 훌륭한 옵션을 제공합니다. 그리고 OpenAI의 제품은 특히 개인 정보 보호 문제가 부차적인 경우 편의성을 우선시하는 사람들에게 여전히 매력적일 수 있습니다.
이 기사의 코드: https://github.com/Yannael/multilingual-embeddings
위 내용은 데이터에 가장 적합한 임베딩 모델 선택: OpenAI와 오픈 소스 다국어 임베딩 비교 테스트의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!