爲什麼用 Qwen3 embedding 和 rerank

排名是真的挺好,開源閉源現在都是第一了,這個事 embeddiing 的,rerank 應該也是第一,甚至 4B 的基本也除了 8B 以外就是它第一。

它和普通的比如原來的我們常用的 BGE 之類的有啥區別?

傳統的 embedding 都是基於 bert 來弄模型,一般也就 encoder only,bert 原來也就是幹分類器的,給一句話到它,它給你進行 embedding 了,這裏考慮到有些同學可以不理解整套流程,我就稍微說細點一般來講用 3 層法就很好理解:

第一層:詞元嵌入(Token Embedding)——“查字典” 階段

“一個 token 一個 token 地進行 embedding”,這是最基礎的,也是第一步。

  1. 分詞(Tokenization):模型拿到一句話,例如 "The cat sat on the mat",會先把它切分爲一個個 “詞元”(Token):["the", "cat", "sat", "on", "the", "mat"]

  2. 查字典(Token Embedding):模型內部有一個龐大的 “字典”(Embedding Layer),存着每個詞元對應的初始向量。模型會根據分詞的結果,依次查出每個 token 的初始向量。舉例:"the" -> [0.1, 0.5, 0.2, ...]"cat" -> [0.8, 0.1, 0.9, ...]…… 這一層得到的向量是上下文無關的。舉個經典例子,無論 “bank” 出現在“river bank”(河岸)還是“investment bank”(投資銀行)裏,在這一層查出的向量都是一樣的。兩個 bank 在這個向量化的時候沒啥區別,但是我們知道語義完全是兩個東西

第二層:上下文感知(Contextualization)——Transformer 就上了

傳統模型(比如 Word2Vec)和現代的 Transformer 模型(比如 BERT、Qwen)就在這裏拉開了差距。

在拿到第一步得到的所有初始向量後,模型不會直接用它們,而是把這一串向量送入 Transformer 核心結構(多層自注意力機制,搞一遍 QKV),進行 “深加工”。

你可以把它想象成:這些獨立的單詞向量都進入了一個 “會議室”。在這裏,“cat” 這個向量會和 “sat”“mat” 等其他向量充分“溝通和討論”(自注意力機制)。經過多輪(多層)討論,每個單詞向量都吸收了整句話的上下文信息,最終全部更新(這塊看不懂可以看我以前的 transformer 算法文章)。

在這一步之後,比如 “bank” 在“river bank”和在 “investment bank” 中的最終向量就不再相同,而是根據上下文有了不同的含義。但要注意:此時我們依然得到了一個詞元序列對應一個向量,即一句話還是對應一串向量,每個詞元一個。

第三層:句子嵌入(Sentence Embedding)——從 “一串” 到“一個”

接下來,有些任務(比如語義搜索、相似度比對等)需要用一個向量來代表整個句子,而不是一串向量。這時就需要一個聚合或池化(Pooling) 的策略,把第二層產出的那一串上下文感知向量,濃縮成一個能夠代表整句話的整體向量。

這塊 BGE 代表的 bert 派和 qwen3 代表的 LLM 派就有區別了

這正是 [CLS] 和 [EOS] 發揮作用的地方!

傳統 BERT 模型([CLS] 策略)

BERT 會在輸入的最前面加一個特殊的 [CLS](Classification)標記。在經過 Transformer 的 “深加工” 後,BERT 會特別訓練模型,使得這一最終的 [CLS] 標記向量能夠代表整句話的含義。

因此,我們只需要從最後一層輸出中,把 [CLS] 對應的向量單獨拿出來,就可以用作整句話的句子嵌入。其他詞元的向量在這個任務中可以忽略。這個 CLS 可以掛在整個句子的最前面

[CLS] 句子 A [SEP] 句子 B [SEP]

bert pooling 完了的結果是由這個 CLS 位爲代表,最終的句子(任意長的 chunk)得到的一個定長的向量,也就是**[CLS]標記最終的隱藏狀態向量**。這個**定長的向量**就是該文本塊的嵌入表示,也正是我們存入向量庫用於後續檢索的那個向量。

