newsence
歡迎

你的個人知識庫

從開放網路上發現值得讀的內容,收藏真正重要的。AI 為你摘要、串連、整理你所知道的一切。

使用 Sentence Transformers 訓練與微調多模態嵌入及重排序模型

使用 Sentence Transformers 訓練與微調多模態嵌入及重排序模型

Huggingface·大約 18 小時前

我將透過微調 Qwen3-VL-Embedding-2B 進行視覺文件檢索的實際案例,展示如何利用 Sentence Transformers 訓練多模態模型,並證明針對特定領域進行微調能顯著提升檢索效能。

使用 Sentence Transformers 訓練與微調多模態嵌入與重排序模型

作為一個實務範例,我將示範如何針對視覺文件檢索(Visual Document Retrieval, VDR)微調 Qwen/Qwen3-VL-Embedding-2B。VDR 的任務是根據給定的文本查詢,檢索相關的文件頁面(以包含圖表、表格和佈局完整的圖像形式呈現)。最終產出的 tomaarsen/Qwen3-VL-Embedding-2B-vdr 展示了透過在特定領域進行微調所能獲得的性能提升。在我的評估數據中,微調後的模型 NDCG@10 達到 0.947,而基礎模型為 0.888,且表現優於我測試過的所有現有 VDR 模型,包括尺寸達其 4 倍的模型。

VDR 模型的模型大小與 NDCG 對比圖

如果您是第一次在 Sentence Transformers 中使用多模態模型,建議先閱讀《使用 Sentence Transformers 的多模態嵌入與重排序模型》。關於訓練純文本嵌入、重排序或稀疏嵌入模型,請參閱文末的「先前部落格文章」章節。

目錄

為什麼要微調?

像 Qwen/Qwen3-VL-Embedding-2B 這樣的通用多模態嵌入模型,是在多樣化的數據上訓練而成的,旨在於各種語言和任務中表現良好:包括圖文匹配、視覺問答、文件理解等。但這種通用性意味著模型很少是任何特定任務的最佳選擇。

以視覺文件檢索為例:給定一個文本查詢如「公司第三季度的營收是多少?」,模型必須從數千張文件截圖中找到最相關的一張。這需要理解文件佈局、圖表、表格和文本,這與將鞋子照片與產品描述進行匹配是完全不同的技能。

透過在特定領域的數據上進行微調,模型可以學習這些專業化的模式。在我的實驗中,微調將 NDCG@10 從 0.888 提升到 0.947,領先於我測試過的每一個近期多模態模型,包括那些體積大 4 倍的模型。

訓練組件

訓練多模態 Sentence Transformer 模型涉及與訓練純文本模型相同的組件:

多模態訓練流程使用與純文本訓練相同的 SentenceTransformerTrainer。主要區別在於您的數據集除了文本外還包含圖像(或其他模態),且模型的處理器(Processor)會自動處理圖像預處理。

讓我們以視覺文件檢索(將文本查詢與文件截圖匹配)為例,逐步介紹每個組件。

模型

最常見的方法是微調現有的多模態嵌入模型,或從視覺語言模型(VLM)檢查點(Checkpoint)開始。Transformer 模組會自動從模型的處理器中偵測支援的模態。

要微調現有的多模態嵌入模型(例如已經包含 modules.json 文件的模型),您可以傳遞 processor_kwargsmodel_kwargs 來分別控制預處理和模型加載。processor_kwargs 會直接傳遞給 AutoProcessor.from_pretrained(...)(例如,圖像解析度限制:較高的 max_pixels 意味著較高的品質但佔用更多記憶體),而 model_kwargs 則傳遞給相應的 AutoModel.from_pretrained(...) 調用(例如,精度、注意力機制實現):

您也可以從尚未針對嵌入進行訓練的全新 VLM 檢查點開始。Sentence Transformers 會嘗試識別架構,從處理器推斷支援的模態,並設置適當的 forward 方法和池化(Pooling)。如果自動偵測對特定模型效果不佳,可以編輯保存的 sentence_bert_config.json 中的配置,以調整模態設置、forward 方法和輸出處理:

在這兩種情況下,Transformer 模組都會檢查處理器以確定哪些模態可用,並在需要時自動添加 Pooling。您可以驗證支援的模態:

除了使用單一 VLM 骨幹網路外,您還可以使用 Router 模組為不同模態組合獨立的編碼器。這讓您可以結合任何現有的編碼器,並根據偵測到的模態將輸入路由到適當的編碼器:

