Attention Is All You Need
计算序列中每个位置与其他所有位置的注意力权重,捕捉全局依赖关系。
并行使用多组 Q/K/V 投影,让模型在不同子空间中关注不同信息。
每个位置独立应用的两层全连接网络,引入非线性变换能力。
对每个样本的所有特征进行归一化,稳定深层网络的训练。
为模型注入序列位置信息,因为 Attention 本身不具备位置感知能力。
跳跃连接缓解梯度消失问题,让网络可以训练到数百层深度。
理解现代 AI 的核心运算
• 中间维度 dff = 2048(通常是 dmodel 的 4 倍)
• 对每个位置独立应用,不共享信息
• 引入非线性,增强模型表达能力
• 现代变体常用 GELU 替代 ReLU
• 与 BatchNorm 的区别:LN 对每个样本的特征维度归一化,BN 对 batch 维度归一化
• 在 NLP 中更稳定,因为序列长度变化大
• γ 和 β 是可学习的缩放和平移参数
• Pre-LN 结构(LayerNorm 在残差之前)训练更稳定
原始 Transformer 使用 Post-LN(残差连接后接 LayerNorm)。现代模型(如 GPT-3、LLaMA)普遍改用 Pre-LN,将 LayerNorm 放在子层之前,训练更加稳定:
class TransformerBlock(nn.Module):
def __init__(self, d_model, num_heads, d_ff, dropout=0.1):
super().__init__()
self.attention = MultiHeadAttention(d_model, num_heads)
self.ffn = FeedForward(d_model, d_ff)
self.norm1 = nn.LayerNorm(d_model)
self.norm2 = nn.LayerNorm(d_model)
self.dropout = nn.Dropout(dropout)
def forward(self, x, mask=None):
# Pre-LN 结构
# Attention 子层
attn_out = self.attention(
self.norm1(x),
self.norm1(x),
self.norm1(x),
mask
)
x = x + self.dropout(attn_out)
# FFN 子层
ffn_out = self.ffn(self.norm2(x))
x = x + self.dropout(ffn_out)
return x
动态图深度学习框架
PyTorch 的核心数据结构,类似于 NumPy 的 ndarray,但可以在 GPU 上运行并支持自动求导。
import torch
# 创建 Tensor
x = torch.tensor([[1, 2], [3, 4]])
x = torch.zeros(2, 3)
x = torch.randn(3, 3) # 标准正态分布
# GPU 张量
x = x.cuda() # 移到 GPU
x = x.to('cuda:0') # 指定 GPU
# 关键属性
x.shape # torch.Size([2, 2])
x.dtype # torch.float32
x.device # cuda:0
PyTorch 的自动微分引擎,通过计算图自动追踪所有操作,支持反向传播计算梯度。
x = torch.tensor(2.0, requires_grad=True)
y = torch.tensor(3.0, requires_grad=True)
z = x**2 + y**3 # z = 4 + 27 = 31
z.backward() # 反向传播
print(x.grad) # 4.0 (∂z/∂x = 2x)
print(y.grad) # 27.0 (∂z/∂y = 3y²)
# 清零梯度(重要!)
optimizer.zero_grad()
所有神经网络模块的基类。通过继承 nn.Module 定义模型,PyTorch 会自动管理参数和子模块。
class Net(nn.Module):
def __init__(self):
super().__init__()
self.conv1 = nn.Conv2d(1, 32, 3)
self.fc = nn.Linear(32*26*26, 10)
def forward(self, x):
x = F.relu(self.conv1(x))
x = x.view(x.size(0), -1)
return self.fc(x)
model = Net()
model = model.to('cuda')
# 查看参数
for name, param in model.named_parameters():
print(name, param.shape)
优化器根据梯度更新参数,损失函数衡量模型预测与真实值的差距。
# 损失函数
criterion = nn.CrossEntropyLoss()
loss = criterion(outputs, labels)
# 优化器
optimizer = torch.optim.Adam(
model.parameters(),
lr=1e-3,
betas=(0.9, 0.999)
)
# 训练步骤(标准模板)
optimizer.zero_grad() # 1. 清零梯度
loss.backward() # 2. 反向传播
optimizer.step() # 3. 更新参数
# 学习率调度
scheduler = torch.optim.lr_scheduler.\
StepLR(optimizer, step_size=10, gamma=0.1)
import torch
import torch.nn as nn
from torch.utils.data import DataLoader
def train_epoch(model, dataloader, criterion, optimizer, device):
model.train()
total_loss = 0
for batch_idx, (data, target) in enumerate(dataloader):
# 1. 数据移动到 GPU
data, target = data.to(device), target.to(device)
# 2. 前向传播
output = model(data)
loss = criterion(output, target)
# 3. 反向传播
optimizer.zero_grad()
loss.backward()
# 4. 梯度裁剪(防止梯度爆炸)
torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm=1.0)
# 5. 更新参数
optimizer.step()
total_loss += loss.item()
return total_loss / len(dataloader)
# 主训练循环
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
model = MyModel().to(device)
for epoch in range(num_epochs):
train_loss = train_epoch(model, train_loader, criterion, optimizer, device)
val_loss = evaluate(model, val_loader, criterion, device)
print(f"Epoch {epoch}: Train Loss={train_loss:.4f}, Val Loss={val_loss:.4f}")
# 保存最佳模型
if val_loss < best_loss:
torch.save(model.state_dict(), 'best_model.pt')
best_loss = val_loss
释放 GPU 并行计算的力量
NVIDIA 推出的并行计算平台和编程模型,让开发者能使用 GPU 进行通用计算(GPGPU)。
现代 GPU 拥有数千个 CUDA Core(如 RTX 4090 有 16384 个),可同时执行大量线程。
基于 C/C++ 的扩展,通过 __global__、__device__ 等关键字定义 GPU 核函数。
GPU 的核心计算单元,每个 SM 包含多个 CUDA Core、Tensor Core、共享内存和寄存器。GPU 通常有 80-144 个 SM。
专用矩阵运算单元,专门加速混合精度(FP16/BF16/TF32)的矩阵乘加运算(GEMM),是 Transformer 训练加速的关键。
从快到慢:寄存器 (Register) → 共享内存 (Shared Memory) → L1/L2 缓存 → 全局内存 (Global Memory/显存 HBM)。
注:H100 FP16 Tensor Core 算力达 989 TFLOPS,是 CPU 的数百倍。
import torch
# 检查 CUDA 是否可用
print(torch.cuda.is_available()) # True
print(torch.cuda.device_count()) # GPU 数量
print(torch.cuda.get_device_name(0)) # NVIDIA RTX 4090
# 创建 GPU 张量
x = torch.randn(3, 3).cuda()
x = torch.randn(3, 3, device='cuda:0')
# 将模型移到 GPU
model = MyModel().to('cuda')
# 指定数据类型(节省显存)
x = x.half() # FP16
x = x.bfloat16() # BF16 (Ampere+)
# 混合精度训练
from torch.cuda.amp import autocast, GradScaler
scaler = GradScaler()
with autocast():
output = model(input)
loss = criterion(output, target)
scaler.scale(loss).backward()
scaler.step(optimizer)
scaler.update()
tensor.to('cuda', non_blocking=True)
DataLoader(..., pin_memory=True)
• torch.cuda.empty_cache() - 释放未使用的缓存显存
• del tensor + torch.cuda.empty_cache() - 主动释放
• 使用 gradient checkpointing 时间换空间
• nvidia-smi 实时监控显存使用
理解底层 CUDA 编程有助于优化 PyTorch 性能。以下是向量加法的 CUDA 核函数示例:
// CUDA 核函数:每个线程处理一个元素
__global__ void vectorAdd(
const float *A,
const float *B,
float *C,
int numElements
) {
// 计算全局线程 ID
int i = blockDim.x * blockIdx.x + threadIdx.x;
if (i < numElements) {
C[i] = A[i] + B[i];
}
}
// 主机代码调用
int numElements = 50000;
int threadsPerBlock = 256;
int blocksPerGrid = (numElements + threadsPerBlock - 1)
/ threadsPerBlock;
vectorAdd<<>>(
d_A, d_B, d_C, numElements
);
__global__ 全局内存(显存,最大最慢)
__shared__ 共享内存(SM 内,块级可见,快)
__constant__ 常量内存(只读,缓存)
__device__ 设备函数,仅在 GPU 调用
Self-Attention 实现全局依赖建模,Multi-Head 增强表达能力,FFN 提供非线性,残差连接和 LayerNorm 保障深层训练稳定。
Tensor 是基础数据结构,Autograd 自动计算梯度,nn.Module 构建网络,配合 Optimizer 和 DataLoader 完成完整训练流程。
GPU 通过海量并行核心加速矩阵运算,Tensor Core 专为 AI 优化。理解内存层次和异步传输是性能优化的关键。