Qwen3 模型([EOS] 策略)

Qwen3 的原理與 BERT 類似,不過由於其結構是單向的,因爲 LLM 是 casul LLM,它看不到你前面的東西啊,所以它選擇在輸入序列的末尾加一個 [EOS](End of Sequence)標記。

也就這麼點區別,因爲看不見前面,所以選擇最後整個語義被壓縮到最後一個 speical token,這裏用的是 EOS,然後最後這個 EOS token 所代表的 hidden state 等駕於 CLS

當然同樣,Qwen3 也會特別訓練模型,確保 [EOS] 標記的最終向量能夠代表整句話的含義。

因此,我們只需取 [EOS] 的那個向量,就得到了所需的句子嵌入。

看起來似乎沒那麼特別大的差別嗎?那它爲什麼效果能好出來 10 幾個百分點呢?

1- 模型夠大,只要你把 BGE 做的 dimension 變大,它其實也能變好的,因爲維度大了,隱空間可表示的表徵自然就豐富,難訓,但是訓好了,泛化性和能力都要更好

2- 基礎模型太強,Qwen3 的語音本身的理解那不是 bert 能比的了的(在我看這纔是核心),早它之前其實也有那拿 mistral 來訓類似的套路的,效果也不錯,可是 mistral 和 qwen 系列還是沒法比的

3- 訓練方法

前兩個階段都是對比學習,3 階段加一個 slerp

1)合成數劇上用 qwen32 來刷的,刷了很多,有邏輯的數據,那以前 BGE 上的只能上社區搜,這塊差了不少,無論質量還是數量。他們總共創造了約 1.5 億對用於弱監督訓練的文本對,有人說 LLM 的語義能力應該可以啊,嗨搞什麼弱監督 pretrain 啊,這不是你的最終任務是這種成對的嗎,所以拿這個刷一刷,原始 pretrain 數據集裏對這種的任務沒有特定的針對 datasets,相當於補充一下

2)多樣性,研發人員在生成數據時,精確地定義和控制各種維度,例如任務類型、語言、文本長度和難度等。論文的附錄中詳細介紹了一個精巧的兩階段生成流程,在生成檢索數據時,會先爲文檔配置一個 “角色(Character)”,然後從這個角色的視角出發生成查詢,極大地提升了數據的多樣性和真實感。

3) 合成加人工在 FT,這階段還有包含約 700 萬對人工標註數據和 1200 萬對高質量合成數據來刷 FT

4- Slerp 這個基本不太會有人特別用,但是論文說用 Slerp 來融合多個 step 的 checkpoint 面對不同的下游任務效果都很好,我覺得看看就可以了,這個不用太當真。

剛纔說它底子好,數據又多是主要原因,其實還有一個原因也很重要,但是估計大多數人不一定用,比如我粘這張圖的 MTEB 的 bench leadboard 就沒考慮進來,全是 zero shot 的,也就是我們普通玩的雙塔

問題 --> embedding 得向量和 docuemnt embedding 得向量一比,哪幾個 topk 更好,就選出他們 index 對英的 chunk

這是普通玩法,當然 qwen3 這個普通玩法我們看着在天梯上就很能打

可是它其實是有新玩法的,就是 instruct

它示例代碼是這樣的:

from sentence_transformers import SentenceTransformer
# Load the model
model = SentenceTransformer("Qwen/Qwen3-Embedding-0.6B")
queries = [
    "What is the capital of China?",
    "Explain gravity",
]
documents = [
    "The capital of China is Beijing.",
    "Gravity is a force that attracts two bodies towards each other...",
]
# Encode the queries and documents. Note that queries benefit from using a prompt
query_embeddings = model.encode(queries, prompt_)
document_embeddings = model.encode(documents)

先看一個用 sentence-transformer 引導的簡單的案例,就是比 2 個 query 和 2 個 document 的距離麼

這個看着特別容易,但是其實有點玄機,玄機在這 

query_embeddings = model.encode(queries, prompt_)

正常我們認爲 encode 一個問題的時候就是把 query 給 encode 了,對吧,但是它這個多來一個尾巴,就是這個 prompt_

