為什么用Qwen3 embedding和rerank
排名是真的挺好,開(kāi)源閉源現(xiàn)在都是第一了,這個(gè)事embeddiing的,rerank應(yīng)該也是第一,甚至4B的基本也除了8B以外就是它第一。
它和普通的比如原來(lái)的我們常用的BGE之類的有啥區(qū)別?
傳統(tǒng)的embedding都是基于bert來(lái)弄模型,一般也就encoder only,bert原來(lái)也就是干分類器的,給一句話到它,它給你進(jìn)行embedding了,這里考慮到有些同學(xué)可以不理解整套流程,我就稍微說(shuō)細(xì)點(diǎn)一般來(lái)講用3層法就很好理解:
第一層:詞元嵌入(Token Embedding)——“查字典”階段
“一個(gè)token一個(gè)token地進(jìn)行embedding”,這是最基礎(chǔ)的,也是第一步。
- 分詞(Tokenization):模型拿到一句話,例如 "The cat sat on the mat",會(huì)先把它切分為一個(gè)個(gè)“詞元”(Token):["the", "cat", "sat", "on", "the", "mat"]
- 查字典(Token Embedding):模型內(nèi)部有一個(gè)龐大的“字典”(Embedding Layer),存著每個(gè)詞元對(duì)應(yīng)的初始向量。模型會(huì)根據(jù)分詞的結(jié)果,依次查出每個(gè)token的初始向量。舉例:"the" -> [0.1, 0.5, 0.2, ...]"cat" -> [0.8, 0.1, 0.9, ...]……這一層得到的向量是上下文無(wú)關(guān)的。舉個(gè)經(jīng)典例子,無(wú)論“bank”出現(xiàn)在“river bank”(河岸)還是“investment bank”(投資銀行)里,在這一層查出的向量都是一樣的。兩個(gè)bank在這個(gè)向量化的時(shí)候沒(méi)啥區(qū)別,但是我們知道語(yǔ)義完全是兩個(gè)東西
第二層:上下文感知(Contextualization)——Transformer就上了
傳統(tǒng)模型(比如Word2Vec)和現(xiàn)代的Transformer模型(比如BERT、Qwen)就在這里拉開(kāi)了差距。
在拿到第一步得到的所有初始向量后,模型不會(huì)直接用它們,而是把這一串向量送入Transformer核心結(jié)構(gòu)(多層自注意力機(jī)制,搞一遍QKV),進(jìn)行“深加工”。
你可以把它想象成:這些獨(dú)立的單詞向量都進(jìn)入了一個(gè)“會(huì)議室”。在這里,“cat”這個(gè)向量會(huì)和“sat”“mat”等其他向量充分“溝通和討論”(自注意力機(jī)制)。經(jīng)過(guò)多輪(多層)討論,每個(gè)單詞向量都吸收了整句話的上下文信息,最終全部更新(這塊看不懂可以看我以前的transformer算法文章)。
在這一步之后,比如“bank”在“river bank”和在“investment bank”中的最終向量就不再相同,而是根據(jù)上下文有了不同的含義。但要注意:此時(shí)我們依然得到了一個(gè)詞元序列對(duì)應(yīng)一個(gè)向量,即一句話還是對(duì)應(yīng)一串向量,每個(gè)詞元一個(gè)。
第三層:句子嵌入(Sentence Embedding)——從“一串”到“一個(gè)”
接下來(lái),有些任務(wù)(比如語(yǔ)義搜索、相似度比對(duì)等)需要用一個(gè)向量來(lái)代表整個(gè)句子,而不是一串向量。這時(shí)就需要一個(gè)聚合或池化(Pooling) 的策略,把第二層產(chǎn)出的那一串上下文感知向量,濃縮成一個(gè)能夠代表整句話的整體向量。
這塊BGE代表的bert派和qwen3代表的LLM派就有區(qū)別了
這正是 [CLS] 和 [EOS] 發(fā)揮作用的地方!
傳統(tǒng)BERT模型([CLS]策略)
BERT會(huì)在輸入的最前面加一個(gè)特殊的 [CLS](Classification)標(biāo)記。在經(jīng)過(guò)Transformer的“深加工”后,BERT會(huì)特別訓(xùn)練模型,使得這一最終的 [CLS] 標(biāo)記向量能夠代表整句話的含義。
因此,我們只需要從最后一層輸出中,把 [CLS] 對(duì)應(yīng)的向量單獨(dú)拿出來(lái),就可以用作整句話的句子嵌入。其他詞元的向量在這個(gè)任務(wù)中可以忽略。這個(gè)CLS可以掛在整個(gè)句子的最前面
[CLS] 句子A [SEP] 句子B [SEP]
bert pooling完了的結(jié)果是由這個(gè)CLS位為代表,最終的句子(任意長(zhǎng)的chunk)得到的一個(gè)定長(zhǎng)的向量,也就是???[CLS]??
?標(biāo)記最終的隱藏狀態(tài)向量。這個(gè)定長(zhǎng)的向量就是該文本塊的嵌入表示,也正是我們存入向量庫(kù)用于后續(xù)檢索的那個(gè)向量。
Qwen3模型([EOS]策略)
Qwen3的原理與BERT類似,不過(guò)由于其結(jié)構(gòu)是單向的,因?yàn)長(zhǎng)LM是casul LLM,它看不到你前面的東西啊,所以它選擇在輸入序列的末尾加一個(gè) [EOS](End of Sequence)標(biāo)記。
也就這么點(diǎn)區(qū)別,因?yàn)榭床灰?jiàn)前面,所以選擇最后整個(gè)語(yǔ)義被壓縮到最后一個(gè)speical token,這里用的是EOS,然后最后這個(gè)EOS token所代表的hidden state 等駕于CLS
當(dāng)然同樣,Qwen3也會(huì)特別訓(xùn)練模型,確保 [EOS] 標(biāo)記的最終向量能夠代表整句話的含義。
因此,我們只需取 [EOS] 的那個(gè)向量,就得到了所需的句子嵌入。
看起來(lái)似乎沒(méi)那么特別大的差別嗎?那它為什么效果能好出來(lái)10幾個(gè)百分點(diǎn)呢?
1- 模型夠大,只要你把BGE做的dimension變大,它其實(shí)也能變好的,因?yàn)榫S度大了,隱空間可表示的表征自然就豐富,難訓(xùn),但是訓(xùn)好了,泛化性和能力都要更好
2- 基礎(chǔ)模型太強(qiáng),Qwen3的語(yǔ)音本身的理解那不是bert能比的了的(在我看這才是核心),早它之前其實(shí)也有那拿mistral來(lái)訓(xùn)類似的套路的,效果也不錯(cuò),可是mistral和qwen系列還是沒(méi)法比的
3- 訓(xùn)練方法
前兩個(gè)階段都是對(duì)比學(xué)習(xí),3階段加一個(gè)slerp
1)合成數(shù)劇上用qwen32來(lái)刷的,刷了很多,有邏輯的數(shù)據(jù),那以前BGE上的只能上社區(qū)搜,這塊差了不少,無(wú)論質(zhì)量還是數(shù)量。他們總共創(chuàng)造了約1.5億對(duì)用于弱監(jiān)督訓(xùn)練的文本對(duì),有人說(shuō)LLM的語(yǔ)義能力應(yīng)該可以啊,嗨搞什么弱監(jiān)督pretrain啊,這不是你的最終任務(wù)是這種成對(duì)的嗎,所以拿這個(gè)刷一刷,原始pretrain數(shù)據(jù)集里對(duì)這種的任務(wù)沒(méi)有特定的針對(duì)datasets,相當(dāng)于補(bǔ)充一下
2)多樣性,研發(fā)人員在生成數(shù)據(jù)時(shí),精確地定義和控制各種維度,例如任務(wù)類型、語(yǔ)言、文本長(zhǎng)度和難度等?。論文的附錄中詳細(xì)介紹了一個(gè)精巧的兩階段生成流程,在生成檢索數(shù)據(jù)時(shí),會(huì)先為文檔配置一個(gè)“角色(Character)”,然后從這個(gè)角色的視角出發(fā)生成查詢,極大地提升了數(shù)據(jù)的多樣性和真實(shí)感?????????。
3) 合成加人工在FT,這階段還有包含約700萬(wàn)對(duì)人工標(biāo)注數(shù)據(jù)和1200萬(wàn)對(duì)高質(zhì)量合成數(shù)據(jù)來(lái)刷FT
4- Slerp這個(gè)基本不太會(huì)有人特別用,但是論文說(shuō)用Slerp來(lái)融合多個(gè)step的checkpoint面對(duì)不同的下游任務(wù)效果都很好,我覺(jué)得看看就可以了,這個(gè)不用太當(dāng)真。
剛才說(shuō)它底子好,數(shù)據(jù)又多是主要原因,其實(shí)還有一個(gè)原因也很重要,但是估計(jì)大多數(shù)人不一定用,比如我粘這張圖的MTEB的bench leadboard就沒(méi)考慮進(jìn)來(lái),全是zero shot的,也就是我們普通玩的雙塔
問(wèn)題--> embedding 得向量和 docuemnt embedding得向量一比,哪幾個(gè)topk更好,就選出他們index對(duì)英的chunk
這是普通玩法,當(dāng)然qwen3這個(gè)普通玩法我們看著在天梯上就很能打
可是它其實(shí)是有新玩法的,就是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_name="query")
document_embeddings = model.encode(documents)
先看一個(gè)用sentence-transformer引導(dǎo)的簡(jiǎn)單的案例,就是比2個(gè)query和2個(gè)document的距離么
這個(gè)看著特別容易,但是其實(shí)有點(diǎn)玄機(jī),玄機(jī)在這
??query_embeddings = model.encode(queries, prompt_name="query")?
?
正常我們認(rèn)為encode一個(gè)問(wèn)題的時(shí)候就是把query給encode了,對(duì)吧,但是它這個(gè)多來(lái)一個(gè)尾巴,就是這個(gè) prompt_name="query"
這個(gè)是什么呢?
這個(gè)就是instruct,玩LLM的對(duì)這個(gè)就沒(méi)什么可陌生的了,最早的chatGPT就有3個(gè)輸入對(duì)吧!
system的
instruct的
user的
system的對(duì)應(yīng)全局role的或者什么其他的設(shè)定,instruct對(duì)應(yīng)本次的,user就是正常說(shuō)話的,只不過(guò)現(xiàn)在被改的基本也就偶爾用用system,instruct基本消失于江湖了,全是user的
但是qwen3把這個(gè)撿了起來(lái)。
它是做什么的呢?
首先如果默認(rèn)寫了prompt_name='query'如上一段代碼,那么背后的意義就是相當(dāng)于開(kāi)個(gè)默認(rèn)的instruct=‘Given a web search query, retrieve relevant passages that answer the query’
而每次跟著用戶的問(wèn)題一起進(jìn)入雙塔中的問(wèn)題塔進(jìn)行encoder的除了用戶的問(wèn)題,還有這個(gè)instruct,相當(dāng)于給你的查詢加了控制
有人說(shuō)看這個(gè)instruct也沒(méi)什么意義啊,基本不都是為了query嗎?那系統(tǒng)本身帶的默認(rèn)的卻是就是給retrive用的
可是還很多場(chǎng)景,你可以給它改了,比如我舉幾個(gè)能想到又好理解的例子:
例子一:FAQ知識(shí)庫(kù)中的“相似問(wèn)題”匹配
場(chǎng)景:假設(shè)你有一個(gè)包含1000個(gè)標(biāo)準(zhǔn)問(wèn)答對(duì)(FAQ)的知識(shí)庫(kù)。用戶提出了一個(gè)口語(yǔ)化的問(wèn)題,你不希望直接從那些冗長(zhǎng)的答案中查找,而是希望先找到與用戶問(wèn)題最相似的“標(biāo)準(zhǔn)問(wèn)題”,再把相應(yīng)的標(biāo)準(zhǔn)答案返回給用戶。
挑戰(zhàn):這里的關(guān)鍵任務(wù)不再是“問(wèn)題→答案”的檢索,而是“問(wèn)題→問(wèn)題”的相似度匹配。
自定義指令:Instruct: For the given user question, find the most similar question from the FAQ list.
中文示例:“為以下用戶問(wèn)題,在FAQ列表中匹配最相似的標(biāo)準(zhǔn)問(wèn)法。”
這個(gè)指令告訴模型,無(wú)需關(guān)注答案內(nèi)容,而是聚焦于兩個(gè)問(wèn)題在語(yǔ)義上的等價(jià)性。相比通用的retrieve指令,這樣更精準(zhǔn),能有效避免用戶問(wèn)題因?yàn)槟硞€(gè)關(guān)鍵詞(如“價(jià)格”)而誤匹配到不相關(guān)的答案。
例子二:“相關(guān)推薦”或“發(fā)現(xiàn)更多”功能
場(chǎng)景:用戶正在閱讀一篇新聞報(bào)道或?yàn)g覽一個(gè)商品詳情頁(yè),你希望在頁(yè)面下方為其推薦“相似文章”或“相似商品”。
挑戰(zhàn):“相似”有多種維度:是主題相似?風(fēng)格或調(diào)性相似?還是同樣提到了某個(gè)人物或產(chǎn)品?
自定義指令與示例
主題推薦:Instruct: Find other articles with a similar topic.
中文示例:“尋找主題相似的其他文章。”
風(fēng)格推薦:Instruct: Find other documents written in a similar narrative style.
中文示例:“尋找寫作風(fēng)格相似的其他文檔。”
意義:你可以用同一套文檔向量,通過(guò)在查詢時(shí)動(dòng)態(tài)傳入不同指令,為用戶提供多維度的推薦。比如讓用戶自己選擇“更關(guān)心主題”還是“喜歡這個(gè)作者的風(fēng)格”,實(shí)現(xiàn)更個(gè)性化的推薦功能。
例子三:代碼庫(kù)中的功能性搜索(論文提到的強(qiáng)項(xiàng))
場(chǎng)景:開(kāi)發(fā)者希望在代碼庫(kù)中尋找能夠“異步寫入文件”的函數(shù)。
挑戰(zhàn):代碼搜索和自然語(yǔ)言搜索不同。直搜“異步寫入文件”未必有效,因?yàn)椴煌_(kāi)發(fā)者可能用不同的變量名或注釋。
自定義指令:Instruct: Find code snippets that perform a similar function.
中文示例:“尋找能夠?qū)崿F(xiàn)相似功能的代碼片段。”
這個(gè)指令能引導(dǎo)模型超越表面詞匯差異,理解代碼的實(shí)際邏輯和功能。這也是Qwen3 Embedding在代碼檢索表現(xiàn)突出的原因之一。開(kāi)發(fā)者還可以更具體地定制指令,比如:"Find usage examples for the 'torch.nn.Module' class"。
例子四:細(xì)粒度的評(píng)論分析
場(chǎng)景:身為產(chǎn)品經(jīng)理,你希望從大量用戶評(píng)論中,找到所有提到“電池續(xù)航差”的負(fù)面評(píng)價(jià)。
挑戰(zhàn):直接搜“電池”會(huì)返回所有正負(fù)評(píng)論,普通語(yǔ)義搜索也難區(qū)分評(píng)論的情感傾向。
自定義指令:Instruct: From the product reviews, retrieve passages that express a negative sentiment about battery life.
中文示例:“從產(chǎn)品評(píng)論中,檢索關(guān)于‘電池續(xù)航’的負(fù)面評(píng)價(jià)段落。”
這不就少挨幾句罵么。。。
綜上,這個(gè)我認(rèn)為是有用,但是現(xiàn)有大部分rag系統(tǒng)本身不支持這個(gè)(我自己玩的BY_RAG也為了這個(gè)能力再改),所以還是有一定工作量和產(chǎn)品設(shè)計(jì)怎么能根據(jù)具體的任務(wù)來(lái)靈活的設(shè)置instruct,新玩法出來(lái)了,但是老工具還是需要改進(jìn)來(lái)fit它的能力。
最后花少許時(shí)間講講qwen-rerank它這個(gè)也和傳統(tǒng)的rerank不一樣,傳統(tǒng)的單塔rerank一般是最后一層liner輸出個(gè)logit,但是它是用system prompt來(lái)讓rerank模型生成yes|no,然后輸出yes的概率得分,(score = P("yes") / (P("yes") + P("no"))包括為了兼容這塊你最好還要做padding的左移,總之現(xiàn)有的代碼你想用,是要進(jìn)行變更的
除了對(duì)rerank分?jǐn)?shù)的判定不一樣,傳統(tǒng)rerank是使用簡(jiǎn)單的??[CLS]Query[SEP]Document?
?拼接方式,然后進(jìn)里面去查相關(guān)性,它不是,它的套路是template
Qwen3 Reranker 的設(shè)計(jì)采用了結(jié)構(gòu)化、類似對(duì)話的上下文輸入方式,最大程度發(fā)揮了大語(yǔ)言模型的理解和推理能力。
根據(jù)論文,輸入格式遵循類聊天模板,主要包含以下幾個(gè)部分:
第1部分
- 系統(tǒng)指令(System Prompt)
首先,系統(tǒng)級(jí)指令為模型設(shè)定角色和任務(wù)規(guī)則。這個(gè)指令會(huì)告訴模型:"根據(jù)提供的查詢和指令來(lái)判斷文檔是否滿足要求",并明確規(guī)定“答案只能是‘yes’或‘no’”。這樣,排序任務(wù)就被直接轉(zhuǎn)化為一個(gè)二元分類問(wèn)題。 - 用戶信息(User Block)
在 user 塊中,結(jié)構(gòu)化地提供三項(xiàng)核心信息:
- ?
?<Instruct>?
?: 用戶自定義、用于指導(dǎo)模型排序的具體指令 - ?
?<Query>?
?: 用戶原始查詢 - ?
?<Document>?
?: 待判斷相關(guān)性的候選文檔
- 助手提示(Assistant Prompt)
最后,輸入以一個(gè) assistant 提示結(jié)尾,讓模型去“思考”并生成最終的判斷。
看起來(lái)這樣
<|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部分:進(jìn)入Qwen3模型(“判官”審閱案卷)
這個(gè)精心構(gòu)建、結(jié)構(gòu)化好的“案卷”文本會(huì)被完整送入Qwen3基礎(chǔ)模型。
Qwen3本身就是一個(gè)強(qiáng)大的大語(yǔ)言模型(雖然小,但是應(yīng)付embedding夠用),擁有0.6B、4B、8B等多種規(guī)模,具備強(qiáng)大的文本理解能力、長(zhǎng)上下文處理(32K序列長(zhǎng)度)、以及出色的指令跟隨能力。
與傳統(tǒng)模型類似,Qwen3會(huì)對(duì)指令、查詢和文檔中的所有詞元進(jìn)行深度、端到端的自注意力計(jì)算,實(shí)現(xiàn)信息的充分交互。
第3部分:輸出判決(計(jì)算“yes”的概率)
Qwen3 Reranker在輸出機(jī)制上和傳統(tǒng)模型有著顯著區(qū)別。它不依賴額外的分類頭輸出抽象分?jǐn)?shù),而是直接通過(guò)預(yù)測(cè)答案“yes”或“no”的概率,作為相關(guān)性判斷的依據(jù)。
具體做法是:模型的主要任務(wù)是預(yù)測(cè) assistant 后最可能出現(xiàn)的詞元,即“yes”或“no”,并計(jì)算它們各自的概率。最終的相關(guān)性分?jǐn)?shù)通過(guò)如下公式歸一化得到:
score = P("yes") / (P("yes") + P("no"))
該分?jǐn)?shù)的取值范圍在0到1之間,直觀代表了文檔與查詢?cè)诋?dāng)前指令下的相關(guān)程度。分?jǐn)?shù)越高,說(shuō)明“yes”的置信度越高,即文檔越符合用戶需求。
Qwen3 Reranker通過(guò)將排序任務(wù)“LLM化”或“對(duì)話化”,充分釋放了其強(qiáng)大基礎(chǔ)模型的潛力,使其不再是一個(gè)簡(jiǎn)單的打分工具,而是一個(gè)能夠理解復(fù)雜指令、進(jìn)行深度推理的智能“判官”,這就是完全兩個(gè)故事了,所以性能和純r(jià)ank打分器也不一樣
訓(xùn)練就不說(shuō)了,沒(méi)啥特殊的,刷數(shù)據(jù)
我自己的RAG肯定是率先都支持了,現(xiàn)在在做和DR集成,做好了,就開(kāi)源,做不好我也不著急發(fā)。
本文轉(zhuǎn)載自???熵減AI???,作者:周博洋
