介紹
您對最先進的檢索增強型 LLM「bge-large-en-v1.5」感興趣嗎?歡迎加入我們這篇部落格,深入探索此模型。您將了解嵌入模型的作用及其實際應用。我們將逐步引導您如何在程式碼中部署「bge-large-en-v1.5」、對其進行微調,並與 LLM API 無縫整合。準備好解鎖嵌入模型與 LLM 交織的新可能性吧!
什麼是 bge-large-en-v1.5?
簡而言之,bge-large-en-v1.5 是 BAAI 創造的開源嵌入模型。
具體來說,「bge-large-en-v1.5」中的「bge」代表「BAAI General Embedding」。BAAI 在 GitHub 上也稱為「FlagEmbedding」,是一家致力於人工智慧研究與開發的私營非營利組織。BAAI 專注於檢索增強型大型語言模型(LLM),並已推出多個相關專案,包括長上下文 LLM(Activation Beacon)、LM 微調(LM-Cocktail)、密集檢索(BGE-M3、LLM Embedder、BGE Embedding)、重排序模型(BGE Reranker)以及基準測試(C-MTEB)。Bge-large-en-v1.5 屬於 BGE Embedding 模型系列,專門為密集檢索用途而開發。

用於密集檢索的嵌入模型有什麼作用?

