Skip to content

ROPE

先備知識:Transformer 模型、自注意力機制、序列資料(如句子)、絕對位置編碼(例如三角函數編碼)的基本概念。

1. 故事背景

1-1 排隊聊天的人們

想像你正在參加一場聚會,現場有許多人排成一列,準備輪流分享故事。為了理解每個人所說的內容,你不僅需要知道他們說了什麼「詞語」,還必須知道他們在隊伍中的「順序」。例如,第一個人說「我喜歡」,第二個人說「吃蘋果」,這組成「我喜歡吃蘋果」;但如果順序顛倒,變成「吃蘋果我喜歡」,意思就完全不同了。

在自然語言處理中,Transformer 模型就像一個超級聽眾,它處理句子時,每個詞(或稱 token)都被轉換成一個向量(詞嵌入)。然而,Transformer 的核心機制——自注意力——本質上是「置換不變」的,也就是說,它把句子當作一堆詞的集合,而不考慮它們的順序。這就像聚會中,你聽到了所有人的發言,但卻不知道誰先誰後,那就無法還原出完整的故事。

1-2 最初的解決方案:發號碼牌

為了解決這個問題,研究人員最初想出了一個簡單的方法:給每個位置發一張「號碼牌」,也就是絕對位置編碼。他們用一組固定的、預先計算好的訊號(例如正弦和餘弦函數)加到詞向量上,告訴模型:「我是第一個詞」、「我是第二個詞」……這樣模型就能勉強分辨出順序。

但是,這個方法就像在每個人的額頭上貼一個號碼牌「1號」、「2號」……雖然能區分順序,但模型很難理解「相鄰」或「相隔幾個位置」這種相對關係。例如,在句子「貓追老鼠」中,「追」和「老鼠」之間的相對距離很重要,但絕對號碼牌只告訴模型「『追』是第2個詞,『老鼠』是第3個詞」,卻沒有直接強調它們是相鄰的。這使得模型在理解長距離依賴或處理比訓練時更長的句子時,表現不佳。

2. 解決的痛點

2-1 從號碼牌到旋轉指針

ROPE(旋轉位置編碼,Rotary Position Embedding)的出現,就像把「貼號碼牌」的方式,升級成了給每個人一個可以「旋轉的指針」。

想像每個人的詞向量是一根箭頭(在數學上是高維空間中的一個向量)。ROPE 的做法是:根據這個詞在句子中的位置,將這根箭頭旋轉一個特定的角度。位置越靠後,旋轉的角度越大。如此一來,兩個詞之間的相對位置,就可以透過它們箭頭之間的夾角來表示。

2-2 更自然地捕捉相對關係

這種設計帶來了一個巨大的好處:當我們計算兩個詞的注意力分數時(通常是點積),結果會自然地依賴於它們之間的「相對位置差」,而不是絕對位置。這就像聚會中,你不需要記住每個人是幾號,只需要知道他們之間的距離,就能理解對話的連貫性。

用數學語言描述:ROPE 透過一個旋轉矩陣 \(R_{\theta, m}\) 作用在詞向量 \(x\) 上,得到位置 \(m\) 的編碼後向量: $$ \tilde{x}m = R{\theta, m} x $$ 而兩個位置 \(m\)\(n\) 的向量在做內積時,會出現一個與相對位置 \(m-n\) 有關的旋轉因子: $$ \langle R_{\theta, m} x, R_{\theta, n} y \rangle = \langle x, R_{\theta, n-m} y \rangle $$ 這意味著模型在計算注意力時,能直接感知到詞與詞之間的間隔,就像聽眾能輕易察覺「剛剛說話的人」和「現在說話的人」之間的關聯,而不必死記他們的號碼牌。

2-3 更強的「外推」能力

另一個重要的痛點是「外推性」(extrapolation)。傳統的絕對位置編碼,如果訓練時只看過長度 512 的句子,當遇到長度 1024 的句子時,那些 512 之後的號碼牌是模型從未見過的,表現往往會崩潰。

而 ROPE 的旋轉角度是連續的,即使位置超出訓練範圍,旋轉的規律依然存在(就像時鐘的指針會一直轉下去,不會因為超過 12 點就亂掉)。這使得模型能夠更平滑地處理更長的序列,理解從未見過的長句子,大大提升了實用性。

總之,ROPE 透過一個優雅的幾何變換,讓 Transformer 模型擺脫了對絕對號碼牌的依賴,轉而用旋轉的指針自然地感知詞語之間的相對距離,解決了傳統位置編碼在捕捉相對關係和外推長序列上的根本痛點。

3 實際案例運算

我們來當一次「數學助教」,實際動手算一遍 ROPE(旋轉位置編碼)是怎麼把位置資訊放進句子裡的。想像我們有一個超級簡單的句子,只有兩個詞:「我」和「你」。每個詞我們用一個 2 維的向量來代表(真實世界通常是幾百維,這裡簡化方便計算)。

3-1 第一層:準備好詞向量與查詢矩陣