這個是什麼呢?

這個就是 instruct,玩 LLM 的對這個就沒什麼可陌生的了,最早的 chatGPT 就有 3 個輸入對吧

system 的

instruct 的

user 的

system 的對應全局 role 的或者什麼其他的設定,instruct 對應本次的,user 就是正常說話的,只不過現在被改的基本也就偶爾用用 system,instruct 基本消失於江湖了,全是 user 的

但是 qwen3 把這個撿了起來。

它是做什麼的呢?

首先如果默認寫了 prompt_name='query'如上一段代碼,那麼背後的意義就是相當於開個默認的 instruct=‘Given a web search query, retrieve relevant passages that answer the query’

而每次跟着用戶的問題一起進入雙塔中的問題塔進行 encoder 的除了用戶的問題,還有這個 instruct,相當於給你的查詢加了控制

有人說看這個 instruct 也沒什麼意義啊,基本不都是爲了 query 嗎?那系統本身帶的默認的卻是就是給 retrive 用的

可是還很多場景,你可以給它改了,比如我舉幾個能想到又好理解的例子:

例子一:FAQ 知識庫中的 “相似問題” 匹配

場景:

假設你有一個包含 1000 個標準問答對(FAQ)的知識庫。用戶提出了一個口語化的問題,你不希望直接從那些冗長的答案中查找,而是希望先找到與用戶問題最相似的 “標準問題”,再把相應的標準答案返回給用戶。

挑戰:

這裏的關鍵任務不再是 “問題→答案” 的檢索,而是 “問題→問題” 的相似度匹配。

自定義指令:

Instruct: For the given user question, find the most similar question from the FAQ list.

中文示例:“爲以下用戶問題,在 FAQ 列表中匹配最相似的標準問法。”

這個指令告訴模型,無需關注答案內容,而是聚焦於兩個問題在語義上的等價性。相比通用的 retrieve 指令,這樣更精準,能有效避免用戶問題因爲某個關鍵詞(如 “價格”)而誤匹配到不相關的答案。

例子二:“相關推薦”或 “發現更多” 功能

場景:

用戶正在閱讀一篇新聞報道或瀏覽一個商品詳情頁,你希望在頁面下方爲其推薦 “相似文章” 或“相似商品”。

挑戰:

“相似” 有多種維度:是主題相似?風格或調性相似?還是同樣提到了某個人物或產品?

自定義指令與示例

主題推薦:

Instruct: Find other articles with a similar topic.

中文示例:“尋找主題相似的其他文章。”

風格推薦:

Instruct: Find other documents written in a similar narrative style.

中文示例:“尋找寫作風格相似的其他文檔。”

意義:

你可以用同一套文檔向量,通過在查詢時動態傳入不同指令,爲用戶提供多維度的推薦。比如讓用戶自己選擇 “更關心主題” 還是“喜歡這個作者的風格”,實現更個性化的推薦功能。

例子三:代碼庫中的功能性搜索(論文提到的強項)

場景:

開發者希望在代碼庫中尋找能夠 “異步寫入文件” 的函數。

挑戰:

代碼搜索和自然語言搜索不同。直搜 “異步寫入文件” 未必有效,因爲不同開發者可能用不同的變量名或註釋。

自定義指令:

Instruct: Find code snippets that perform a similar function.

中文示例:“尋找能夠實現相似功能的代碼片段。”

這個指令能引導模型超越表面詞彙差異,理解代碼的實際邏輯和功能。這也是 Qwen3 Embedding 在代碼檢索表現突出的原因之一。開發者還可以更具體地定製指令,比如:"Find usage examples for the'torch.nn.Module'class"。

例子四:細粒度的評論分析

場景:

身爲產品經理,你希望從大量用戶評論中,找到所有提到 “電池續航差” 的負面評價。

挑戰:

直接搜 “電池” 會返回所有正負評論,普通語義搜索也難區分評論的情感傾向。

自定義指令:

Instruct: From the product reviews, retrieve passages that express a negative sentiment about battery life.

中文示例:“從產品評論中,檢索關於‘電池續航’的負面評價段落。”

