公式速查表
1. 向量與矩陣:表示、轉換與知識存儲的基礎
向量表示 (Vectors): 語義的載體
在LLM中,向量 x ∈ R d \mathbf{x}\in\mathbb{R}^d x∈Rd 是信息的基本單元,承載著豐富的語義信息:
- 詞嵌入向量 (Word Embeddings):將離散的token(如單詞"北京"或子詞"思")映射為一個稠密的高維向量(例如,BERT使用768維,GPT-3使用數千維)。這些向量是學習得到的,目標是使語義上相似的詞在向量空間中彼此靠近。例如,"國王"和"女王"的向量會比"國王"和"香蕉"的向量更接近。它們是模型處理語言的原子輸入。
- 位置編碼向量 (Positional Encodings):由于Transformer的自注意力機制本身不感知序列順序,位置編碼向量為模型提供了token在序列中的位置信息。這些向量通過固定函數(如正弦/余弦函數)生成或通過學習得到,并加到詞嵌入向量上,使得模型能夠區分"我愛北京"和"北京愛我"。
- 隱藏狀態向量 (Hidden State Vectors):在Transformer的每一層處理后,每個token的表示都會更新為一個新的隱藏狀態向量。這個向量是該token在當前上下文中的動態、情境化表示,融合了詞本身的意義、位置信息以及通過注意力機制從序列中其他token獲取的相關信息。
矩陣變換 (Matrix Transformations): 知識的編碼與特征提取
權重矩陣 W ∈ R m × n \mathbf{W}\in\mathbb{R}^{m\times n} W∈Rm×n 是模型學習和存儲知識的主體。通過線性變換 y = W x + b \mathbf{y} = \mathbf{W}\mathbf{x} + \mathbf{b} y=Wx+b,模型將輸入向量 x \mathbf{x} x (n維) 投影或轉換為輸出向量 y \mathbf{y} y (m維)。偏置項 b \mathbf{b} b 則允許對變換后的空間進行平移,增加了模型的表達能力。
import torch
import torch.nn.functional as F
import math# 線性變換的簡化PyTorch實現
def linear_transform(x_batch, W, b):# x_batch: [batch_size, in_features]# W: [out_features, in_features] (PyTorch nn.Linear stores W this way)# b: [out_features]# torch.matmul(x, W.t()) or F.linear(x, W, b)return F.linear(x_batch, W, b)# 示例:
# x = torch.randn(32, 128) # Batch of 32 vectors, each 128-dim
# W_example = torch.randn(64, 128) # Projects from 128-dim to 64-dim
# b_example = torch.randn(64)
# y = linear_transform(x, W_example, b_example) # y will be [32, 64]
在LLM的核心組件——自注意力機制中,同一個輸入序列的隱藏狀態向量 x \mathbf{x} x 會通過三個不同的學習到的權重矩陣 W q , W k , W v \mathbf{W_q}, \mathbf{W_k}, \mathbf{W_v} Wq?,Wk?,Wv? 映射,生成查詢 (Query, Q)、鍵 (Key, K) 和值 (Value, V) 向量:
# 假設 x 是一個批次的序列表示: [batch_size, seq_len, d_model]
# W_q, W_k, W_v 是權重矩陣: [d_model, d_k] 或 [d_model, d_v]
# (實際實現中,這些權重通常合并為一個大矩陣進行計算,然后分割/重塑)# x_token: [d_model] (單個token的表示)
# W_q_matrix: [d_model, d_k] (假設d_q = d_k)# Q_token = torch.matmul(x_token, W_q_matrix) # 查詢向量 [d_k]
# K_token = torch.matmul(x_token, W_k_matrix) # 鍵向量 [d_k]
# V_token = torch.matmul(x_token, W_v_matrix) # 值向量 [d_v]# 對于整個序列 (batch_size, seq_len, d_model) -> (batch_size, seq_len, d_k or d_v)
# Q = F.linear(x, W_q_full) # W_q_full: [d_k_total, d_model] if considering multi-head
# K = F.linear(x, W_k_full)
# V = F.linear(x, W_v_full)
深層意義:學習特征的層次化抽象
這些線性變換在高維語義空間中執行著復雜的操作。每個權重矩陣可以被看作是學習到的一個特定"視角"或"投影儀",它將輸入信息投影到能揭示某些特定關系或特征的子空間。例如,一個 W \mathbf{W} W 可能學會提取與情感相關的特征,另一個則可能關注語法結構。在深度網絡中,這些變換層疊進行,使得模型能夠學習從低級特征(如詞形)到高級抽象概念(如主題、意圖)的層次化表示。模型的學習過程本質上就是在調整這些矩陣的參數,以最小化預測任務(如預測下一個詞)的損失。
2. 張量 (Tensors): 多維數據的結構化處理
張量是向量(一階張量)和矩陣(二階張量)向更高維度的推廣。在LLM中,數據通常以三階或更高階張量的形式存在,例如 T ∈ R B × L × d \mathcal{T}\in\mathbb{R}^{B\times L\times d} T∈RB×L×d,其中:
- B (Batch Size): 批量大小,即模型一次并行處理的獨立序列數量,利用GPU并行計算能力提高訓練效率。
- L (Sequence Length): 序列長度,即每個輸入序列包含的token數量。
- d (Hidden Dimension / Embedding Dimension): 隱藏維度或嵌入維度,即表示每個token的向量的特征數量。
實際應用與并行計算
Transformer模型中的操作,如多頭注意力、層歸一化、前饋網絡等,都高度依賴于高效的張量運算。
# 輸入張量形狀變化示例(簡化)
batch_size = 32
seq_len = 512
d_model = 768
num_heads = 12
d_head = d_model // num_heads # 64, 每個頭的維度inputs = torch.randn(batch_size, seq_len, d_model)# 在多頭注意力中,Q, K, V 會被計算并重塑以分離各個頭
# 假設 W_q projects d_model to d_model (num_heads * d_head)
# Q_projected = F.linear(inputs, W_q_weight) # [batch_size, seq_len, d_model]
# Q_reshaped = Q_projected.view(batch_size, seq_len, num_heads, d_head)
# Q_transposed = Q_reshaped.permute(0, 2, 1, 3) # [batch_size, num_heads, seq_len, d_head]
# K 和 V 類似處理
# K_transposed: [batch_size, num_heads, seq_len, d_head]
# V_transposed: [batch_size, num_heads, seq_len, d_head]
維度操作的重要性:效率與模塊化
張量的轉置 (permute)、重塑 (view/reshape) 和廣播 (broadcasting) 是實現高效并行計算,尤其是多頭注意力機制的關鍵。多頭注意力機制允許模型同時從輸入的不同表示子空間中學習信息,每個"頭"可以獨立地關注輸入序列的不同方面。張量操作使得這些獨立的計算可以被優雅地表示和高效地在現代硬件(如GPU/TPU,它們就是為大規模并行浮點運算設計的)上執行。
3. 內積 (Inner Product) 與相似度計算:注意力的核心機制
兩個向量 q \mathbf{q} q 和 k \mathbf{k} k(通常是查詢向量和鍵向量)的內積(或點積) ? q , k ? = q ? k = ∑ i q i k i \langle \mathbf{q},\mathbf{k} \rangle = \mathbf{q}^\top \mathbf{k} = \sum_i q_i k_i ?q,k?=q?k=∑i?qi?ki? 是注意力機制計算相似度的基礎。
幾何理解:對齊度的量化
內積可以表示為: q ? k = ∥ q ∥ ? ∥ k ∥ ? cos ? ( θ ) \mathbf{q}^\top \mathbf{k} = \|\mathbf{q}\| \cdot \|\mathbf{k}\| \cdot \cos(\theta) q?k=∥q∥?∥k∥?cos(θ),其中 θ \theta θ 是 q \mathbf{q} q 和 k \mathbf{k} k 之間的夾角。
- 當兩個向量方向一致時( θ = 0 , cos ? ( θ ) = 1 \theta=0, \cos(\theta)=1 θ=0,cos(θ)=1),內積達到最大正值(給定范數)。這表示兩者高度相關或相似。
- 當兩個向量正交( θ = π / 2 , cos ? ( θ ) = 0 \theta=\pi/2, \cos(\theta)=0 θ=π/2,cos(θ)=0),內積為0。表示兩者線性無關。
- 當兩個向量方向相反時( θ = π , cos ? ( θ ) = ? 1 \theta=\pi, \cos(\theta)=-1 θ=π,cos(θ)=?1),內積達到最大負值。表示兩者負相關。
在注意力機制中,通常更關心方向的一致性,即 cos ? ( θ ) \cos(\theta) cos(θ)。縮放點積注意力 (Scaled Dot-Product Attention) 中除以 d k \sqrt{d_k} dk?? (鍵向量維度的平方根) 是為了在梯度計算時穩定數值,防止內積過大導致softmax函數進入飽和區。
在注意力中的應用:信息選擇的權重
自注意力機制通過計算一個序列中每個查詢向量與所有鍵向量的相似度(內積)來決定每個詞應該“關注”序列中其他詞的程度:
# 假設 Q, K, V 已經是 [batch_size, num_heads, seq_len, d_head]
# Q: [..., seq_len_q, d_head]
# K: [..., seq_len_k, d_head]
# V: [..., seq_len_k, d_head] (seq_len_k 和 seq_len_v 是一樣的)# d_k = Q.size(-1) # d_head
# attention_scores = torch.matmul(Q, K.transpose(-2, -1)) / math.sqrt(d_k)
# # attention_scores: [batch_size, num_heads, seq_len_q, seq_len_k]# attention_weights = F.softmax(attention_scores, dim=-1)
# # attention_weights: [batch_size, num_heads, seq_len_q, seq_len_k]
# # 表示對于每個查詢token,它對所有鍵token的注意力分布# context_vectors = torch.matmul(attention_weights, V)
# # context_vectors: [batch_size, num_heads, seq_len_q, d_head]
# # 這是通過注意力加權聚合V得到的新表示
例如,當計算句子 “The cat sat on the mat” 中 “sat” 作為查詢詞時,它與 “cat” 和 “mat” (作為鍵) 的內積可能會比較高,表明這些詞與 “sat” 的動作在語義上或句法上高度相關,因此在計算 “sat” 的新表示時,“cat” 和 “mat” 的值向量會獲得更高的注意力權重。這實現了所謂的內容尋址記憶(content-addressable memory)的特性。
4. 正交性 (Orthogonality) 與歸一化 (Normalization): 訓練穩定性與表達力的保障
正交矩陣的優良特性
一個實方陣 Q \mathbf{Q} Q 如果是正交的,則滿足 Q ? Q = Q Q ? = I \mathbf{Q}^\top\mathbf{Q} = \mathbf{Q}\mathbf{Q}^\top = \mathbf{I} Q?Q=QQ?=I (單位矩陣)。正交變換保持向量的L2范數(長度)不變: ∥ Q x ∥ 2 = ∥ x ∥ 2 \|\mathbf{Q}\mathbf{x}\|_2 = \|\mathbf{x}\|_2 ∥Qx∥2?=∥x∥2?,并且保持向量間的內積和角度不變。
在LLM中:
- 權重初始化 (Weight Initialization):使用接近正交的矩陣(如通過Xavier或Kaiming初始化的變體,或者直接進行正交初始化)進行權重初始化,有助于在訓練初期維持信號的方差,防止梯度在深層網絡中消失或爆炸,從而加速收斂。
- 潛在的正則化效應:某些研究表明,鼓勵權重矩陣接近正交性可以作為一種正則化手段,提高泛化能力。
層歸一化 (Layer Normalization)
層歸一化是Transformer模型中至關重要的組件,它對每個樣本的每一層的激活值(在一個層內的所有隱藏單元上)進行歸一化,使其均值為0,方差為1,然后再通過可學習的縮放因子 γ \gamma γ 和平移因子 β \beta β 進行調整。
# LayerNorm實現示例 (PyTorch自帶 nn.LayerNorm)
# def layer_norm(x, gamma, beta, eps=1e-5):
# # x: [batch_size, seq_len, hidden_dim]
# mean = x.mean(dim=-1, keepdim=True) # 在最后一個維度(hidden_dim)上計算均值
# var = x.var(dim=-1, keepdim=True, unbiased=False) # 方差
# normalized_x = (x - mean) / torch.sqrt(var + eps) # 歸一化
# return gamma * normalized_x + beta # 應用可學習的仿射變換# # PyTorch usage:
# d_model = 768
# layer_norm_module = torch.nn.LayerNorm(d_model)
# x = torch.randn(32, 512, d_model)
# normalized_x_pytorch = layer_norm_module(x)
為什么需要歸一化:穩定信息流
在深層網絡中,每一層的計算都可能改變其輸出激活值的分布。如果沒有歸一化,這些分布可能會在層間傳遞時發生劇烈變化(稱為內部協變量偏移,internal covariate shift),導致信號逐漸衰減至0或膨脹至極大值,使得網絡難以訓練。層歸一化通過在每個層級重新調整激活值的尺度,確保了梯度能夠穩定地反向傳播,并使得模型對權重初始化和學習率的選擇不那么敏感,從而顯著提高了訓練的穩定性和速度。與批量歸一化(Batch Normalization)不同,層歸一化獨立于批量大小,并且對序列數據(其長度可變)特別有效。
5. 矩陣分解 (Matrix Factorization): 理解模型、壓縮與效率提升
矩陣分解是將一個矩陣表示為多個(通常更簡單或具有特定結構的)矩陣的乘積。
奇異值分解 (SVD)
任何實矩陣 A ∈ R m × n \mathbf{A}\in\mathbb{R}^{m\times n} A∈Rm×n 都可以分解為 A = U Σ V ? \mathbf{A}=\mathbf{U}\mathbf{\Sigma}\mathbf{V}^\top A=UΣV?,其中:
- U ∈ R m × m \mathbf{U}\in\mathbb{R}^{m\times m} U∈Rm×m 和 V ∈ R n × n \mathbf{V}\in\mathbb{R}^{n\times n} V∈Rn×n 是正交矩陣。 U \mathbf{U} U的列是 A A ? \mathbf{A}\mathbf{A}^\top AA?的特征向量(左奇異向量), V \mathbf{V} V的列是 A ? A \mathbf{A}^\top\mathbf{A} A?A的特征向量(右奇異向量)。
- Σ ∈ R m × n \mathbf{\Sigma}\in\mathbb{R}^{m\times n} Σ∈Rm×n 是一個對角矩陣(或對角塊矩陣),其對角線上的元素 σ i \sigma_i σi? 稱為奇異值,它們是非負的并按降序排列。奇異值表示了矩陣在對應奇異向量方向上的“拉伸”程度。
在LLM優化與分析中的應用
SVD及其相關的特征分解(Eigen-decomposition, A = P D P ? 1 \mathbf{A} = \mathbf{P}\mathbf{D}\mathbf{P}^{-1} A=PDP?1 for diagonalizable square matrices, where D is diagonal with eigenvalues)是強大的分析工具和優化手段:
- 模型壓縮 (Model Compression) via Low-Rank Approximation: 通過保留最大的k個奇異值及其對應的奇異向量,可以得到原矩陣的最佳低秩近似 A k = U k Σ k V k ? \mathbf{A}_k = \mathbf{U}_k\mathbf{\Sigma}_k\mathbf{V}_k^\top Ak?=Uk?Σk?Vk??。這常用于壓縮LLM中的權重矩陣,減少參數量和計算量,同時盡量保持模型性能。
# 使用SVD壓縮權重矩陣 (概念性) # weight_matrix: [out_features, in_features] # U, S, Vt = torch.linalg.svd(weight_matrix) # S is a vector of singular values # k = 100 # 保留的奇異值數量,壓縮比例取決于需求 # U_k = U[:, :k] # S_k_diag = torch.diag(S[:k]) # Vt_k = Vt[:k, :] # Vt is already V.T # compressed_weight = torch.matmul(U_k, torch.matmul(S_k_diag, Vt_k))
- 理解模型內部機制: 分析權重矩陣的奇異值譜(奇異值的分布)可以揭示矩陣的有效秩和信息容量。分析奇異向量可以幫助理解矩陣變換的主要方向和模型學習到的關鍵特征。例如,分析注意力頭輸出投影矩陣的奇異向量,可能揭示該頭關注的特定語義或句法模式。
- 降噪與正則化: 截斷SVD可以去除由較小奇異值表示的噪聲成分,有時能提高模型的泛化能力。
6. 秩 (Rank) 與低秩近似 (Low-Rank Approximation): 參數效率與模型適應
矩陣的秩是指其線性獨立的行向量或列向量的最大數目。它反映了矩陣所代表的線性變換能將輸入空間映射到的輸出空間的維度,即變換的“有效維度”。
低秩近似在LLM中的核心價值:
許多在大型模型中出現的權重矩陣,或者在微調過程中產生的權重更新矩陣,實際上可能是“過參數化”的,即它們的內在秩遠小于其完整維度。利用這一特性進行低秩近似,可以在不顯著犧牲性能的前提下,大幅提高參數效率。
- 模型微調 (Fine-tuning) - LoRA (Low-Rank Adaptation): LoRA是一種非常流行的參數高效微調技術。它假設預訓練模型的權重更新矩陣 Δ W \Delta \mathbf{W} ΔW 是低秩的。因此,它不直接更新原始權重 W 0 \mathbf{W}_0 W0?,而是學習兩個較小的低秩矩陣 A ∈ R m × r \mathbf{A} \in \mathbb{R}^{m \times r} A∈Rm×r 和 B ∈ R r × n \mathbf{B} \in \mathbb{R}^{r \times n} B∈Rr×n (其中 r ? min ? ( m , n ) r \ll \min(m,n) r?min(m,n) 是秩),使得 Δ W ≈ A B \Delta \mathbf{W} \approx \mathbf{A}\mathbf{B} ΔW≈AB。在推理時,等效的權重是 W 0 + A B \mathbf{W}_0 + \mathbf{A}\mathbf{B} W0?+AB。這極大地減少了微調所需的訓練參數數量。
# 低秩參數化 (LoRA 核心思想) # 原始權重 W0 ∈ R^(m×n) (凍結) # 低秩更新 A ∈ R^(m×r), B ∈ R^(r×n) (可訓練) # r = 8 # 通常是一個很小的值,如4, 8, 16, 32# class LoRALayer(torch.nn.Module): # def __init__(self, W0, r): # super().__init__() # self.m, self.n = W0.shape # self.r = r # self.A = torch.nn.Parameter(torch.randn(self.m, r)) # self.B = torch.nn.Parameter(torch.zeros(r, self.n)) # B通常初始化為0 # self.W0 = W0 # 凍結的原始權重 # # def forward(self, input_tensor): # delta_W = self.A @ self.B # output = F.linear(input_tensor, self.W0 + delta_W) # return output
- 模型量化與結構化剪枝: 一些量化技術也借鑒了低秩分解的思想,或者通過分析秩來指導剪枝策略。
- 知識蒸餾: 在知識蒸餾中,學生模型可能被設計為具有低秩結構的層,以更有效地從教師模型中學習。
- 推理加速: 使用分解后的小矩陣進行計算通常比使用原始大矩陣更快。
7. 范數 (Norms) 與距離 (Distances): 約束、正則化與優化穩定性
范數是衡量向量或矩陣“大小”或“長度”的函數。距離則是衡量兩個向量或點之間“遠近”的度量,通常基于范數定義。
常用范數
- L2范數 (Euclidean Norm): ∥ x ∥ 2 = ∑ i x i 2 \|\mathbf{x}\|_2 = \sqrt{\sum_i x_i^2} ∥x∥2?=∑i?xi2??。衡量向量在歐幾里得空間中的長度。
- L1范數 (Manhattan Norm): ∥ x ∥ 1 = ∑ i ∣ x i ∣ \|\mathbf{x}\|_1 = \sum_i |x_i| ∥x∥1?=∑i?∣xi?∣。衡量向量各元素絕對值之和。
- Frobenius范數 (For Matrices): ∥ A ∥ F = ∑ i , j a i j 2 \|\mathbf{A}\|_F = \sqrt{\sum_{i,j} a_{ij}^2} ∥A∥F?=∑i,j?aij2??。矩陣所有元素的平方和的平方根,相當于將矩陣視為一個長向量后計算其L2范數。
在LLM訓練與優化中的應用
范數在LLM訓練中扮演多重角色:
- 權重衰減 (Weight Decay / L2 Regularization): 在損失函數中加入權重的L2范數平方項( λ ∥ W ∥ F 2 \lambda \|\mathbf{W}\|_F^2 λ∥W∥F2?)。這會懲罰過大的權重值,傾向于使權重分布更平滑,有助于防止過擬合,提高模型泛化能力。幾何上,它將權重向原點“拉回”。
# L2權重衰減(通常由優化器實現,如AdamW) # loss = task_loss + weight_decay_lambda * torch.sum(torch.square(weights_parameter))
- L1 正則化: 在損失函數中加入權重的L1范數項( λ ∥ W ∥ 1 \lambda \|\mathbf{W}\|_1 λ∥W∥1?)。L1正則化傾向于產生稀疏權重(即許多權重為零),可以用于特征選擇或模型剪枝。
# l1_penalty = torch.sum(torch.abs(weights_parameter)) # loss = task_loss + l1_lambda * l1_penalty
- 梯度裁剪 (Gradient Clipping): 為了防止在訓練過程中梯度因某些樣本或特定網絡結構而變得過大(梯度爆炸),導致訓練不穩定,通常會裁剪梯度的范數。如果梯度的L2范數超過一個閾值,就將其縮放到該閾值。
# max_grad_norm = 1.0 # torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm=max_grad_norm)
- 相似度度量: 余弦相似度 cos ? ( θ ) = a ? b ∥ a ∥ 2 ∥ b ∥ 2 \cos(\theta) = \frac{\mathbf{a} \cdot \mathbf{b}}{\|\mathbf{a}\|_2 \|\mathbf{b}\|_2} cos(θ)=∥a∥2?∥b∥2?a?b?,是基于L2范數和內積定義的,廣泛用于衡量詞嵌入向量之間的語義相似性。
8. 投影 (Projections): 子空間映射與信息分離
投影是將一個向量映射到某個特定子空間(如由一組基向量張成的空間)的操作。在線性代數中,投影矩陣 P \mathbf{P} P 滿足 P 2 = P \mathbf{P}^2 = \mathbf{P} P2=P (冪等性)。
LLM中的實際應用:特征解耦與并行處理
- 多頭注意力 (Multi-Head Attention): 這是投影概念最顯著的應用之一。輸入序列的表示(詞嵌入+位置編碼)首先被線性投影到多個不同的、低維的查詢(Q)、鍵(K)和值(V)子空間。每個“頭”在各自的子空間中獨立執行注意力計算。這使得模型能夠同時關注來自輸入的不同方面的信息。例如,一個頭可能關注句法依賴,另一個頭可能關注語義關聯,還有一個頭可能關注指代關系。
# 多頭注意力投影示例(簡化版,W_q, W_k, W_v 包含了所有頭的投影權重) # def multi_head_projection(x, W_q_all_heads, W_k_all_heads, W_v_all_heads, num_heads): # # x: [batch_size, seq_len, d_model] # batch_size, seq_len, d_model = x.shape # d_head = d_model // num_heads # # # 投影到Q, K, V空間,并為多頭重塑 # # W_q_all_heads: [d_model, d_model] (d_model = num_heads * d_head) # q_projected = F.linear(x, W_q_all_heads) # [batch_size, seq_len, d_model] # q = q_projected.view(batch_size, seq_len, num_heads, d_head).transpose(1, 2) # # q: [batch_size, num_heads, seq_len, d_head] # # # k 和 v 類似處理 # # ... # return q, k, v
- 輸出層: 最終的Transformer層輸出的隱藏狀態向量會被投影回詞匯表大小的維度,然后通過Softmax函數得到下一個詞的概率分布。這個投影矩陣(通常與輸入詞嵌入矩陣共享或綁定權重)將高維的上下文表示映射到具體的詞選擇上。
- 殘差連接中的投影: 在殘差連接中,如果輸入和輸出的維度不匹配(例如,在某些網絡架構的下采樣層),可能需要一個線性投影(通常是一個1x1卷積或一個線性層)來使它們的維度一致,以便相加。
9. 仿射變換 (Affine Transformations) 與線性子空間:模型的幾何解釋
仿射變換是線性變換與平移(向量加法)的結合: y = W x + b \mathbf{y} = \mathbf{W}\mathbf{x} + \mathbf{b} y=Wx+b。Transformer模型中的幾乎所有參數化層(如注意力機制中的QKV投影、輸出投影,以及前饋網絡中的線性層)都是仿射變換。
LLM的幾何之旅:在高維空間中塑造語義
Transformer的整個工作流程可以被看作是一系列在高維向量空間中進行的復雜幾何操作:
- 嵌入與注入: 輸入的離散token首先被嵌入(投影)到高維語義空間,并與位置信息結合。
- 序列變換與信息融合: 每一層Transformer塊通過自注意力機制和前饋網絡對這些向量表示進行迭代式的仿射變換和非線性激活 (如GELU, ReLU)。
- 自注意力可以被視為一種動態的、內容敏感的加權平均過程,它根據向量間的相似性(通過內積度量)在不同子空間中重新組合和傳播信息。
- 前饋網絡 (FFN),通常是兩個仿射變換夾一個非線性激活函數(如 FFN ( x ) = GELU ( x W 1 + b 1 ) W 2 + b 2 \text{FFN}(\mathbf{x}) = \text{GELU}(\mathbf{x}\mathbf{W}_1 + \mathbf{b}_1)\mathbf{W}_2 + \mathbf{b}_2 FFN(x)=GELU(xW1?+b1?)W2?+b2?),對每個位置的表示進行獨立的、更深層次的特征提取和轉換。這個非線性是至關重要的,它使得模型能夠學習遠比單純線性變換復雜得多的函數。
- 空間扭曲與分離: 經過多層這樣的處理,輸入序列的表示在語義空間中被不斷地“扭曲”、“拉伸”和“折疊”,使得原本難以區分的語義模式變得線性可分或易于處理。
- 輸出投影: 最終,經過充分變換的頂層隱藏狀態被投影回詞匯表空間,模型在此空間中選擇概率最高的下一個token。
每一層Transformer實際上都在學習如何將輸入表示映射到新的特征子空間,這些子空間能夠更好地揭示與最終任務(如語言建模、翻譯、問答)相關的特定模式或關系。殘差連接確保了信息可以直接流過層,使得模型可以學習對恒等映射的修正,極大地幫助了深層網絡的訓練。
10. 跡 (Trace) 與譜特性 (Spectral Properties): 模型內部分析與正則化工具
矩陣的跡 (Trace) 是其主對角線上元素之和: Tr ( A ) = ∑ i a i i \text{Tr}(\mathbf{A}) = \sum_i a_{ii} Tr(A)=∑i?aii?。對于方陣,跡等于其所有特征值之和。譜特性主要指矩陣的特征值 (eigenvalues) 和奇異值 (singular values) 及其分布。
在LLM分析與設計中的應用
- 理解信息流與表示能力:
- 信息瓶頸理論: 某些理論工作使用互信息(與熵和條件熵相關,間接聯系到概率分布的“形狀”和矩陣變換如何改變它們)來分析信息在網絡層間的流動。跡和譜有時在這些分析的數學推導中出現。
- 協方差矩陣的譜: 分析數據表示的協方差矩陣(如 X ? X \mathbf{X}^\top\mathbf{X} X?X)的特征值譜,可以揭示數據的主要變化方向和表示的“有效維度”或“各向異性”。
- 譜歸一化 (Spectral Normalization): 一種正則化技術,通過將權重矩陣 W \mathbf{W} W 除以其最大的奇異值(譜范數)來約束其Lipschitz常數。即 W sn = W / σ max ? ( W ) \mathbf{W}_{\text{sn}} = \mathbf{W} / \sigma_{\max}(\mathbf{W}) Wsn?=W/σmax?(W)。這有助于穩定訓練過程,尤其是在生成對抗網絡(GANs)中常用,但其原理對任何深度網絡都有借鑒意義,可以防止層輸出的尺度爆炸。
# 譜歸一化 (概念性,PyTorch有 torch.nn.utils.spectral_norm) # def spectral_norm_regularize(weight_matrix): # # 計算最大奇異值 (通常通過冪迭代法近似) # _, S, _ = torch.linalg.svd(weight_matrix.data) # .data to avoid autograd issues if applying in place # max_singular_value = S[0] # # 歸一化權重 # normalized_weight = weight_matrix / max_singular_value # return normalized_weight # 在實踐中,優化器會作用于原始權重,而歸一化在每次前向時進行
- 注意力機制分析:
- 分析注意力矩陣 A \mathbf{A} A (softmax后的權重)的譜特性。例如,其主特征向量可能揭示了注意力機制傾向于關注的“模式”或“主題”。
- 研究者有時會觀察權重矩陣(如 W q , W k , W v , W o \mathbf{W_q}, \mathbf{W_k}, \mathbf{W_v}, \mathbf{W_o} Wq?,Wk?,Wv?,Wo?)的奇異值衰減情況,以判斷其是否接近低秩,或是否存在某些主導的語義轉換方向。
- 模型可解釋性: 通過分析特定層權重矩陣的奇異值和奇異向量,可以嘗試理解模型學到的變換的本質,哪些輸入特征被放大,哪些被抑制。
11. 實際應用集成:一個簡化的Transformer層
大型語言模型的驚人能力源于上述所有線性代數組件的復雜而精妙的協同作用。以下是一個極其簡化的Transformer編碼器層(不含dropout、精確的權重初始化等細節),以展示這些概念如何結合:
# 假設我們已經有了模型參數:
# attn_weights = {'Wq': ..., 'Wk': ..., 'Wv': ..., 'Wo': ...} (線性層權重和偏置)
# ffn_weights = {'W1': ..., 'W2': ...} (線性層權重和偏置)
# norm_params = {'gamma1':..., 'beta1':..., 'gamma2':..., 'beta2':...} (LayerNorm參數)class SimplifiedTransformerLayer(torch.nn.Module):def __init__(self, d_model, num_heads, d_ffn, dropout_rate=0.1):super().__init__()self.d_model = d_modelself.num_heads = num_headsassert d_model % num_heads == 0, "d_model must be divisible by num_heads"self.d_head = d_model // num_heads# 1. 多頭自注意力組件self.W_q = torch.nn.Linear(d_model, d_model) # Projects to Q_total (all heads)self.W_k = torch.nn.Linear(d_model, d_model) # Projects to K_totalself.W_v = torch.nn.Linear(d_model, d_model) # Projects to V_totalself.W_o = torch.nn.Linear(d_model, d_model) # Output projection# 2. 前饋網絡組件self.linear1_ffn = torch.nn.Linear(d_model, d_ffn)self.linear2_ffn = torch.nn.Linear(d_ffn, d_model)self.activation_ffn = torch.nn.GELU()# 3. 層歸一化self.norm1 = torch.nn.LayerNorm(d_model)self.norm2 = torch.nn.LayerNorm(d_model)# (Dropout layers would also be here)def scaled_dot_product_attention(self, Q, K, V, mask=None):# Q, K, V: [batch_size, num_heads, seq_len, d_head]attention_scores = torch.matmul(Q, K.transpose(-2, -1)) / math.sqrt(self.d_head)if mask is not None:attention_scores = attention_scores.masked_fill(mask == 0, -1e9) # Apply maskattention_weights = F.softmax(attention_scores, dim=-1) # Softmax over keys for each query# (Dropout on attention_weights can be applied here)context = torch.matmul(attention_weights, V) # Weighted sum of Vreturn context, attention_weightsdef forward(self, x, src_mask=None): # x: [batch_size, seq_len, d_model]batch_size, seq_len, _ = x.shape# --- 1. 多頭自注意力子層 ---# a. 殘差連接的輸入residual1 = x# b. 第一個層歸一化 (LN前置,Pre-LN)x_norm1 = self.norm1(x)# c. 線性投影到Q, K, V并重塑 (向量投影、張量操作)Q = self.W_q(x_norm1).view(batch_size, seq_len, self.num_heads, self.d_head).transpose(1, 2)K = self.W_k(x_norm1).view(batch_size, seq_len, self.num_heads, self.d_head).transpose(1, 2)V = self.W_v(x_norm1).view(batch_size, seq_len, self.num_heads, self.d_head).transpose(1, 2)# Q, K, V: [batch_size, num_heads, seq_len, d_head]# d. 計算注意力 (內積、相似度、加權平均)context_vectors, attn_weights_debug = self.scaled_dot_product_attention(Q, K, V, src_mask)# e. 合并多頭輸出并進行最終投影 (張量操作、線性變換)context_vectors = context_vectors.transpose(1, 2).contiguous().view(batch_size, seq_len, self.d_model)attn_output = self.W_o(context_vectors)# f. 殘差連接 (向量加法,促進梯度流動)# (Dropout on attn_output can be applied here)x = residual1 + attn_output# --- 2. 前饋網絡子層 ---# a. 殘差連接的輸入residual2 = x# b. 第二個層歸一化x_norm2 = self.norm2(x)# c. 前饋網絡計算 (仿射變換、非線性激活)ffn_hidden = self.linear1_ffn(x_norm2)ffn_activated = self.activation_ffn(ffn_hidden)# (Dropout on ffn_activated can be applied here)ffn_output = self.linear2_ffn(ffn_activated)# d. 殘差連接# (Dropout on ffn_output can be applied here)output = residual2 + ffn_outputreturn output #, attn_weights_debug (if needed for analysis)
在這段代碼中,清晰可見:
- 向量和矩陣是數據表示和參數存儲的基本形式。
- 張量操作(如
view
,transpose
)對于實現多頭并行至關重要。 - 內積(在
torch.matmul(Q, K.transpose(...))
中)用于計算查詢和鍵之間的相似度,構成注意力的核心。 - 層歸一化在子層輸入前應用,以穩定數值和加速訓練。
- 線性變換(
torch.nn.Linear
,內部是矩陣乘法和偏置加法)用于投影、特征提取和輸出組合。 - 殘差連接(向量加法)允許梯度直接傳播,并使模型易于學習恒等映射的微小調整。