首先,我們把「我」和「你」這兩個詞,分別用兩個 2 維向量表示。同時,我們要準備一個「查詢權重矩陣」 \(W_Q\),這個矩陣的任務是把原始的詞向量,轉換成「查詢向量」(Query, Q),也就是模型要拿來跟別人比對的問題。

3-1-1 輸入詞向量與權重矩陣

假設我們的輸入句子有兩個詞,token 1 代表「我」,token 2 代表「你」。它們的詞向量(\(x_1, x_2\))如下:

\[ \text{詞向量矩陣}\ X\ (\text{shape}=2\times 2)= \begin{bmatrix} 1 & 0 \\ 0 & 1 \end{bmatrix} \]

這裡,第一行 \([1, 0]\) 是「我」的向量,第二行 \([0, 1]\) 是「你」的向量。

我們用來生成查詢(Q)的權重矩陣 \(W_Q\) 是:

\[ W_Q\ (\text{shape}=2\times 2)= \begin{bmatrix} 1 & 0 \\ 1 & 1 \end{bmatrix} \]

3-1-2 計算初始查詢矩陣 Q

現在,我們用矩陣乘法算出所有詞的查詢向量 Q。公式是 \(Q = X \cdot W_Q\)

\[ Q\ (\text{shape}=2\times 2) = X \cdot W_Q = \begin{bmatrix} 1 & 0 \\ 0 & 1 \end{bmatrix} \cdot \begin{bmatrix} 1 & 0 \\ 1 & 1 \end{bmatrix} = \begin{bmatrix} (1\cdot1 + 0\cdot1) & (1\cdot0 + 0\cdot1) \\ (0\cdot1 + 1\cdot1) & (0\cdot0 + 1\cdot1) \end{bmatrix} = \begin{bmatrix} 1 & 0 \\ 1 & 1 \end{bmatrix} \]

這個 \(Q\) 矩陣的每一行,就是每個詞的查詢向量: * 「我」的查詢向量 \(q_1 = [1, 0]\) * 「你」的查詢向量 \(q_2 = [1, 1]\)

此時,這兩個查詢向量只包含了詞本身的語義,完全不知道它們在句子中的順序。誰先誰後?模型從 \(q_1\)\(q_2\) 看不出來。這就是我們要解決的核心痛點:缺乏位置資訊。 痛點:初始查詢向量 Q 只聚合詞義,無法區分詞在序列中的順序,導致注意力機制無法理解語序。

3-2 第二層:根據位置,旋轉查詢向量

ROPE 登場!它要做的事很直觀:根據詞的位置 \(m\),把它的查詢向量旋轉一個角度 \(m \cdot \theta\)。這裡的 \(\theta\) 是一個預先設好的角度(通常跟維度有關,我們簡單設 \(\theta = \frac{\pi}{4}\) (45度) 來計算)。

對 2 維向量 \([x, y]\) 來說,旋轉角度 \(\phi\) 的公式是: 旋轉後向量 = \([x \cdot \cos\phi - y \cdot \sin\phi, \ x \cdot \sin\phi + y \cdot \cos\phi]\)

我們的位置 m 從 0 開始算: * 詞 1(「我」,\(m=0\)):旋轉角度 \(\phi = 0 \cdot \frac{\pi}{4} = 0\),所以向量不變。 * 詞 2(「你」,\(m=1\)):旋轉角度 \(\phi = 1 \cdot \frac{\pi}{4} = \frac{\pi}{4}\) (45度)。