這不就少挨幾句罵麼。。。

綜上,這個我認爲是有用,但是現有大部分 rag 系統本身不支持這個(我自己玩的 BY_RAG 也爲了這個能力再改),所以還是有一定工作量和產品設計怎麼能根據具體的任務來靈活的設置 instruct,新玩法出來了,但是老工具還是需要改進來 fit 它的能力。

最後花少許時間講講 qwen-rerank

它這個也和傳統的 rerank 不一樣,傳統的單塔 rerank 一般是最後一層 liner 輸出個 logit,但是它是用 system prompt 來讓 rerank 模型生成 yes|no,然後輸出 yes 的概率得分,(score = P("yes") / (P("yes") + P("no")) 包括爲了兼容這塊你最好還要做 padding 的左移,總之現有的代碼你想用,是要進行變更的

除了對 rerank 分數的判定不一樣,傳統 rerank 是使用簡單的[CLS]Query[SEP]Document拼接方式,然後進裏面去查相關性,它不是,它的套路是 template

Qwen3 Reranker 的設計採用了結構化、類似對話的上下文輸入方式,最大程度發揮了大語言模型的理解和推理能力。

根據論文,輸入格式遵循類聊天模板,主要包含以下幾個部分:

第 1 部分

  1. 系統指令(System Prompt)
    首先,系統級指令爲模型設定角色和任務規則。這個指令會告訴模型:"根據提供的查詢和指令來判斷文檔是否滿足要求",並明確規定 “答案只能是‘yes’或‘no’”。這樣,排序任務就被直接轉化爲一個二元分類問題。

  2. 用戶信息(User Block)
    在 user 塊中,結構化地提供三項核心信息:

  1. 助手提示(Assistant Prompt)
    最後,輸入以一個 assistant 提示結尾,讓模型去 “思考” 並生成最終的判斷。

看起來這樣

<|im_start|>system
Judge whether the Document meets the requirements based on the Query and the
Instruct provided. Note that the answer can only be "yes" or "no".<|im_end|>
<|im_start|>user
<Instruct>: {用戶自定義的指令}
<Query>: {用戶的查詢}
<Document>: {候選文檔}<|im_end|>
<|im_start|>assistant

第 2 部分:進入 Qwen3 模型(“判官” 審閱案卷)

這個精心構建、結構化好的 “案卷” 文本會被完整送入 Qwen3 基礎模型。

Qwen3 本身就是一個強大的大語言模型(雖然小,但是應付 embedding 夠用),擁有 0.6B、4B、8B 等多種規模,具備強大的文本理解能力、長上下文處理(32K 序列長度)、以及出色的指令跟隨能力。

與傳統模型類似,Qwen3 會對指令、查詢和文檔中的所有詞元進行深度、端到端的自注意力計算,實現信息的充分交互。

第 3 部分:輸出判決(計算 “yes” 的概率)

Qwen3 Reranker 在輸出機制上和傳統模型有着顯著區別。它不依賴額外的分類頭輸出抽象分數,而是直接通過預測答案 “yes” 或“no”的概率,作爲相關性判斷的依據。

具體做法是:模型的主要任務是預測 assistant 後最可能出現的詞元,即 “yes” 或“no”,並計算它們各自的概率。最終的相關性分數通過如下公式歸一化得到:

score = P("yes") / (P("yes") + P("no"))

該分數的取值範圍在 0 到 1 之間,直觀代表了文檔與查詢在當前指令下的相關程度。分數越高,說明 “yes” 的置信度越高,即文檔越符合用戶需求。

Qwen3 Reranker 通過將排序任務 “LLM 化” “對話化”,充分釋放了其強大基礎模型的潛力,使其不再是一個簡單的打分工具,而是一個能夠理解複雜指令、進行深度推理的智能 “判官”,這就是完全兩個故事了,所以性能和純 rank 打分器也不一樣

訓練就不說了,沒啥特殊的,刷數據

我自己的 RAG 肯定是率先都支持了,現在在做和 DR 集成,做好了,就開源,做不好我也不着急發

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/hmJ1H9gTBmHV_dOGM7UeWg