位置編碼(Positional Encoding)

在大語言模型(LLM)中,位置編碼(Positional Encoding)是用于表示輸入序列中詞匯或標(biāo)記相對位置的技術(shù)。由于Transformer架構(gòu)本身并沒有內(nèi)建順序信息,位置編碼是為了讓模型能夠理解詞與詞之間的順序關(guān)系。以下是一些常用的位置編碼方法:

一、常用位置編碼

1. 固定位置編碼(Sinusoidal Position Encoding)

由Vaswani等人在《Attention is All You Need》論文中提出,是Transformer模型中的經(jīng)典位置編碼方法。
使用正弦(sine)和余弦(cosine)函數(shù)生成不同頻率的編碼:


Sinusoidal Position Encoding formula.png

其中,pos是位置,i是維度索引,d是嵌入的維度大?。╡mbedding的shape)。

  • 優(yōu)點(diǎn):
    • 可外推能力強(qiáng):即使輸入序列長度大于訓(xùn)練長度,編碼依然有效。
    • 無需學(xué)習(xí)參數(shù):位置編碼是由公式生成,不增加模型參數(shù)量。
    • 可解釋性強(qiáng):具有周期性和規(guī)律性,在數(shù)學(xué)上可以分析和理解
  • 缺點(diǎn):
    • 缺乏靈活性:無法針對特定任務(wù)或數(shù)據(jù)學(xué)習(xí)更有效的位置表示。
    • 固定模式可能不適配任務(wù)需求:對某些結(jié)構(gòu)信息復(fù)雜的任務(wù)可能表達(dá)力不足。
    • 與詞嵌入無耦合學(xué)習(xí):與 token embedding 是分離的,無法共同優(yōu)化。

2. 學(xué)習(xí)型位置編碼(Learnable Position Encoding)

在這種方法中,位置編碼作為模型的可訓(xùn)練參數(shù)來學(xué)習(xí),而不是使用固定的公式生成。
每個位置有一個對應(yīng)的嵌入向量,訓(xùn)練過程中這些向量與其他詞嵌入一起進(jìn)行優(yōu)化。

  • 優(yōu)點(diǎn):
    • 可任務(wù)自適應(yīng)學(xué)習(xí):模型可以根據(jù)任務(wù)自動調(diào)整位置編碼,提高性能。
    • 表達(dá)能力更強(qiáng):位置表示可嵌入特定語言模式,適合結(jié)構(gòu)復(fù)雜的語言任務(wù)。
    • 與詞嵌入一起學(xué)習(xí)優(yōu)化:能與 token embedding 一起訓(xùn)練,形成更合理的上下文表示。
  • 缺點(diǎn):
    • 無法外推:訓(xùn)練時(shí)只學(xué)習(xí)固定長度(如 512、1024)的位置信息,超長序列無法處理。
    • 增加參數(shù)量:每一個位置都要存儲一個向量,位置越多,參數(shù)越多。
    • 不具備可解釋性:學(xué)習(xí)結(jié)果較難解讀,缺乏數(shù)學(xué)解釋性。

3. 相對位置編碼(Relative Position Encoding)

這種方法不直接編碼絕對位置,而是編碼詞語間的相對距離。通過這種方式,模型能夠?qū)W⒂诓蹲皆~之間的相對關(guān)系,而不僅僅是其絕對位置。
一種流行的實(shí)現(xiàn)方法是通過 相對位置注意力(Relative Attention),例如 T5 和 Transformer-XL 中的實(shí)現(xiàn)。

  • 優(yōu)點(diǎn):
    • 能夠更好地處理變長輸入序列。
    • 相對位置使得模型能更好地捕捉詞語間的關(guān)系,而不僅僅是位置。
  • 缺點(diǎn):
    • 可能需要額外的計(jì)算和復(fù)雜的模型設(shè)計(jì)。

4. 旋轉(zhuǎn)位置編碼(Rotary Position Encoding, RoPE)

旋轉(zhuǎn)位置編碼是一種創(chuàng)新的相對位置編碼方法,通過旋轉(zhuǎn)嵌入向量來傳遞位置信息。這種方法在 GPT-3 和一些最新的大型預(yù)訓(xùn)練模型中得到了應(yīng)用。

  • 優(yōu)點(diǎn):
    • 更加有效地表示位置間的相對關(guān)系,尤其是在長序列中。
    • 在長文本任務(wù)中表現(xiàn)更好。
  • 缺點(diǎn):
    可能需要更復(fù)雜的數(shù)學(xué)理解和實(shí)現(xiàn)。