由於基於 Router 的多模態模型為每個模態使用獨立的編碼器,它們的嵌入空間最初是不對齊的。需要進行訓練來對齊空間,以實現有意義的跨模態相似度。上面顯示的 Dense 投影層有助於將來自不同編碼器的嵌入映射到共享空間中。

當您想使用輕量級、專業化的編碼器而不是大型 VLM 時,這種方法非常有用。您還可以使用 route_mappings 將基於 Router 的多模態與基於任務的路由結合(例如,查詢與文件使用不同的編碼器)。有關進階路由場景,請參閱 Router 文檔。

數據集

視覺文件檢索數據集

在此範例中,我使用 tomaarsen/llamaindex-vdr-en-train-preprocessed 數據集,這是 llamaindex/vdr-multilingual-train 的預處理英文子集。原始數據集是隨 LlamaIndex 的《視覺文件檢索走向多語言》部落格文章一同發布的,包含約 50 萬個從公開網路 PDF 中收集的多語言查詢-圖像樣本,查詢是使用 VLM(gemini-1.5-pro 和 Qwen2-VL-72B)合成生成的。
我的預處理版本篩選出 53,512 個英文樣本,並將每個樣本 16 個基於 ID 的硬負樣本(Hard Negatives)中的 4 個解析為實際的文件截圖圖像,因此可以直接用於訓練而無需進一步預處理:

訓練配置包含前 10,000 個樣本,評估配置包含接下來的 300 個樣本(也提供包含所有 53,512 個樣本的完整配置)。對於訓練,我選擇 queryimagenegative_0 來組成(錨點 anchor, 正樣本 positive, 硬負樣本 hard negative)三元組。包含額外的硬負樣本可能會改善訓練信號,但每個額外的負樣本也會增加記憶體使用量和訓練時間,因此我只保留一個。對於評估,我保留每個查詢的所有四個硬負樣本,以建立一個更具挑戰性的檢索語料庫(詳見評估器章節)。

數據集格式

就像純文本訓練一樣,數據集格式必須與您選擇的損失函數相匹配。規則是相同的:

對於多模態數據集,輸入可以包含:

數據整理器(Data Collator)會自動調用 model.preprocess(),它會偵測每個輸入的模態並應用適當的預處理。不需要手動進行分詞(Tokenization)或圖像處理。

許多可直接與 Sentence Transformers 配合使用的 Hugging Face 數據集都已標記 sentence-transformers 標籤,您可以在 https://huggingface.co/datasets?other=sentence-transformers 輕鬆找到它們。

損失函數

CachedMultipleNegativesRankingLoss

在這次訓練中,我使用 CachedMultipleNegativesRankingLoss,這是檢索任務的常見選擇。它接受(查詢, 正樣本)對以及任意數量的額外硬負樣本列(從 0 到 n),只要每個樣本具有相同數量的負樣本即可。
在訓練期間,損失函數會推高每個查詢與其正樣本的相似度,並降低其與每個負樣本的相似度。負樣本來自兩個來源:

每個查詢的負樣本越多,訓練信號就越強,因此較大的批次大小(Batch Size)能直接提高訓練品質。除此之外,「緩存(Cached)」版本的損失函數使用梯度緩存技術,使得即使在 GPU 記憶體有限的情況下,也能實現大型的有效批次大小。

mini_batch_size 參數控制在緩存前向傳遞期間一次處理多少個樣本。對於大型多模態模型,將此值設置為較小的值(例如 1)對於避免記憶體不足(OOM)錯誤至關重要,同時又不會犧牲大型有效批次大小的好處:

MatryoshkaLoss

為了產生在多種維度下都能良好運作的嵌入,我使用 MatryoshkaLoss 包裝基礎損失函數。這會訓練模型,使得即使將嵌入截斷到較小的維度,仍能保持良好的性能:

這對於多模態模型特別有用,因為其嵌入可能非常大(Qwen3-VL 為 2048 維)。透過 Matryoshka 訓練,您可以在部署時使用截斷的嵌入(例如 256 或 128 維),以實現更快的搜索並僅損失極少的品質。如我在結果章節所示,微調後的模型即使在 512 維度下也能達到接近峰值的性能。

訓練參數

SentenceTransformerTrainingArguments 類別讓您控制訓練超參數。以下是用於 VDR 微調的配置:

