从Andrej Karpathy《深入了解ChatGPT之类的大语言模型》入门LLMs:原理与实践指南

1次阅读
没有评论

共计 3761 个字符,预计需要花费 10 分钟才能阅读完成。

image.webp

1. 大语言模型核心概念解析

1.1 Tokenization:文本的数字化起点

Tokenization 是将原始文本切割成模型可处理的基本单元的过程。以 GPT- 3 为例:
– 使用 BPE(Byte Pair Encoding)算法构建包含 50,257 个 token 的词汇表
– 平均每个 token 对应约 4 个英文字符
– 中文需要更高 token 占比(约 2:1 字符 token 比)

从 Andrej Karpathy《深入了解 ChatGPT 之类的大语言模型》入门 LLMs:原理与实践指南

典型 Python 实现示例:

from transformers import GPT2Tokenizer
tokenizer = GPT2Tokenizer.from_pretrained('gpt2')
encoded = tokenizer("Hello world!")["input_ids"]  # [15496, 995, 0]

1.2 Attention 机制:语言理解的魔力透镜

Self-Attention 的计算过程可分解为:
1. 将输入嵌入向量转换为 Q(Query)、K(Key)、V(Value) 三组矩阵
2. 计算注意力分数:$\text{Attention}(Q, K, V) = \text{softmax}(\frac{QK^T}{\sqrt{d_k}})V$
3. 多头注意力并行计算(GPT- 3 使用 96 头)

关键特性:
– 计算复杂度:$O(n^2d)$(n 为序列长度,d 为特征维度)
– 内存占用:需要缓存所有中间结果用于反向传播

2. 主流架构对比分析

架构类型 典型模型 计算复杂度 内存占用 适用场景
Decoder-only GPT-3 $O(n^2d)$ 800GB+ 文本生成
Encoder-only BERT $O(n^2d)$ 350GB+ 分类 / 标注
Encoder-Decoder T5 $O(n^2d + m^2d)$ 1TB+ 机器翻译

(注:内存占用为训练时参数,基于 175B 模型估算)

3. Mini-GPT 实战实现

3.1 数据预处理管道

import torch
from torch.utils.data import Dataset

class TextDataset(Dataset):
    def __init__(self, texts, tokenizer, max_length=128):
        self.encodings = tokenizer(
            texts, 
            truncation=True,
            max_length=max_length,
            padding='max_length',
            return_tensors='pt'
        )

    def __getitem__(self, idx):
        return {'input_ids': self.encodings['input_ids'][idx],
            'attention_mask': self.encodings['attention_mask'][idx]
        }

3.2 Self-Attention 层实现

import math
import torch.nn as nn

class SelfAttention(nn.Module):
    def __init__(self, embed_size, heads):
        super().__init__()
        self.embed_size = embed_size
        self.heads = heads
        self.head_dim = embed_size // heads

        self.values = nn.Linear(self.head_dim, self.head_dim, bias=False)
        self.keys = nn.Linear(self.head_dim, self.head_dim, bias=False)
        self.queries = nn.Linear(self.head_dim, self.head_dim, bias=False)
        self.fc_out = nn.Linear(heads * self.head_dim, embed_size)

    def forward(self, values, keys, query, mask):
        N = query.shape[0]
        value_len, key_len, query_len = values.shape[1], keys.shape[1], query.shape[1]

        # Split into multiple heads
        values = values.reshape(N, value_len, self.heads, self.head_dim)
        keys = keys.reshape(N, key_len, self.heads, self.head_dim)
        queries = query.reshape(N, query_len, self.heads, self.head_dim)

        energy = torch.einsum("nqhd,nkhd->nhqk", [queries, keys]) / math.sqrt(self.head_dim)

        if mask is not None:
            energy = energy.masked_fill(mask == 0, float("-1e20"))

        attention = torch.softmax(energy, dim=3)

        out = torch.einsum("nhql,nlhd->nqhd", [attention, values])
        out = out.reshape(N, query_len, self.heads * self.head_dim)

        return self.fc_out(out)

3.3 文本生成演示

def generate_text(model, tokenizer, prompt, max_length=50):
    input_ids = tokenizer.encode(prompt, return_tensors='pt')

    with torch.no_grad():
        for _ in range(max_length):
            outputs = model(input_ids)
            next_token_logits = outputs[:, -1, :]
            next_token = torch.argmax(next_token_logits, dim=-1, keepdim=True)
            input_ids = torch.cat([input_ids, next_token], dim=-1)

            if next_token == tokenizer.eos_token_id:
                break

    return tokenizer.decode(input_ids[0])

4. 生产环境挑战

4.1 显存优化技巧

  • Gradient Checkpointing:通过只保存部分激活值,节省约 75% 显存

    from torch.utils.checkpoint import checkpoint
    
    def forward(self, x):
        return checkpoint(self._forward, x)

  • 混合精度训练 :FP16 减少 50% 显存占用

    scaler = torch.cuda.amp.GradScaler()
    
    with torch.cuda.amp.autocast():
        outputs = model(inputs)
        loss = criterion(outputs, labels)
    
    scaler.scale(loss).backward()
    scaler.step(optimizer)
    scaler.update()

4.2 分布式训练陷阱

  1. 数据并行 :每个 GPU 保存完整模型副本,适合单机多卡
  2. 需同步梯度(torch.nn.parallel.DistributedDataParallel

  3. 模型并行 :将模型层拆分到不同设备,适合超大模型

  4. 需处理跨设备通信开销

  5. Pipeline 并行 :按层切分 mini-batch,需平衡气泡时间

4.3 量化部署方案

量化类型 精度损失 加速比 硬件要求
FP32 基准 0% 1x 通用 GPU
FP16 <1% 2-3x Volta+
INT8 1-5% 4x Turing+

典型部署流程:

# 动态量化
quantized_model = torch.quantization.quantize_dynamic(model, {torch.nn.Linear}, dtype=torch.qint8
)

# 静态量化
model.qconfig = torch.quantization.get_default_qconfig('fbgemm')
torch.quantization.prepare(model, inplace=True)
# 校准代码...
torch.quantization.convert(model, inplace=True)

5. 开放性问题

  1. 缩放定律 :模型性能与计算预算的关系是否永远遵循 $L(N) = N^{-α}$?当 N→∞时是否存在拐点?

  2. 涌现能力 :为何某些能力(如数学推理)仅在模型达到特定规模后突然出现?

  3. 数据瓶颈 :当高质量训练数据耗尽时,如何突破当前模型上限?

参考文献

  1. Vaswani et al. Attention Is All You Need (2017) arXiv:1706.03762
  2. Brown et al. Language Models are Few-Shot Learners (2020) arXiv:2005.14165
  3. Kaplan et al. Scaling Laws for Neural Language Models (2020) arXiv:2001.08361
正文完
 0
评论(没有评论)