5. 絕對+相對位置編碼混合(Absolute and Relative Position Encoding Mix)

一些最新的研究提出將絕對位置編碼與相對位置編碼結(jié)合使用。例如,DeBERTa(Decoding-enhanced BERT with disentangled attention)模型采用了這種混合方法。

  • 優(yōu)點(diǎn):
    • 結(jié)合了兩種編碼的優(yōu)勢,能兼顧序列的絕對和相對結(jié)構(gòu)信息。
  • 缺點(diǎn):
    • 需要更多的參數(shù)和計(jì)算資源。

6. 全局位置編碼(Global Contextual Position Encoding)

這是一種嘗試捕捉全局上下文信息的編碼方法,例如通過全局注意力機(jī)制來編碼位置信息。這種方法能夠處理長文本并保留文本的全局結(jié)構(gòu)。

  • 優(yōu)點(diǎn):
    • 可以更好地處理長文本和全局依賴關(guān)系。
  • 缺點(diǎn):
    • 實(shí)現(xiàn)復(fù)雜且需要更多計(jì)算資源。

7. 結(jié)構(gòu)化位置編碼(Structural Position Encoding)

該方法通過編碼更為復(fù)雜的結(jié)構(gòu)信息,如句法結(jié)構(gòu)、樹形結(jié)構(gòu)等,以增強(qiáng)模型對句法結(jié)構(gòu)的理解。
這種方法更多應(yīng)用于圖神經(jīng)網(wǎng)絡(luò)(GNN)與自然語言處理結(jié)合的模型中。

  • 優(yōu)點(diǎn):
    • 能更好地捕捉句法或語義關(guān)系。
  • 缺點(diǎn):
    • 對輸入結(jié)構(gòu)的要求更高,且模型更復(fù)雜。

8. 稀疏位置編碼(Sparse Position Encoding)

為了應(yīng)對長文本序列中的位置編碼問題,稀疏位置編碼只為特定位置編碼,而不為每個位置都提供編碼,從而減少計(jì)算量。
這種方法在某些長文本模型中得到了應(yīng)用,比如Sparse Transformer。

  • 優(yōu)點(diǎn):
    • 降低了計(jì)算復(fù)雜度,特別是在長序列處理中。
  • 缺點(diǎn):
    • 可能喪失某些細(xì)粒度的位置信息。

總結(jié)
固定位置編碼(Sinusoidal)和學(xué)習(xí)型位置編碼是最常見的基礎(chǔ)方法,廣泛應(yīng)用于多種任務(wù)。
相對位置編碼和旋轉(zhuǎn)位置編碼則主要應(yīng)用于長序列處理和模型優(yōu)化中,尤其是對于GPT等模型。
更高級的技術(shù)如全局位置編碼和稀疏位置編碼等在特定任務(wù)中能提供更強(qiáng)的性能,尤其是在長序列的處理上。
選擇哪種位置編碼方法,通常取決于任務(wù)的需求、序列長度以及計(jì)算資源的限制。

二、用python實(shí)現(xiàn)

1. 固定位置編碼

import numpy as np
import matplotlib.pyplot as plt

def positional_encoding(seq_len, d_model):
    """
    生成固定位置編碼(Sinusoidal Position Encoding)
    
    Parameters:
        seq_len (int): 輸入序列的長度
        d_model (int): 嵌入的維度大小
    
    Returns:
        np.ndarray: 形狀為 (seq_len, d_model) 的位置編碼矩陣
    """
    # 創(chuàng)建位置編碼矩陣,seq_len是序列長度,d_model是每個位置的編碼維度
    pe = np.zeros((seq_len, d_model))
    
    # 計(jì)算位置編碼
    position = np.arange(0, seq_len)[:, np.newaxis]  # 位置索引
    div_term = np.exp(np.arange(0, d_model, 2) * -(np.log(10000.0) / d_model))  # 用于縮放的除數(shù)
    
    # 填充偶數(shù)維度(sin)和奇數(shù)維度(cos)
    pe[:, 0::2] = np.sin(position * div_term)  # 偶數(shù)列使用正弦
    pe[:, 1::2] = np.cos(position * div_term)  # 奇數(shù)列使用余弦
    
    return pe

