
2017年我讀到《Attention Is All You Need》時印象其實是矛盾的。一方面self-attention的全局建模能力確實漂亮另一方面O(n2)復雜度讓我下意識覺得這種架構只會停留在中等長度序列上撐不起真正的長文本場景。后來的發(fā)展大家都看到了transformer不僅成了NLP的默認底座還一路蔓延到圖像、語音、多模態(tài)甚至連近年大模型里最核心的算法選型也都圍繞transformer架構在不斷演進。我想把這幾年觀察到的“核心算法是如何一步步被改出來的”講清楚從Q/K/V注意力本身到復雜度優(yōu)化、位置編碼、歸一化策略、注意力頭配置再到Decoder-only范式。不管你是要做模型訓練、推理優(yōu)化還是單純想理解大模型底層這條演進線都值得過一次。這里不會只堆結論我會把每一步背后的動機、代價和實際取舍都拆開說。理解這些比記住一堆模型名字更能幫你應對新出的模型。1. 起點問題為什么循環(huán)網絡會被自注意力取代1.1 RNN序列建模的硬傷遠不止“不能并行”先從RNN說起。RNN的致命問題不是簡單的不支持并行而是序列建模的方式決定了信息必須沿著時間步逐步傳遞。每一步隱狀態(tài)既要表達當前輸入又要保留過去的記憶這個隱狀態(tài)本質上是個“有損壓縮瓶口”。LSTM注入門控以后緩解了梯度消失但距離很遠的位置之間要經過多層門控復合信號早就衰減或扭曲了。機器翻譯里把整句編碼成一個向量的做法尤其明顯句子越長語義細節(jié)越難塞進一個固定向量。比如一篇新聞稿把開頭的主語和結尾的時間地點強行壓縮到同一個向量里中間的轉折關系很容易被平均掉。這個問題不是靠加深循環(huán)層就能解決的因為無論堆多少層路徑仍然是線性的信息依然要一站一站傳下去。真正讓序列建模發(fā)生質變的是把“路徑距離”這個概念直接抹平。Transformer讓任意兩個token之間都有一條直連路徑不需要經過中間token的中轉。從信息論視角看這相當于把一條容易衰減的串行信道換成了全連接網絡。代價是每條路徑都要顯式建模相關性于是就有了自注意力那個n×n的相似度矩陣。1.2 Attention機制從輔助走向主角的臨界點Attention也不是Transformer原創(chuàng)的。2014年前后Bahdanau等人在神經機器翻譯里引入的attention本質上是動態(tài)加權源端隱狀態(tài)讓decoder每一步能“按需查閱”源端信息而不是只靠最后一個向量。這個思路解決了一個實際問題但還沒有脫離RNN的主干。Transformer的突破在于把attention完全提升到主架構層面每一個位置的表示都通過它與其他所有位置的注意力來生成。于是任意兩個token之間的距離被拉到了1長距離依賴不再是經過若干步傳播而是直接計算相關性。這在算法設計上是個根本轉變用全局檢索代替順序傳遞同時讓所有位置的計算天然可以并行。所以討論Transformer的核心算法演進起點其實是這個選擇為什么要放棄順序結構答案不是“RNN不好”這么簡單而是RNN的串行瓶頸和長程衰減在規(guī)?;柧毨锾蕴?。Transformer把這條路跳過去之后后面所有演進都圍繞兩個核心問題展開一是如何讓注意力更快、更省、能處理更長序列二是如何在保持表達力的同時讓訓練更穩(wěn)定。理解了這兩個靶子后面所有改進就都能對號入座。2. 自注意力精算Q/K/V設計、縮放點積與多頭的數(shù)學邏輯2.1 Attention運算中的“查詢-鍵-值”到底在做什么要理解自注意力可以先把它想成一個數(shù)據(jù)庫檢索系統(tǒng)。每個輸入token經過三套不同的線性變換分別得到查詢Query、鍵Key和值Value。查詢是“我想找什么”鍵是“我身上有什么索引”值是“我實際提供的內容”。某個請求與前一個位置的鍵越匹配注意力權重越大輸出就越偏向前一個位置的值。在自注意力場景中這個機制是模型自己對自己的序列做檢索每個token都能根據(jù)整個序列的內容決定自己的表示。從實現(xiàn)角度看所有token的Q、K、V可以被組織成矩陣因此可以用矩陣乘法一次算完所有token之間的相似度。這也是并行性的來源不再是逐步計算而是一次性算出一張完整的關系表。具體公式可以寫成Attention(Q, K, V) softmax(Q * K^T / sqrt(d_k)) * V矩陣Q和K的每一行對應一個token的查詢和鍵。Q和K的轉置相乘得到n×n的相似度分數(shù)矩陣softmax把每行歸一化成概率分布最后用這些概率對V做加權求和得到每個token的新表示。2.2 縮放因子sqrt(d_k)一個經常被忽略的穩(wěn)定性設計公式里除以sqrt(d_k)很多入門文章把它當作“經驗性技巧”實際上這里藏著訓練穩(wěn)定性的關鍵。假設Q、K中的元素是均值0、方差1的隨機變量那么單個維度乘積的均值是0、方差是1對d_k個維度的點積結果來說方差會累積到d_k。如果不對點積做縮放當d_k變大時點積數(shù)值的方差也會變大。Softmax的輸入一旦落到兩端飽和區(qū)梯度會變得非常小模型幾乎無法學習。除以sqrt(d_k)可以讓點積方差回到1左右讓softmax保持在梯度敏感的區(qū)間。這是基于隨機變量方差性質的推導不是拍腦袋的經驗。實際訓練中不縮放也能跑通小模型但深層模型和長序列場景下會明顯難訓。很多復現(xiàn)Transformer失敗的項目最后排查下來就是漏了這個因子或者實現(xiàn)時數(shù)據(jù)類型精度不對。2.3 多頭注意力如何讓模型同時看到多種關系一個注意力頭只能有一組線性映射也就是說它只能用一種相似度度量來衡量任意兩個token的關系。但一段文本里的關系是多種多樣的有的頭適合關注相鄰詞有的頭適合追蹤句法依存有的頭適合捕捉跨句話題。如果只用單頭模式會被迫壓縮到同一個空間里。多頭注意力把輸入投影到h個平行子空間每個頭獨立計算注意力最后拼接再經過一次輸出投影。由于每個頭的初始線性映射不同它們會被逼著分化成不同的語義角色。實驗和后來的分析都表明這種分工是自動出現(xiàn)的而不是人為指定的。Transformer原始論文里d_model512、h8、每個頭維度64這個配置到今天仍是很多模型的起點。多頭付出的額外參數(shù)不算大但讓模型表達空間立刻豐富起來這是它能以相對較低成本碾壓單頭注意力的主要原因。3. 復雜度突圍稀疏、線性與IO感知的注意力演進3.1 平方復雜度在長序列場景中先卡住顯存自注意力的直接計算復雜度是O(n2·d)n是序列長度d是特征維度。表面上看這是個“計算量”問題實際第一卡點是顯存注意力權重矩陣本身是一個n×n的矩陣需要在顯存里顯式存下來。我算過一個直觀數(shù)據(jù)n8192、float32時單層注意力矩陣就是8192×8192×4字節(jié)約268MB。如果模型有三四十層又不用任何優(yōu)化顯存很快會被中間矩陣占滿。所以當大家想把Transformer用到長文本、長視頻序列時“平方”根本不是細節(jié)而是第一堵墻。后面所有高效注意力算法目標都是拆掉這堵墻。這里容易有個誤區(qū)以為O(n2)只是慢實際上它同時限制了批量大小和序列長度。很多時候不是算不動而是顯存放不下連batch size 1都跑不了。理解這一點再看稀疏注意力和FlashAttention的動機就會清楚很多。3.2 稀疏注意力用局部全局連接近似完整關系最早被大量驗證的做法是稀疏注意力。Longformer的思路很直接保留一個滑動窗口讓每個token只看附近若干token同時額外設置少數(shù)全局token比如CLS讓信息可以通過它們跨區(qū)域傳播。BigBird在此基礎上又加了隨機連接證明窗口、隨機、全局三種模式的組合能夠在理論上逼近完整注意力的表達能力。視覺里的Swin Transformer也采用了類似哲學。它把注意力限制在局部窗口內再用窗口移位獲得跨窗口連接既把復雜度降下來了又保留了層次化的視覺感知。稀疏注意力的核心代價是必須人工決定哪些位置需要被關注。任務不同最佳模式也不同長文本問答里局部窗口可能不夠全局token的選點需要試驗圖像任務里窗口大小本身就是超參數(shù)。 它不像標準自注意力那樣“無腦”調起來更麻煩。3.3 線性注意力把softmax換成特征映射后的計算重排另一個方向是從數(shù)學上消掉n×n矩陣。完整softmax注意力要先算QK^T再softmax再乘以V。線性注意力把softmax中的指數(shù)相似度拆成兩個獨立特征映射的內積形式然后利用矩陣結合律把運算順序改成φ(Q) * (φ(K)^T * V)這樣先算φ(K)^T * V得到一個d×d的小矩陣再與φ(Q)相乘復雜度從O(n2)降到了O(n)。這類方法在超長序列檢索、DNA序列建模等場景有應用但效果普遍不如完整注意力因為它把softmax的歸一化競爭性抹掉了。沒有了歸一化模型很難通過注意力權重做“選哪個、忽略哪個”的離散判斷。我自己的經驗是線性注意力更適合序列非常長、但對質量要求不極端嚴苛的任務如果資源允許優(yōu)先嘗試FlashAttention往往更劃算。3.4 FlashAttention的真實貢獻不省計算省內存搬運FlashAttention經常被誤歸為近似注意力這其實是最大的誤解。它計算的注意力結果和標準注意力完全一致只是改變了計算順序和存儲策略。GPU有兩塊存儲片上SRAM很快但很小顯存HBM很大但慢。標準做法是頻繁把QK^T等中間矩陣寫到HBM再從HBM讀出來一遍遍搬運。FlashAttention把Q、K、V分塊放到SRAM里每個block內做完整softmax再用online softmax的思想逐步累積結果全程不落盤完整注意力矩陣。效果是顯存占用從O(n2)降到O(n)速度提升明顯。它優(yōu)化的是IO搬運而不是計算量?,F(xiàn)在主流訓練框架里FlashAttention基本可以無腦開啟這也讓長上下文在工程上變得現(xiàn)實了很多。如果項目里發(fā)現(xiàn)訓練長序列時GPU利用率低先確認是不是沒開FlashAttention開了以后瓶頸往往會從前向計算轉移到通信或數(shù)據(jù)加載這是我自己踩過的坑。4. 位置編碼演進出sin/cos、相對編碼與RoPE4.1 為什么自注意力必須額外補充位置信息自注意力有個性質如果把輸入序列打亂順序輸出也只會隨之打亂而不會改變任意兩個位置之間的關系結構。因為它只看內容相似度不看誰在誰前面。對語言來說順序就是信息?!皬埲蛄死钏摹焙汀袄钏拇蛄藦埲钡脑~完全一樣語義完全相反。所以Transformer在最初設計中就必須顯式加入位置信息。這個模塊看似配角實際撐起了今天長文本外推能力的大半。很多項目訓練時一切正常一換序列長度就崩往往就是位置編碼選型的問題。位置編碼本身也從最初的固定三角函數(shù)一路演進到可學習絕對位置編碼、相對位置編碼、旋轉位置編碼RoPE再到零參數(shù)的ALiBi。4.2 絕對位置編碼的兩種形態(tài)固定式與可學習式原始Transformer使用固定三角函數(shù)編碼不同維度用不同頻率的sin/cos生成。好處是參數(shù)少、不學習、可以嘗試外推更關鍵的是由于三角函數(shù)的和差化積公式理論上編碼后兩個位置向量的點積能包含相對位置信息。不過在深層網絡里這種相對信息能不能被有效利用并不一定。到了BERT時代大家發(fā)現(xiàn)直接用可學習的位置embedding更簡單效果當時也更好所以大量預訓練模型都采用了它??蓪W習絕對位置編碼的問題是訓練長度固定模型見過多長就只能處理多長。如果訓練時最長512推理時來了1024超出部分的位置embedding是從未訓練過的隨機值效果自然崩。后來為了讓模型能處理長文檔大家才重新轉向相對位置類編碼因為相對距離比絕對序號更容易泛化你說“隔了兩句話的關系”比說“第5個詞和第120個詞的關系”更本質。4.3 相對位置編碼與Transformer-XL的外推思路絕對位置編碼把“第i個位置”當作獨立標簽相對位置編碼則直接建?!暗趇和j個位置相距多遠”。Transformer-XL使用相對位置編碼后模型在訓練長度之外也能延續(xù)一定距離因為距離關系比絕對序號更容易遷移。T5的處理更直接給注意力分數(shù)加一個由相對距離決定的可學習bias讓模型在打分時知道兩個token離得遠還是近。這類設計的直覺是語言中“相鄰”“相隔兩個詞”“跨句”這些距離模式是穩(wěn)定的而具體出現(xiàn)在第幾段并不重要。不過相對位置編碼的實現(xiàn)細節(jié)通常更繞比如需要調整K和V的拆分方式網絡層數(shù)一變就容易搞混。我在復現(xiàn)Transformer-XL時曾花了大半天排查維度不對齊的問題原因就是相對位置索引的偏移量沒寫對。位置編碼雖然看著只有幾行代碼但確實是實現(xiàn)時最容易出錯的地方之一。4.4 RoPE為什么成了LLM的事實標準旋轉位置編碼RoPE是近幾年大模型里用得最多的位置編碼。它的核心想法很漂亮把每個位置對應的Q或K向量在高維空間里旋轉一個與該位置相關的角度。兩個旋轉后的向量做內積時旋轉不改變向量長度只改變相位所以內積結果恰好只依賴兩個位置的旋轉角之差也就是相對位置。這種設計把位置信息與注意力計算融合得不露痕跡同時具備相對位置編碼的外推優(yōu)勢。更重要的是后續(xù)對RoPE做長度外推很方便直接對旋轉角做線性插值或NTK插值就可以把模型推到訓練長度之外不需要改動模型結構。Llama、Qwen這些開源模型都用它生態(tài)工具也都對齊了所以它成為事實標準不是偶然。如果需要在超長上下文場景部署模型RoPE加插值方案是目前最成熟的方向之一。4.5 外推替代方案ALiBi如果你不想引入復雜的旋轉公式ALiBi是另一個有趣的思路。它完全不做位置embedding而是在注意力分數(shù)上直接減去一個與兩個位置距離成正比的懲罰項讓模型天然對“遠距離”降低權重。這種設計幾乎零參數(shù)在短訓練、中長推理的外推場景上表現(xiàn)不錯。我實際測評中發(fā)現(xiàn)ALiBi在需要較長外推的任務里比較省心但訓練充分的大模型里RoPE配合插值通常更穩(wěn)。位置編碼沒有銀彈關鍵是定義清楚你手里的序列長度需求和外推目標。如果訓練和推理長度一致可學習絕對位置編碼足夠如果要外推RoPE或ALiBi是更穩(wěn)的選擇。這個判斷越早做后面返工越少。5. 同是Transformer外殼內部件一直在換歸一化、激活、共享頭5.1 Post-LN到Pre-LN的穩(wěn)定化改動原始Transformer把LayerNorm放在殘差相加之后也就是Post-LN。理論上Post-LN表達能力更強因為它不對殘差路徑做額外限制但實際訓練大模型時容易不穩(wěn)定需要warmup和精細調參。后來GPT-2和很多開源模型改用Pre-LN先對輸入做LayerNorm再進行注意力或前饋網絡最后殘差直接相加。Pre-LN的殘差路徑更干凈梯度更容易跨層流動訓練更穩(wěn)定。代價是模型最終效果可能略弱于Post-LN但和“能不能訓起來”相比這個代價非常好接受。工程上我見過不少照著原始Transformer搭模型的朋友第一版堆不出深度改成Pre-LN以后幾十層就能穩(wěn)定跑了。現(xiàn)在看主流LLM的開源代碼幾乎都是Pre-LN或者它的變體。如果你自己從零訓練Transformer先把這一步改對比調一堆學習率更有效。5.2 從LayerNorm到RMSNorm的一步簡化LayerNorm要計算均值和方差然后做歸一化。RMSNorm的研究者發(fā)現(xiàn)均值那一步其實可以省掉只要用RMS均方根做縮放就足夠穩(wěn)定而且省了不少計算。聽起來像小改動但對幾十億參數(shù)模型來說省一個reduce對訓練吞吐是有實際影響的。LLaMA系列用的就是RMSNorm。從算法演進角度看RMSNorm少了一次中心化偏移的可學習參數(shù)也少了一層統(tǒng)計耦合訓練時更干脆。如果你的模型在訓練時發(fā)現(xiàn)LayerNorm統(tǒng)計均值長期偏離0仿照RMSNorm砍掉中心化通常會更快收斂。當然這不是萬能技巧但在很多場景下確實能讓歸一化這塊更簡潔。現(xiàn)在新開源模型普遍用RMSNorm也說明這種簡化在工程上是劃算的。5.3 激活函數(shù)ReLU到GELU、SwiGLU的演進Transformer前饋網絡里的激活函數(shù)也在演進。原始論文用ReLU簡單高效但負數(shù)區(qū)域梯度完全為0容易造成神經元死亡。BERT和GPT-1開始用GELU它用標準正態(tài)累積分布做平滑門控0附近不是尖點梯度更連續(xù)訓練更穩(wěn)。后來PaLM、LLaMA、很多LLM用SwiGLU把門控線性單元和Swish組合起來等于一個分支負責“內容”另一個分支負責“門控”。SwiGLU在同等計算量下通常能帶來穩(wěn)定的效果提升但會額外增加參數(shù)。實際使用時常常要把中間層維度縮小比如從4倍降到約2.67倍來抵消參數(shù)增量。這里給個參數(shù)建議表激活函數(shù)典型中間層倍數(shù)特點ReLU4倍簡單快速容易神經元死亡GELU4倍平滑梯度預訓練更穩(wěn)SwiGLU約2.67倍門控機制效果好但參數(shù)多這個維度調整看起來小但對訓練吞吐影響很大。我見過有人把SwiGLU的中間層繼續(xù)設成4倍結果參數(shù)量爆炸訓練速度直線下降效果卻沒提升。激活函數(shù)選型時一定要連同維度一起看。5.4 從MHA到MQA/GQA推理成本驅動的頭結構變化注意力頭結構的最大演進動力來自推理階段的KV cache。標準多頭注意力MHA每個頭都獨立存K和V序列越長顯存越大。推理時這些KV要一直存在所以有人做了MQA讓所有頭共享同一個K和V。共享以后KV cache大幅縮小但表達能力下降模型質量可能有折扣。折中方案是GQA把注意力頭分成若干組組內共享一組K/V。GQA在質量和KV cache之間取得了平衡比如Llama 2 70B就用了GQA。如果你在做長上下文服務的部署KV cache是繞不開的工程問題。MQA/GQA這類結構改動遠比單純加顯存更實際。下面這張表可以幫你快速決策類型K/V共享方式KV cache開銷適用場景MHA每頭獨立最高訓練階段追求表達上限MQA所有頭共享一組最低輕量推理接受質量回落GQA組內共享折中生成式LLM質量與顯存平衡實際開發(fā)時訓練階段可以用MHA充分訓練推理階段再做GQA轉換或量化這種思路在一些部署實踐中已經很常見。不過要注意訓練和推理的注意力頭配置不一致時需要做參數(shù)重構不能簡單改名了事。6. 范式位移Decoder-only與條件計算帶來的新問題6.1 BERT與GPT左右兩條路的結果從Transformer衍生出來的早期路線分兩支。BERT走Encoder-only架構用雙向上下文預訓練在GLUE、SQuAD等理解類任務上統(tǒng)治了很久。GPT走Decoder-only架構用因果語言模型做生成一開始更擅長續(xù)寫。當時很多研究者的判斷是兩種架構各司其職理解歸BERT生成歸GPT。后來的發(fā)展大家都清楚生成式AI成為大模型主流后兩邊在規(guī)模、生態(tài)、社區(qū)投入上開始明顯傾斜。這種偏差背后有算法理念的原因BERT的預訓練目標需要額外任務頭才能遷移而GPT的自回歸目標天然把所有任務統(tǒng)一成“預測下一個token”下游使用時幾乎不需要架構改動??雌饋碇皇怯柧毮繕说牟顒e實際變成了整個產品形態(tài)的差別。6.2 為什么生成式大模型把Decoder-only當成默認架構除了統(tǒng)一任務很方便Decoder-only在工程上也更好擴展。因果注意力意味著所有位置只看左側顯存中KV的形態(tài)整齊推理時逐token生成天然符合KV cache的更新方式。Encoder-Decoder架構雖然雙向理解更強但生成時仍然要從Decoder走一遍編碼端和解碼端的調度更復雜推理開銷也更大。再加上近年一些對照實驗顯示在同等參數(shù)量和訓練數(shù)據(jù)下Decoder-only在下游任務上比Encoder-Decoder不弱甚至更強。這直接推動元模型、Llama、Qwen等幾乎所有主流大模型都選了Decoder-only。倒不是說Encoder-Decoder沒有價值而是在當前規(guī)?;傻姆妒街蠨ecoder-only的工程優(yōu)勢太明顯。如果只是做純理解任務Encoder-only依舊有其價值但如果你要做一個通用助手Decoder-only幾乎是最省事的起點。6.3 MoE、多模態(tài)等架構層面的新變量說Transformer架構演進還不能不提MoE。MoE不是改注意力算法而是把FFN層換成多個專家網絡并通過門控網絡對每個token動態(tài)選擇專家。它以條件計算的方式讓模型參數(shù)量大幅增加但單次推理只激活一部分參數(shù)。Mixtral、DeepSeek等模型把MoE和Transformer結合后長上下文的性價比進一步提升。多模態(tài)方向則出現(xiàn)把圖像、音頻都當作token序列輸入到Transformer的做法。核心算法時代的很多技巧都能原樣保留只是模態(tài)編碼器不同。這些都說明Transformer的核心算法演進不會停在“注意力本身怎么算”而會在“結構算法如何匹配實際算力”上繼續(xù)延伸。我入行這幾年最大的感受是很多看似理論優(yōu)雅的演進最初都來自工程上的“卡脖子”問題。FlashAttention來自顯存瓶頸Pre-LN來自深度訓練不穩(wěn)定GQA來自推理KV cache膨脹。如果你自己做項目別急著追新模塊先看看當前流程卡在哪一層序列一長就崩優(yōu)先看注意力復雜度模型越深越難收斂優(yōu)先看歸一化和殘差服務端KV cache太吃顯存優(yōu)先看GQA。按這個思路去選架構算法比復制別人的配置要有效得多。這也是我把前面那些演進串成一條邏輯線的意義把每個新模塊的名字都還原成它原本要解決的問題用的時候自然知道怎么選。