用Python程式碼解釋大語言模型的工作原理

banq發表於2024-02-21

ChatGPT 和 GPT-4 等大型語言模型 ( LLM ) 自然語言處理的發展標誌著一個重要的里程碑,這些模型在基於文字的任務中展示了接近人類的理解能力。除此之外,OpenAI 引入的大型多模態模型 (LMM) 代表了一個顯著的轉變,使這些模型能夠處理影像和文字資料。

本文將重點關注大模型的核心文字解釋技術:標記化和標記嵌入


什麼是標記化
這是將文字分割成更小的單元(稱為標記)的過程。此步驟對於將複雜的語言結構分解為機器學習模型可以處理和理解的元素至關重要。

  • 字元級標記化是最簡單的形式,它將文字劃分為單個字元。不過,它的直接性導致標記序列較長,處理效率較低。詞級標記化是另一種形式,它將文字分割成單詞。這種方法比較直觀,但在處理大量詞彙時可能會遇到困難,而且在遇到新詞或未知詞時往往會出現問題。
  • 位元組對編碼法(BPE)是子字標記化中一種更為平衡的方法。BPE 從由訓練語料庫中所有獨特字元組成的基礎詞彙開始,確保每個單詞都能分解成這些基本單位。BPE 的核心在於其頻率分析和詞對合並方法。它透過反覆掃描語料庫來識別出現頻率最高的字元對或標記。然後將這些字元對合併成新的標記。這一步至關重要,因為它能讓模型識別併合並常見的配對,在後續處理中將其視為單一單元。這一過程會繼續進行,每次迭代都會合並下一個最常見的詞對。

BPE標記化
隨著詞彙表每次迭代,都會新增新的標記(合併對)。這個過程不斷重複,直到詞彙量達到預定的大小或所需的粒度水平。最終的詞彙量要在足夠詳細以表示複雜詞彙和足夠易於管理以高效處理之間取得平衡。

在對新文字進行標記化處理時,演算法會使用這一細化詞彙。首先,演算法會在詞庫中搜尋最大可能的標記。如果找不到匹配詞,演算法就會將文字分解成更小的單元,直到找到合適的匹配詞為止。這種方法可確保常用詞和短語被標記為更少、更大的標記,從而提高處理速度,而不常用的短語則會被進一步分解,以保證準確性。

BPE 在表示常見短語方面的效率、透過子詞單位處理罕見詞和未知詞的能力以及均衡的方法,使其在處理詞彙量大或詞形複雜的語言時特別有效。這種方法是準備資料供語言學家處理的複雜方法的典範,極大地促進了他們對人類語言的理解。

舉例說明 BPE 是如何工作的,並隨後給出一些程式碼,使這一概念更加具體:

讓我們以句子 "This is an example "為例。

  • 一開始,BPE 會將句子分解為基本單元。它不是從整個單詞開始,而是從字元或一小組字元開始。因此,
  • "This is an example"(這是一個例子)首先會被標記為 "T"、"h"、"i"、"s "等單個字元。
  • 然後,BPE 會分析訓練資料中字元對的頻率,並開始合併最常見的字元對。例如,如果 "Th"、"is"、"an"、"ex "和 "ambu "是訓練資料中最常見的字元對,BPE 就會將它們合併為單個標記。這一過程會反覆進行,從而使 "Th"、"is"、"an"、"ex "和 "ambu "等更少、更大的標記詞代表句子。(類似壓縮,標記化其實是字串壓縮


標記嵌入
一旦完成標記化,文字的下一步就是標記嵌入,這是一個根據上下文捕獲單詞語義的過程。
該過程包括初始化嵌入、訓練模型以調整這些嵌入,以及確保語義相似的標記在嵌入空間中接近。

import numpy as np
import random

#1、詞彙和嵌入式隨機初始化
vocab = [<font>"cat""dog""animal""pet""feline""canine"]
embedding_dim = 300 # Typical dimensions range from 128 to 4096
embeddings = {word: np.random.randn(embedding_dim) for word in vocab}

#2、模擬訓練調整功能
def adjust_embeddings(embeddings, word_pairs, learning_rate=0.01):
for word1, word2 in word_pairs:
if word1 in embeddings and word2 in embeddings:
# 簡單調整:使相關詞的嵌入更接近
embedding_diff = embeddings[word1] - embeddings[word2]
embeddings[word1] -= learning_rate * embedding_diff
embeddings[word2] += learning_rate * embedding_diff

# 模擬訓練資料(與上下文相關的詞對)
related_word_pairs = [(
"cat""feline"), ("dog""canine"), ("cat""pet"), ("dog""pet")]

# Simulating training
for _ in range(1000): # Number of iterations
random.shuffle(related_word_pairs)
adjust_embeddings(embeddings, related_word_pairs)

檢查調整後的嵌入
print(
"Adjusted Embeddings for 'cat' and 'dog':")
print(
"Cat:", embeddings["cat"][:5]) # Displaying first 5 dimensions
print(
"Dog:", embeddings["dog"][:5])

程式碼說明

  • 嵌入初始化:模型詞彙表中的每個標記(單詞或子詞)都與一個嵌入相關聯,嵌入是一個高維向量。這些嵌入通常是隨機初始化的。這種隨機性為訓練過程提供了調整和細化這些向量的起點。上述程式碼定義了一個詞彙表,並隨機為每個單詞初始化嵌入,為簡單起見,將嵌入維度設定為 300。
  • 模擬訓練:在訓練過程中,模型會接觸大量文字資料。它學習根據每個標記出現的上下文來調整嵌入。此學習過程涉及反向傳播和最佳化演算法(例如隨機梯度下降或 Adam)來迭代調整嵌入以最小化模型的預測誤差。程式碼使用 adjust_embeddings 函式模擬訓練,調整相關詞對(如 "cat "和 "feline")的嵌入,使其在向量空間中更接近。這是透過迭代減少每對詞的嵌入之間的距離來實現的,模仿了 LLM 根據上下文完善標記嵌入的方式。
  • 調整嵌入與語義關係:  在相似上下文中使用的標記在向量空間中具有彼此接近的嵌入。這種接近度通常使用餘弦相似度來衡量。此過程建立一個語義圖,其中具有相似含義或用法的單詞在高維空間中彼此靠近。
  • 結果:經過多次迭代後,上下文相關詞語的嵌入在嵌入空間中被調整到彼此更接近的位置,這代表了 LLM 中上下文學習的一種基本形式。

Transformer增強上下文的解釋能力
標記嵌入為大型語言模型 (LLM) 提供了對語言上下文和含義的深入理解。 Transformer 在此基礎上並行處理這些嵌入,使用自注意力機制來辨別複雜的單詞關係。這種協同作用使大模型能夠透過對語言語義和結構的細緻理解來解釋和生成文字。

Transformers之所以比RNN有“優勢”,是因為透過注意力,它能夠做3件很酷的事情:

  • 1)基於內容的查詢(“我對類似於X的向量感興趣...”)
  • 2)絕對位置查詢(例如從句子開始的第三個單詞)
  • 3)相對位置


Transformer 採用分層架構設計,每一層都有助於處理輸入資料。每層的核心元件是自注意力機制和前饋神經網路。 Transformer 與 RNN 和 LSTM 等早期模型的區別在於它們能夠同時處理輸入序列中的所有標記。這種並行處理方法不僅提高了計算效率,而且使模型能夠更有效地捕獲資料中複雜的依賴關係和關係。