關於(多模態)訓練的幾點注意事項:

評估器

為了追蹤訓練前、訓練中和訓練後的檢索性能,我使用 InformationRetrievalEvaluator。它會計算標準的檢索指標,如 NDCG@10、MAP 和 Recall@k:

評估器接收文本查詢、圖像語料庫(包括硬負樣本)以及哪些文件與哪些查詢相關的映射。請注意,語料庫包含正樣本和硬負樣本文件截圖的混合,這使得評估具有挑戰性。使用 batch_size=1 可防止在評估大型 VLM 時出現記憶體不足問題。

訓練器

SentenceTransformerTrainer 將所有內容整合在一起。以下是完整的訓練腳本:

訓練腳本與純文本訓練腳本幾乎完全相同。唯一的區別是:

其他所有內容(訓練器、訓練參數、數據集加載)的工作方式都與純文本訓練完全相同。

結果

模型大小 vs NDCG@10

僅訓練 1 個 Epoch 後,微調後的 tomaarsen/Qwen3-VL-Embedding-2B-vdr 模型在評估集(300 個查詢,1500 個語料庫文件,餘弦相似度)上達到了 0.947 的 NDCG@10。這比基礎 Qwen/Qwen3-VL-Embedding-2B 模型的 0.888 有了顯著提升,且優於所有現有的 VDR 模型:

VDR 模型的模型大小與 NDCG 對比圖

微調後的 2B 模型甚至優於 8B 的 Qwen3-VL-Embedding 模型,展示了特定任務微調的力量。即使有更大的通用模型可用,在您自己的領域進行微調通常也是值得考慮的!

Matryoshka 維度 vs NDCG@10

上述比較使用的是完整的 2048 維嵌入。得益於 Matryoshka 訓練,微調後的模型在截斷為較少維度時也表現良好,讓您在部署時可以在嵌入大小和檢索品質之間取得平衡:

MRL 維度 vs NDCG@10

微調後的模型峰值出現在完整的 2048 維(0.948),但直到 512 維(縮小 4 倍)仍保持在峰值的 0.3% 以內,甚至在 64 維(縮小 32 倍)時仍保留了超過 92% 的峰值性能。Matryoshka 訓練將最重要的資訊集中在前面的維度,因此適度的截斷對性能影響極小。

1024 維與 2048 維之間的差距很小(0.946 vs. 0.948),因此我在模型配置中設置了 truncate_dim=1024 並保存。這意味著 SentenceTransformer("tomaarsen/Qwen3-VL-Embedding-2B-vdr") 預設會產生 1024 維的嵌入,與完整的 2048 維相比,存儲空間減半。如果您需要不同的維度,請在加載時傳遞 truncate_dim=N 來覆蓋它。

訓練多模態重排序模型

您還可以使用相同的訓練基礎設施來微調多模態 Cross Encoder(重排序)模型。主要區別在於使用 CrossEncoderTrainer 和 Cross Encoder 特有的損失函數。本節提供簡要概述;請參閱完整的訓練範例,以獲取包含數據準備和評估的完整可執行腳本。

以下是一個基於塗鴉(doodles)訓練腳本的簡化範例,該腳本訓練一個重排序器來匹配圖像與文本描述:

多模態重排序器有多種有效的架構選擇,包括:

這兩種方法都在多模態 Cross Encoder 訓練範例中得到了展示。

上面連結的兩個腳本將訓練數據分為兩個數據集,每個方向一個(圖像到文本和文本到圖像),每個方向都有一個特定任務的提示(Prompt),告訴模型如何對該方向進行評分。然後,每個正樣本對會與隨機採樣的負樣本一起擴展,使損失函數看到匹配與不匹配的平衡混合。

其他資源

先前部落格文章

訓練範例

Sentence Transformers 存儲庫包含多個多模態訓練範例:

文檔

此外,以下頁面可能對了解更多關於 Sentence Transformers 訓練的資訊有所幫助:

本文提到的模型 2

本文提到的數據集 2

更多來自我們部落格的文章

圖片

使用 Sentence Transformers 的多模態嵌入與重排序模型

圖片

Falcon 2:一個 11B 參數的預訓練語言模型與 VLM,在超過 5000B 個 Token 和 11 種語言上訓練而成

社群

· 註冊或登入以發表評論

本文提到的模型 2

本文提到的數據集 2

https://huggingface.co/blog/train-multimodal-sentence-transformers