用於密集檢索的嵌入模型將文本資料轉換為密集的語義表示,以捕捉輸入的意義和上下文。這些密集表示由密集檢索器使用,以高效地檢索相關資訊。以下說明其運作方式及一些範例:
將文本轉換為密集表示
嵌入模型將句子、段落或整個文檔作為輸入,並將其轉換為固定長度的向量(嵌入)。這些向量編碼文本的語義資訊,使其能夠超越簡單的關鍵字匹配,進行更細緻的理解。
LLM 通常將嵌入模型納入其架構中。例如,BERT 使用嵌入技術來表示詞彙和輸入序列,然後再透過其 Transformer 層進行處理。LLM 受益於嵌入模型,因為它們能夠捕捉語義關係和上下文細微差別,這對於在對話生成或機器翻譯等任務中生成連貫且符合上下文的回應至關重要。
密集檢索器的角色
密集檢索器利用這些嵌入來執行檢索任務。與依賴精確關鍵字匹配或索引的傳統稀疏檢索方法不同,密集檢索器直接計算查詢嵌入與文檔嵌入之間的相似度分數。這種方法可以在各種長度的文本輸入(從短句到長篇文檔)上實現更準確的檢索。
應用範例
在資訊檢索任務中,例如搜尋引擎或問答系統,這些密集表示能夠高效且準確地檢索相關文檔或段落。
例如,像「COVID-19 有哪些症狀?」這樣的查詢可以被轉換為嵌入向量。同樣,討論 COVID-19 症狀的文檔也會被轉換為嵌入。透過比較查詢嵌入與文檔嵌入之間的相似度(使用餘弦相似度等技術),可以快速識別並排序最相關的文檔。
另一個範例是推薦系統。在這種情況下,嵌入通過了解用戶偏好和內容相似性來幫助推薦產品、文章或影片。
總之,用於密集檢索的嵌入模型,搭配密集檢索器,在現代 AI 應用中扮演關鍵角色,負責將文本轉換為有意義的表示,並基於語義相似性高效檢索相關資訊。
如何在程式碼中使用 bge-large-en-v1.5?
在 Langchain 中使用 bge-large-en-v1.5
您可以像這樣在 langchain 中使用 bge:
from langchain.embeddings import HuggingFaceBgeEmbeddings
model_name = "BAAI/bge-large-en-v1.5"
model_kwargs = {'device': 'cuda'}
encode_kwargs = {'normalize_embeddings': True} # 設為 True 以計算餘弦相似度
model = HuggingFaceBgeEmbeddings(
model_name=model_name,
model_kwargs=model_kwargs,
encode_kwargs=encode_kwargs,
query_instruction="Generate a representation for this sentence to be used for retrieving relevant articles:"
)
model.query_instruction = "Generate a representation for this sentence to be used for retrieving relevant articles:"
在 Huggingface Transformers 中使用 bge-large-en-v1.5
使用 transformers 套件,您可以像這樣使用模型:首先,將輸入傳入 transformer 模型,然後選擇第一個 token(即 [CLS])的最後隱藏狀態作為句子嵌入。
from transformers import AutoTokenizer, AutoModel
import torch
# 我們想要句子嵌入的句子
sentences = ["Sample Data-1", "Sample Data-2"]
# 從 HuggingFace Hub 加載模型
tokenizer = AutoTokenizer.from_pretrained('BAAI/bge-large-en-v1.5')
model = AutoModel.from_pretrained('BAAI/bge-large-en-v1.5')
model.eval()
# 對句子進行分詞
encoded_input = tokenizer(sentences, padding=True, truncation=True, return_tensors='pt')
# 對於 s2p(短查詢到長段落)檢索任務,請為查詢添加指令(不要為段落添加指令)
# encoded_input = tokenizer([instruction + q for q in queries], padding=True, truncation=True, return_tensors='pt')
# 計算 token 嵌入
with torch.no_grad():
model_output = model(**encoded_input)
# 執行池化。在此情況下為 cls 池化。
sentence_embeddings = model_output[0][:, 0]
# 歸一化嵌入
sentence_embeddings = torch.nn.functional.normalize(sentence_embeddings, p=2, dim=1)
print("Sentence embeddings:", sentence_embeddings)
有關 bge 模型使用的更多資訊,您可以造訪 GitHub 上的 FlagEmbedding。
如何微調 bge-large-en-v1.5?
步驟 1 安裝
- 使用 pip 安裝:
pip install -U FlagEmbedding - 或者從原始碼安裝:克隆倉庫並進入目錄後執行
pip install . - 用於開發,請使用可編輯安裝:
pip install -e .
步驟 2 資料準備
- 訓練資料應為 JSON 格式,每行是一個字典,包含
query、pos(正例文本列表)和neg(負例文本列表)。 - 如果沒有負例文本,可以從語料庫中隨機抽樣。
步驟 3 挖掘困難負例
- 使用腳本挖掘困難負例以提升句子嵌入品質。
- 您可以按照以下指令挖掘困難負例:
python -m FlagEmbedding.baai_general_embedding.finetune.hn_mine \
--model_name_or_path BAAI/bge-base-en-v1.5 \
--input_file toy_finetune_data.jsonl \
--output_file toy_finetune_data_minedHN.jsonl \
--range_for_sampling 2-200 \
--negative_number 15 \
--use_gpu_for_searching
- 輸入檔案:一個 JSON 檔案,包含用於微調的資料,腳本會為每個查詢找出 top-k 文檔,然後從這些 top-k 結果中隨機選取負例,排除已提供的正例。
- 輸出檔案:存放已新增新採樣困難負例的 JSON 檔案,供後續微調過程使用。
- 負例數量:指定要收集的負樣本數量。
- 採樣範圍:定義從中抽取負樣本的範圍。例如,範圍 2–100 表示將從 top 2 到 top 100 的文檔中取得負例。將範圍擴大,例如到 60–300,則會考慮更廣泛的文檔集合,從而降低負例的挑選難度。
- 檢索池:腳本從中檢索文檔的來源。預設情況下,這是指輸入檔案中所有負例的集合,格式類似於預訓練資料。如果指定了特定的檢索池,腳本將使用此集合來尋找負例。
- 基於 GPU 的搜尋:一個選項,指示是否應使用 GPU 加速的 faiss-gpu 來提升負例檢索過程的效率。
步驟 4 訓練
torchrun --nproc_per_node {gpu 數量} \
-m FlagEmbedding.baai_general_embedding.finetune.run \
--output_dir {儲存模型的路徑} \
--model_name_or_path BAAI/bge-large-en-v1.5 \
--train_data ./toy_finetune_data.jsonl \
--learning_rate 1e-5 \
--fp16 \
--num_train_epochs 5 \
--per_device_train_batch_size {大批次大小;玩具資料設為 1} \
--dataloader_drop_last True \
--normlized True \
--temperature 0.02 \
--query_max_len 64 \
--passage_max_len 256 \
--train_group_size 2 \
--negatives_cross_device \
--logging_steps 10 \
--save_steps 1000 \
--query_instruction_for_retrieval ""
- 每個裝置的訓練批次大小:每個訓練批次中處理的樣本數量。通常,增加批次大小可以提升模型效能。您可以透過使用半精度訓練(
--fp16)、DeepSpeed 配置(--deepspeed ./df_config.json,其中df_config.json也可能寫成ds_config.json)以及梯度檢查點(--gradient_checkpointing)來增加此大小。 - 訓練組大小:決定訓練過程中每個查詢使用的總樣本數(包括正例和負例)。由於有一個保證的正例,此設定決定負例數量(計算方式為
train_group_size - 1)。請注意,此數字不應超過資料中neg列表內可用的負例數量。除了這些組內負例外,同一批次內的其他負例也會被納入微調過程。 - 跨裝置負例共享:啟用後可將負例分發到所有可用的 GPU,從而有效增加訓練中使用的負例總數。
- 學習率:選擇適合您特定模型的值。對於大型、基礎或小型模型,通常建議使用 1e-5、2e-5 或 3e-5 等數值。
- 溫度:影響相似度分數分佈的擴散程度。建議值範圍為 0.01 到 0.1。
- 最大查詢長度:查詢長度的上限,應與資料集中查詢的平均長度相符。
- 最大段落長度:段落長度的上限,根據資料中段落的平均長度設定。
- 檢索查詢指令:可選的指令,附加到每個查詢以用於檢索。如果不需要額外上下文,您可以將其設為空字串。
- 批次內負例使用:一個標誌,指示是否將同一批次中的段落視為訓練中的負例。預設為啟用(True)。
- 檢查點儲存間隔:根據完成的訓練步數定義儲存模型檢查點的頻率。
步驟 5 模型載入
一旦 BGE 模型微調完成,您可以按照此範例輕鬆載入它。如果您在微調階段為 --query_instruction_for_retrieval 超參數指定了唯一值,請確保相應地替換 query_instruction_for_retrieval。
步驟 6 模型載入
對於模型評估,您可以執行 FlagEmbedding 提供的這個腳本。
透過微調調整基礎的 bge 模型可以獲得更好的特定任務表現,但也可能導致模型在目標領域之外的有效性顯著下降(例如在 c-mteb 任務上的表現下降)。有關解決方案(使用 LM-Cocktail)以及微調過程的資訊,請查看 GitHub 上的「FlagEmbedding/examples/finetune」。
如何將 bge-large-en-v1.5 與 LLM API 整合?
將嵌入模型與 LLM 整合,可豐富 AI 的自然語言處理能力,實現更複雜的語義搜尋、上下文理解和個人化互動。此整合對於增強內容推薦、文檔聚類、異常偵測、跨語言處理和知識圖譜構建等任務特別有用。它還有助於先進的文本摘要和機器學習模型的特徵增強,從而改善情感分析和主題分類的表現。
步驟 1:設定環境
首先,確保您擁有必要的 Python 環境並安裝了所需的套件。
pip install openai
# 安裝其他必要套件,例如 requests、numpy 等
步驟 2:初始化 Novita AI API 客戶端
您已經提供了初始化 Novita AI API 客戶端的程式碼。以下供參考:
from openai import OpenAI
client = OpenAI(
base_url="https://api.novita.ai/v3/openai",
api_key="<您的 Novita AI API 金鑰>", # 請替換為您的實際 API 金鑰
)
model = "nousresearch/nous-hermes-llama2-13b"
步驟 3:取得嵌入模型
假設您有權使用 bge-large-en-v1.5 模型,您可以載入它。如果是 Hugging Face 模型,您可以使用 transformers 函式庫,如下所示:
from transformers import AutoModel, AutoTokenizer
tokenizer = AutoTokenizer.from_pretrained("BAAI/bge-large-en-v1.5")
model = AutoModel.from_pretrained("BAAI/bge-large-en-v1.5")
步驟 4:定義取得嵌入的函數
建立一個從 bge-large-en-v1.5 模型取得嵌入的函數。
def get_embeddings(text):
inputs = tokenizer(text, return_tensors="pt")
with torch.no_grad():
embeddings = model(**inputs)[0].mean(dim=1)
return embeddings.numpy()
步驟 5:與 Novita AI LLM API 整合
現在,將嵌入模型與 LLM API 整合,以增強 API 的回應或執行語義搜尋等任務。
def enhanced_llm_response(prompt):
# 從 LLM 取得初始回應
response = client.completions.create(
model=model,
prompt=prompt,
stream=True,
max_tokens=512,
)
# 處理回應(例如提取文本)
# 此處為實際回應處理的佔位符
response_text = next(response)['choices'][0]['text'].content
# 取得回應的嵌入
response_embeddings = get_embeddings(response_text)
# 在這裡,您可以將嵌入用於各種目的,
# 例如語義搜尋、過濾等。
return response_text, response_embeddings
步驟 6:使用增強函數
現在您可以使用 enhanced_llm_response 函數從 LLM 取得回應,並使用嵌入模型進行處理。
prompt = "一個好奇用戶與人工智慧助理之間的對話"
response, embeddings = enhanced_llm_response(prompt)
print(response)
# 對嵌入進行一些操作,例如儲存、搜尋相似文本等
步驟 7:錯誤處理與記錄
在程式碼中新增錯誤處理和記錄,以管理 API 限制、請求失敗和其他潛在問題。
步驟 8:測試與迭代
徹底測試整合,並根據結果進行迭代。您可能需要調整參數、處理更多邊緣情況或最佳化效能。
請注意,實際實作細節可能會根據 Novita AI LLM API 和 bge-large-en-v1.5 模型的特定功能和要求而有所不同。您可以聯繫 Novita AI 團隊以獲得技術支援:support@novita.ai。
結論
總之,我們對「bge-large-en-v1.5」的探索凸顯了它在密集檢索任務中的核心作用,深入介紹了它的能力、應用和實際實作。從介紹模型及其在嵌入領域的重要性,到展示其在程式碼中的使用和微調過程,我們提供了全面的指南。此外,與 Novita AI LLM API 的整合體現了該模型在增強 LLM 語義理解和檢索準確性方面的潛力。
敬請期待更多關於 LLM 的最新消息!
常見問題
1. BGE 重排序器如何運作?
透過將查詢和段落輸入重排序器,您可以獲得相關性分數。該分數可以透過 sigmoid 函數轉換為 [0, 1] 範圍內的浮點數。此過程旨在確保排名靠前的結果更相關且品質更高,從而改善整體系統效能。
2. BGE 的上下文長度是多少?
最新的模型 bge-m3 的上下文長度為 8kb。
3. bge m3 嵌入的大小是多少?
它可以處理從短句到長達 8192 個 token 的長篇文檔等不同長度的輸入。
Novita AI 是一個一體化雲端平台,助力您的 AI 抱負。憑藉無縫整合的 API、無伺服器運算和 GPU 加速,我們提供經濟高效的工具,幫助您快速建構和擴展 AI 驅動的業務。消除基礎設施煩惱,從免費開始 — Novita AI 讓您的 AI 夢想成真。
推薦閱讀
