使用 Sentence Transformers 訓練與微調多模態嵌入及重排序模型
我將透過微調 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 倍的模型。

如果您是第一次在 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_kwargs 和 model_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 個樣本的完整配置)。對於訓練,我選擇 query、image 和 negative_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 模型:

微調後的 2B 模型甚至優於 8B 的 Qwen3-VL-Embedding 模型,展示了特定任務微調的力量。即使有更大的通用模型可用,在您自己的領域進行微調通常也是值得考慮的!
Matryoshka 維度 vs NDCG@10
上述比較使用的是完整的 2048 維嵌入。得益於 Matryoshka 訓練,微調後的模型在截斷為較少維度時也表現良好,讓您在部署時可以在嵌入大小和檢索品質之間取得平衡:

微調後的模型峰值出現在完整的 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 種語言上訓練而成
社群
· 註冊或登入以發表評論