自注意力機制:

  • 每個 Transformer 層的核心是自注意力機制。該機制計算輸入序列中每個標記的所謂注意力分數。這些分數衡量模型在處理特定標記時應將多少焦點或“注意力”分配給序列中的其他標記。
  • 自注意力機制允許 Transformer 根據整個序列本身動態調整序列中每個標記的影響力。這對於理解上下文至關重要,因為它使模型能夠解釋每個標記,而不是孤立的,而是與其他標記相關聯。
  • 此外,《Transformer 》採用了所謂的“多頭注意力”。這意味著自注意力過程在每一層內並行複製多次。每個複製或​​“頭”可能會關注標記關係的不同方面,例如句法或語義連線。透過這樣做,模型可以捕獲對文字更豐富、更細緻的理解。

位置編碼:

  • Transformer 設計中的一個獨特挑戰是它們缺乏固有的序列處理能力——這是 RNN 等序列模型固有的特徵。為了解決這個問題,Transformers 使用位置編碼。這些被新增到標記嵌入中,以便為模型提供有關序列中每個標記的位置的資訊。
  • 位置編碼通常使用正弦函式生成。此方法可確保序列中的每個位置接收唯一的編碼,從而允許模型根據標記在序列中的順序來區分標記。
  • 位置資訊對於模型理解語言的流程和結構至關重要。

逐層處理:

  • 在 Transformer 模型中,每一層都會處理輸入序列,逐步轉換和細化每個標記的表示。這種轉換是由自注意力機制提供的上下文以及層內前饋網路的後續操作通知的。
  • 當輸入資料透過 Transformer 的連續層時,標記的表示變得越來越細化並豐富了上下文資訊。這種逐層處理可以實現對語言的複雜理解和生成,使模型能夠以顯著的效率和效果處理複雜的語言任務。

程式碼示例及說明
下面是一個簡化的 Python 程式碼示例,用於說明 Transformer 的自注意力機制的基本版本。 

import numpy as np
import math

def softmax(x):
return np.exp(x) / np.sum(np.exp(x), axis=0)

def scaled_dot_product_attention(Q, K, V):
# 計算 Q 和 K 的點積,並按 K 維度的平方根進行縮放
matmul_qk = np.dot(Q, K.T) / math.sqrt(K.shape[1])

# 應用 softmax 獲取注意力權重
attention_weights = softmax(matmul_qk)

# 乘以 V 得出輸出
output = np.dot(attention_weights, V)
return output, attention_weights

標記嵌入示例(隨機初始化)
token_embeddings = np.random.rand(3, 64) # 3 tokens, 64-dimensional embeddings

# 模擬查詢 (Q)、鍵 (K) 和值 (V) 矩陣
Q = token_embeddings
K = token_embeddings
V = token_embeddings

# 應用自我注意
attention_output, attention_weights = scaled_dot_product_attention(Q, K, V)

print(<font>"Attention Output:", attention_output)
print(
"Attention Weights:", attention_weights)

程式碼說明
Softmax 函式:用於對注意力分數進行歸一化處理,確保其總和為 1。

標度點積注意力:

  • 該函式是自我注意力機制的核心,用於計算注意力分數。
  • 它將查詢(Q)和關鍵字(K)矩陣的點積按關鍵字維度的平方根進行縮放,這有助於在訓練過程中穩定梯度。
  • Softmax 函式適用於這些分數,由此產生的權重用於建立一個加權和值(V),代表注意力機制的輸出。

標記嵌入:

  • 為便於說明,我們使用隨機初始化的嵌入。實際上,這些都是透過訓練學習的。
  • 為簡單起見,我們將同一組嵌入詞視為查詢、鍵和值。

輸出:

  • attention_output(注意輸出)表示應用自我注意後的轉換嵌入式。
  • attention_weights(關注權重)可以讓我們瞭解每個標記對序列中其他標記的關注程度。

透過這段程式碼,我們可以基本瞭解Transformer 中的自我關注是如何執行的。真實世界中的 Transformer 模型要複雜得多,每一層都有額外的元件,如層歸一化、殘差連線和前饋網路,所有這些對其高階效能都至關重要。

 

相關文章