# 示例
seq_len = 10  # 輸入序列長度
d_model = 16  # 嵌入維度

# 生成位置編碼
pe = positional_encoding(seq_len, d_model)

# 打印位置編碼
print("Position Encoding Matrix (shape: {}, {}):".format(pe.shape[0], pe.shape[1]))
print(pe)

# 可視化位置編碼
plt.imshow(pe, cmap='viridis', aspect='auto')
plt.colorbar()
plt.title('Sinusoidal Positional Encoding')
plt.xlabel('Embedding Dimensions')
plt.ylabel('Sequence Position')
plt.show()
Sinusoidal Position Encoding.png

2. 旋轉(zhuǎn)位置編碼

旋轉(zhuǎn)位置編碼(Rotary Positional Encoding, RoPE)是一種在Transformer模型中用于表示位置信息的技術(shù),其核心思想是通過對詞向量進(jìn)行旋轉(zhuǎn)操作來表示位置信息,而不是像傳統(tǒng)的正弦余弦位置編碼那樣通過直接加和位置向量。

RoPE 主要用于 增強(qiáng) Transformer 模型對相對位置的敏感性,特別是在處理長序列時(shí),它避免了傳統(tǒng)位置編碼的限制。RoPE 的一個關(guān)鍵特性是使用旋轉(zhuǎn)變換來計(jì)算每個位置的編碼,因此具有更好的擴(kuò)展性。

RoPE 的公式
對于每個位置 pos 和維度 i,RoPE 會計(jì)算一個旋轉(zhuǎn)矩陣并應(yīng)用于輸入的詞嵌入。這種旋轉(zhuǎn)通常在頻域上進(jìn)行,在不同維度上應(yīng)用不同的旋轉(zhuǎn)角度。

具體公式如下:


RoPE formula.png

其中,θ_i 是用于旋轉(zhuǎn)的角度。

import numpy as np

def rotary_position_encoding(seq_len, dim, base=10000.0):
    """
    生成 RoPE (Rotary Position Encoding) 編碼。
    
    參數(shù):
    - seq_len: 序列的最大長度(位置數(shù))
    - dim: 詞嵌入的維度
    - base: 頻率基準(zhǔn)(默認(rèn)10000)
    
    返回:
    - position_encoding: shape (seq_len, dim),位置編碼矩陣
    """
    # 創(chuàng)建位置(從0到seq_len-1)
    positions = np.arange(seq_len)
    
    # 計(jì)算每個維度的頻率
    freqs = np.arange(0, dim, 2)
    div_term = np.exp(-np.log(base) * freqs / dim)
    
    # 創(chuàng)建 RoPE 編碼矩陣
    position_encoding = np.zeros((seq_len, dim))
    
    for i in range(0, dim, 2):
        # 使用sin和cos函數(shù)來計(jì)算旋轉(zhuǎn)位置編碼
        pos = positions * div_term[i//2]
        position_encoding[:, i] = np.cos(pos)  # 偶數(shù)維度
        position_encoding[:, i+1] = np.sin(pos)  # 奇數(shù)維度
    
    return position_encoding

# 示例
seq_len = 10  # 序列長度
dim = 16      # 嵌入維度

position_encoding = rotary_position_encoding(seq_len, dim)
print(position_encoding)

QA

Q1. 位置編碼的shape需要和embedding的shape相同嗎

A: 是的,位置編碼的形狀(shape)需要與詞嵌入的形狀一致。這是因?yàn)槲恢镁幋a是加到詞嵌入上的,它需要與每個單詞的詞嵌入(即詞向量)在維度上匹配,從而確保它們能夠按元素相加。

Q2. 學(xué)習(xí)型位置編碼 在推理的時(shí)候可以擴(kuò)展嗎?

A: 在Transformer模型中,位置編碼的作用是提供每個詞在序列中的位置信息。傳統(tǒng)的固定位置編碼(如正弦/余弦位置編碼)具有固定的形狀,它在訓(xùn)練期間是預(yù)先計(jì)算好的,并且可以在推理時(shí)直接使用。然而,學(xué)習(xí)型位置編碼(Learnable Positional Encoding)是通過訓(xùn)練學(xué)習(xí)到的,它可以根據(jù)訓(xùn)練數(shù)據(jù)自適應(yīng)地調(diào)整,而不是依賴固定的公式。

