首頁  >  文章  >  科技週邊  >  大語言模型中常用的旋轉位置編碼RoPE詳解:為什麼它比絕對或相對位置編碼更好?

大語言模型中常用的旋轉位置編碼RoPE詳解:為什麼它比絕對或相對位置編碼更好?

王林
王林轉載
2024-04-01 20:19:01419瀏覽

自2017年發表的「Attention Is All You Need」論文以來,Transformer架構一直是自然語言處理(NLP)領域的基石。它的設計多年來基本上沒有變化,隨著旋轉位置編碼(RoPE)的引入,2022年標誌著該領域的重大發展。

旋轉位置嵌入是最先進的 NLP 位置嵌入技術。大多數流行的大型語言模型(如 Llama、Llama2、PaLM 和 CodeGen)已經在使用它。在本文中,我們將深入探討什麼是旋轉位置編碼,以及它們如何巧妙地整合絕對位置嵌入和相對位置嵌入的優點。

大語言模型中常用的旋轉位置編碼RoPE詳解:為什麼它比絕對或相對位置編碼更好?

位置編碼的需求

為了理解RoPE 的重要性,我們先回顧為什麼位置編碼至關重要。 Transformer 模型根據其固有的設計,不會考慮輸入標記的順序。

例如,像「the dog chases the pig 」和「the pig chases the dogs」這樣的短語雖然含義不同,但由於它們被視為一組無序的標記,因此被視為無法區分。為了維護序列資訊及其意義,需要一個表示來將位置資訊整合到模型中。

絕對位置編碼

為了對句子中的位置進行編碼,需要使用具有相同維度的向量的另一個工具,其中每個向量代表句子中的一個位置。例如,在句子中的第二個單字指定特定向量。因此,每個句子位置都有其獨特的向量。然後透過將單字嵌入與其對應位置的嵌入結合起來,來形成Transformer層的輸入。

有兩種主要方法來產生這些嵌入:

  1. #從資料中學習:在這裡,位置向量是在訓練過程中學習的,就像其他模型參數一樣。我們為每個位置(例如從 1 到 512)學習一個唯一的向量。這引入了一個限制——最大序列長度受到限制。如果模型僅學習到位置 512,則它無法表示比該位置更長的序列。
  2. 正弦函數:此方法涉及使用正弦函數為每個位置建立唯一的嵌入。儘管這種構造的細節很複雜,但它本質上為序列中的每個位置提供了獨特的位置嵌入。實證研究表明,從數據中學習和使用正弦函數可以在現實世界模型中提供相當的性能。

絕對位置編碼的限制

#儘管使用廣泛但絕對位置嵌入也並非沒有缺點:

  1. #有限序列長度:如上所述,如果模型學習到某個點的位置向量,它本質上不能表示超出該限制的位置。
  2. 位置嵌入的獨立性:每個位置嵌入都是獨立於其他位置嵌入的。這意味著在模型看來,位置 1 和 2 之間的差異與位置 2 和 500 之間的差異相同。但其實位置 1 和 2 應該比位置 500 相關性更密切,位置 500  距離明顯更遠。這種相對定位的缺乏可能會阻礙模型理解語言結構的細微差別的能力。

相對位置編碼

相對位置不是專注於句子中記的絕對位置,而是專注於記對之間的距離。此方法不會直接在詞向量中加入位置向量。而是改變了注意力機制以納入相對位置資訊。

T5(Text-to-Text Transfer Transformer)是利用相對位置嵌入的著名模型。 T5 引入了一種處理位置資訊的微妙方式:

  • 位置偏移的偏差: T5 使用偏差(浮點數)來表示每個可能的位置偏移。例如,偏差 B1 可能表示任意兩個相距一個位置的標記之間的相對距離,無論它們在句子中的絕對位置如何。
  • 自註意力層中的整合:此相對位置偏差矩陣被加入到自註意力層中的查詢矩陣和關鍵矩陣的乘積中。這確保了相同相對距離的標記始終由相同的偏差表示,無論它們在序列中的位置如何。
  • 可擴展性:此方法的一個顯著優點是其可擴展性。它可以擴展到任意長的序列,這比絕對位置嵌入有明顯的優勢。

相對位置編碼的限制

大語言模型中常用的旋轉位置編碼RoPE詳解:為什麼它比絕對或相對位置編碼更好?

#

儘管它們在理論上很有吸引力,但相對位置編碼得問題很嚴重

  1. #計算效率低下:必須創建成對的位置編碼矩陣,然後執行大量張量操作以獲得每個時間步的相對位置編碼。特別是對於較長的序列。這主要是由於自註意力層中的額外計算步驟,其中位置矩陣被添加到查詢鍵矩陣中。
  2. 鍵值快取所使用的複雜性:由於每個附加令牌都會改變每個其他令牌的嵌入,這使得 Transformer 中鍵值快取的有效使用變得複雜。 使用KV 快取的一項要求是已經產生的單字的位置編碼, 在產生新單字時不改變(絕對位置編碼提供)因此相對位置編碼不適合推理,因為每個標記的嵌入會隨著每個新時間步的變化而改變。

由於這些工程複雜性,位置編碼未被廣泛採用,特別是在較大的語言模型中。

旋轉位置編碼 (RoPE)?

RoPE  代表了一種編碼位置資訊的新方法。傳統方法中無論是絕對方法或相對方法,都有其限制。絕對位置編碼為每個位置分配一個唯一的向量,雖然簡單但不能很好地擴展並且無法有效捕獲相對位置;相對位置編碼關注標記之間的距離,增強模型對標記關係的理解,但使模型架構複雜化。