3-2-1 計算旋轉後的 Q

  • 詞 1(m=0)旋轉:

    • \(\cos 0 = 1, \ \sin 0 = 0\)
    • \(q_1' = [1 \cdot 1 - 0 \cdot 0, \ 1 \cdot 0 + 0 \cdot 1] = [1, 0]\) (不變)
  • 詞 2(m=1)旋轉:

    • \(\cos\frac{\pi}{4} = \frac{\sqrt{2}}{2} \approx 0.707, \ \sin\frac{\pi}{4} = \frac{\sqrt{2}}{2} \approx 0.707\)
    • 原向量 \(q_2 = [1, 1]\)
    • \(q_2' = [1 \cdot 0.707 - 1 \cdot 0.707, \ 1 \cdot 0.707 + 1 \cdot 0.707]\)
    • \(q_2' = [0.707 - 0.707, \ 0.707 + 0.707] = [0, 1.414]\)

所以,經過 ROPE 之後,我們得到新的查詢矩陣 \(Q'\)

\[ Q'\ (\text{shape}=2\times 2)= \begin{bmatrix} 1 & 0 \\ 0 & 1.414 \end{bmatrix} \]

「我」的向量從 \([1, 0]\) 變成 \([1, 0]\) (沒動),「你」的向量從 \([1, 1]\) 變成 \([0, 1.414]\)。透過旋轉,我們把位置 1 的資訊編碼進了「你」的向量中。 痛點:透過旋轉操作,將絕對位置 \(m\) 轉換為幾何角度,注入到詞向量中,解決了位置資訊缺失的問題。這是 ROPE 的核心。

3-3 第三層:同樣方法處理鍵矩陣 K,並計算注意力

跟查詢 Q 一樣,我們也需要對「鍵」(Key, K)做同樣的旋轉操作,這樣在後續計算查詢和鍵的相似度(點積)時,才能自然體現出相對位置。

3-3-1 計算並旋轉 K 矩陣

我們需要另一個權重矩陣 \(W_K\) 來生成 K。假設: $$ W_K (\text{shape}=2\times 2)= \begin{bmatrix} 1 & 1 \ 0 & 1 \end{bmatrix} $$

先計算初始的 K 矩陣: $$ K (\text{shape}=2\times 2) = X \cdot W_K = \begin{bmatrix} 1 & 0 \ 0 & 1 \end{bmatrix} \cdot \begin{bmatrix} 1 & 1 \ 0 & 1 \end{bmatrix} = \begin{bmatrix} 1 & 1 \ 0 & 1 \end{bmatrix} $$ 初始的鍵向量:\(k_1 = [1, 1]\) (「我」),\(k_2 = [0, 1]\) (「你」)。

然後,對 K 應用完全相同角度的 ROPE 旋轉: * 詞 1 (m=0) 的 \(k_1\) 旋轉 0 度,不變,\(k_1' = [1, 1]\)。 * 詞 2 (m=1) 的 \(k_2\) 旋轉 45 度。 * 原向量 \(k_2 = [0, 1]\) * \(k_2' = [0 \cdot 0.707 - 1 \cdot 0.707, \ 0 \cdot 0.707 + 1 \cdot 0.707]\) * \(k_2' = [0 - 0.707, \ 0 + 0.707] = [-0.707, 0.707]\)

得到旋轉後的鍵矩陣 \(K'\): $$ K' (\text{shape}=2\times 2)= \begin{bmatrix} 1 & 1 \ -0.707 & 0.707 \end{bmatrix} $$

3-3-2 計算注意力分數(查詢與鍵的點積)

現在,我們用旋轉後的 \(Q'\)\(K'\) 來計算注意力分數 \(S = Q' \cdot (K')^T\)。這個分數代表每個詞應該放多少注意力在其他詞上。

首先,計算 \(K'\) 的轉置 \((K')^T\): $$ (K')^T (\text{shape}=2\times 2)= \begin{bmatrix} 1 & -0.707 \ 1 & 0.707 \end{bmatrix} $$

然後做矩陣乘法: $$ S = Q' \cdot (K')^T = \begin{bmatrix} 1 & 0 \ 0 & 1.414 \end{bmatrix} \cdot \begin{bmatrix} 1 & -0.707 \ 1 & 0.707 \end{bmatrix} = \begin{bmatrix} (1\cdot1 + 0\cdot1) & (1\cdot -0.707 + 0\cdot0.707) \ (0\cdot1 + 1.414\cdot1) & (0\cdot -0.707 + 1.414\cdot0.707) \end{bmatrix} $$

\[ S = \begin{bmatrix} 1 & -0.707 \\ 1.414 & 1.414\cdot0.707 \end{bmatrix} \]

計算右下角元素:\(1.414 \times 0.707 \approx 1.0\)(因為 \(\sqrt{2} \times \frac{\sqrt{2}}{2} = 1\))。所以:

\[ S\ (\text{shape}=2\times 2)= \begin{bmatrix} 1 & -0.707 \\ 1.414 & 1 \end{bmatrix} \]

3-3-3 解讀包含位置資訊的分數矩陣 S

這個 \(S\) 矩陣就是帶有位置資訊的注意力分數。我們來分析一下: * \(S_{1,1} = 1.0\):「我」對「我」自己的注意力。 * \(S_{1,2} = -0.707\):「我」對「你」的注意力。這裡是負的,代表在這種設定的權重和角度下,模型可能會減弱對後面詞的關注。 * \(S_{2,1} = 1.414\):「你」對「我」的注意力。這個分數比 1 還高!這代表了位置 1 的詞(你)在看向位置 0 的詞(我)時,因為旋轉的關係,分數被增強了。 * \(S_{2,2} = 1.0\):「你」對「你」自己的注意力。

關鍵點在於,\(S_{2,1}\)\(S_{1,2}\) 這兩個分數不對稱,而且數值直接受到相對位置 (m=1 對 m=0) 的影響。如果沒有 ROPE,在我們這個對稱的輸入(「我」=\([1,0]\),「你」=\([0,1]\))和對稱的權重(\(W_Q, W_K\))設定下,計算出的注意力分數矩陣會是對稱的,無法區分方向。但現在,分數矩陣 \(S\) 明顯不對稱,成功編碼了「誰在前,誰在後」的相對關係。 痛點:在計算注意力分數時,透過旋轉後的 Q 和 K 進行點積,分數會自然地反映詞與詞之間的相對位置差(例如 m-n),而非僅僅是絕對位置。這讓模型能更直觀地理解詞序關係,解決了傳統絕對位置編碼難以捕捉相對距離的問題。同時,旋轉的連續性也讓模型在面對比訓練時更長的句子時,能更平滑地推算位置(外推性),解決了長序列處理的痛點。