關(guān)于學(xué)習(xí)型位置編碼在推理時(shí)是否可以擴(kuò)展,主要取決于兩方面:

位置編碼的學(xué)習(xí)方式:

學(xué)習(xí)型位置編碼是通過優(yōu)化目標(biāo)函數(shù)(例如,損失函數(shù))在訓(xùn)練過程中學(xué)習(xí)得到的。這些位置編碼通常是一個可學(xué)習(xí)的矩陣,其維度通常是 (seq_len, d_model),其中seq_len是序列的長度,d_model是嵌入的維度。在訓(xùn)練時(shí),模型會將這些位置編碼與詞嵌入相加,幫助模型學(xué)習(xí)每個詞的順序信息。
推理時(shí)的擴(kuò)展:通常,學(xué)習(xí)型位置編碼會在訓(xùn)練時(shí)有一個固定的最大序列長度。因?yàn)槟P偷妮斎胪ǔJ且粋€有限長度的序列,在訓(xùn)練時(shí)位置編碼矩陣的大小是固定的(比如max_seq_len x d_model)。在推理時(shí),如果輸入序列長度超過了訓(xùn)練時(shí)的最大序列長度,就會遇到問題。
推理時(shí)的擴(kuò)展策略:

直接擴(kuò)展:如果模型在推理時(shí)的輸入序列長度超過了訓(xùn)練時(shí)的最大序列長度,簡單的擴(kuò)展學(xué)習(xí)型位置編碼是不可行的,因?yàn)閷W(xué)習(xí)型位置編碼是依賴于訓(xùn)練時(shí)的序列長度的,無法直接通過線性插值或重復(fù)來擴(kuò)展。

可能的解決方法:

使用相同的編碼:一種簡單的策略是,將學(xué)習(xí)型位置編碼中的最后一個位置編碼重復(fù)或復(fù)制到超出訓(xùn)練時(shí)最大長度的位置,直到達(dá)到推理時(shí)的最大序列長度。雖然這種方式較為粗糙,但在一些任務(wù)中可能能接受。

插值(Interpolation):另一種方法是對學(xué)習(xí)型位置編碼進(jìn)行插值。比如在推理時(shí),當(dāng)輸入序列長度超過訓(xùn)練時(shí)的最大長度時(shí),可以根據(jù)現(xiàn)有的學(xué)習(xí)型位置編碼,使用插值(如線性插值)生成新的位置編碼,這樣可以在一定程度上避免丟失位置信息。不過,這種方法會增加計(jì)算復(fù)雜度,并且可能會導(dǎo)致性能下降,因?yàn)橥评頃r(shí)的編碼和訓(xùn)練時(shí)的編碼可能會存在不一致性。

訓(xùn)練時(shí)使用更大的序列長度:一種更直接的方法是在訓(xùn)練時(shí)使用足夠大的序列長度,以保證在推理時(shí)輸入序列不會超過最大序列長度。這種方法可以避免推理時(shí)的擴(kuò)展問題,但會增加訓(xùn)練時(shí)的計(jì)算和內(nèi)存開銷。

學(xué)到的“通用”位置編碼:有些研究者嘗試學(xué)習(xí)一個更“通用”的位置編碼,能夠適應(yīng)不同長度的序列,而不僅僅是固定長度。這種方法需要在訓(xùn)練過程中使用更大范圍的序列長度,或者通過特別的技術(shù)來確保模型能應(yīng)對不同長度的序列。

總結(jié):
學(xué)習(xí)型位置編碼在推理時(shí)的擴(kuò)展不是直接支持的,因?yàn)樗鼈冊谟?xùn)練期間是學(xué)習(xí)得到的,并且通常是為訓(xùn)練時(shí)的最大序列長度而設(shè)計(jì)的。
如果在推理時(shí)輸入的序列長度超出了訓(xùn)練時(shí)的最大序列長度,可以考慮以下幾種擴(kuò)展策略:

  • 重復(fù)最后一個位置編碼:直接擴(kuò)展編碼。
  • 插值生成新的位置編碼:對原位置編碼進(jìn)行插值。
  • 訓(xùn)練時(shí)使用更長的序列:增加訓(xùn)練時(shí)的序列長度。
  • 學(xué)習(xí)更通用的位置編碼:使位置編碼能夠適應(yīng)不同長度的序列。
    在選擇具體的擴(kuò)展方法時(shí),應(yīng)該考慮任務(wù)的特性和性能需求。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容