RoPE巧妙地結合了兩者的優點。允許模型理解標記的絕對位置及其相對距離的方式對位置資訊進行編碼。這是透過旋轉機制實現的,其中序列中的每個位置都由嵌入空間中的旋轉表示。 RoPE 的優雅之處在於其簡單性和高效性,這使得模型能夠更好地掌握語言語法和語義的細微差別。

旋轉矩陣源自於我們在高中學到的正弦和餘弦的三角性質,使用二維矩陣應該足以獲得旋轉矩陣的理論,如下所示!

大語言模型中常用的旋轉位置編碼RoPE詳解:為什麼它比絕對或相對位置編碼更好?

我們看到旋轉矩陣保留了原始向量的大小(或長度),如上圖中的「r」所示,唯一改變的是與x軸的角度。

RoPE 引進了一個新穎的概念。它不是添加位置向量,而是對詞向量應用旋轉。旋轉角度 (θ) 與單字在句子中的位置成正比。第一個位置的向量旋轉 θ,第二個位置的向量旋轉 2θ,依此類推。這個方法有幾個好處:

  1. 向量的穩定性:在句子末尾加上標記不會影響開頭單字的向量,有利於高效快取.
  2. 相對位置的保留:如果兩個單字在不同的上下文中保持相同的相對距離,則它們的向量將旋轉相同的量。這確保了角度以及這些向量之間的點積保持恆定

RoPE 的矩陣公式

大語言模型中常用的旋轉位置編碼RoPE詳解:為什麼它比絕對或相對位置編碼更好?

RoPE的技術實作涉及旋轉矩陣。在 2D 情況下,論文中的方程式包含一個旋轉矩陣,該矩陣將向量旋轉 Mθ 角度,其中 M 是句子中的絕對位置。這種旋轉應用於 Transformer 自註意力機制中的查詢向量和鍵向量。

對於更高維度,向量被分成 2D 區塊,並且每對獨立旋轉。這可以被想像成一個在空間中旋轉的 n 維。聽著這個方法好好像實作是複雜,其實不然,這在 PyTorch 等函式庫只需要大約十行程式碼就可以有效率的實作。

import torch import torch.nn as nn  class RotaryPositionalEmbedding(nn.Module): def __init__(self, d_model, max_seq_len): super(RotaryPositionalEmbedding, self).__init__()  # Create a rotation matrix. self.rotation_matrix = torch.zeros(d_model, d_model, device=torch.device("cuda")) for i in range(d_model): for j in range(d_model): self.rotation_matrix[i, j] = torch.cos(i * j * 0.01)  # Create a positional embedding matrix. self.positional_embedding = torch.zeros(max_seq_len, d_model, device=torch.device("cuda")) for i in range(max_seq_len): for j in range(d_model): self.positional_embedding[i, j] = torch.cos(i * j * 0.01)  def forward(self, x): """Args:x: A tensor of shape (batch_size, seq_len, d_model). Returns:A tensor of shape (batch_size, seq_len, d_model)."""  # Add the positional embedding to the input tensor. x += self.positional_embedding  # Apply the rotation matrix to the input tensor. x = torch.matmul(x, self.rotation_matrix)  return x
#

大語言模型中常用的旋轉位置編碼RoPE詳解:為什麼它比絕對或相對位置編碼更好?

为了旋转是通过简单的向量运算而不是矩阵乘法来执行。距离较近的单词更有可能具有较高的点积,而距离较远的单词则具有较低的点积,这反映了它们在给定上下文中的相对相关性。

大語言模型中常用的旋轉位置編碼RoPE詳解:為什麼它比絕對或相對位置編碼更好?

使用 RoPE 对 RoBERTa 和 Performer 等模型进行的实验表明,与正弦嵌入相比,它的训练时间更快。并且该方法在各种架构和训练设置中都很稳健。

最主要的是RoPE是可以外推的,也就是说可以直接处理任意长的问题。在最早的llamacpp项目中就有人通过线性插值RoPE扩张,在推理的时候直接通过线性插值将LLAMA的context由2k拓展到4k,并且性能没有下降,所以这也可以证明RoPE的有效性。

代码如下:

import transformers  old_init = transformers.models.llama.modeling_llama.LlamaRotaryEmbedding.__init__ def ntk_scaled_init(self, dim, max_position_embeddings=2048, base=10000, device=None): #The method is just these three linesmax_position_embeddings = 16384a = 8 #Alpha valuebase = base * a ** (dim / (dim-2)) #Base change formula old_init(self, dim, max_position_embeddings, base, device)   transformers.models.llama.modeling_llama.LlamaRotaryEmbedding.__init__ = ntk_scaled_init

总结

旋转位置嵌入代表了 Transformer 架构的范式转变,提供了一种更稳健、直观和可扩展的位置信息编码方式。

RoPE不仅解决了LLM context过长之后引起的上下文无法关联问题,并且还提高了训练和推理的速度。这一进步不仅增强了当前的语言模型,还为 NLP  的未来创新奠定了基础。随着我们不断解开语言和人工智能的复杂性,像 RoPE 这样的方法将有助于构建更先进、更准确、更类人的语言处理系统。

以上是大語言模型中常用的旋轉位置編碼RoPE詳解:為什麼它比絕對或相對位置編碼更好?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:51cto.com。如有侵權,請聯絡admin@php.cn刪除