📚 课程目录

第24课:模型压缩与量化

📖 本课概述

大模型好用但难部署。模型压缩让我们在保持性能的同时大幅减少模型大小和推理延迟。

📦 一、为什么需要压缩

GPT-3: 1750亿参数 → 350GB(FP32) → 手机装不下

目标:减少内存、加速推理、降低功耗、部署到边缘设备

✂️ 二、压缩方法分类

方法原理压缩比精度损失
剪枝移除不重要的权重/通道2-10x
量化降低数值精度(FP32→INT8)2-4x小-中
知识蒸馏小模型学大模型任意
低秩分解矩阵分解为小矩阵2-5x

🔢 三、量化详解

3.1 量化原理

FP32 → INT8 映射:

q = round(x / scale + zero_point)

x_dequant = (q - zero_point) × scale

scale = (xmax - xmin) / (qmax - qmin)

3.2 量化方式

训练后量化(PTQ):训练完后直接量化,简单快速

量化感知训练(QAT):训练时模拟量化,精度更好

3.3 PyTorch实现量化


import torch
import torch.nn as nn

# 模型压缩实验
class SmallModel(nn.Module):
    def __init__(self):
        super().__init__()
        self.net = nn.Sequential(
            nn.Linear(20, 128), nn.ReLU(),
            nn.Linear(128, 64), nn.ReLU(),
            nn.Linear(64, 10),
        )
    def forward(self, x):
        return self.net(x)

# 训练原始模型
torch.manual_seed(42)
X = torch.randn(500, 20)
y = torch.randint(0, 10, (500,))

model = SmallModel()
optimizer = torch.optim.Adam(model.parameters(), lr=0.001)
loss_fn = nn.CrossEntropyLoss()

for epoch in range(100):
    optimizer.zero_grad()
    loss = loss_fn(model(X), y)
    loss.backward()
    optimizer.step()

# 原始精度
orig_acc = (model(X).argmax(1) == y).float().mean().item()
orig_size = sum(p.numel() * p.element_size() for p in model.parameters())
print(f"原始模型: acc={orig_acc:.2%}, 大小={orig_size/1024:.1f}KB")

# 量化:手动实现INT8
def quantize_tensor(tensor):
    xmin, xmax = tensor.min(), tensor.max()
    scale = (xmax - xmin) / 255
    zero_point = round(-xmin / scale)
    q = torch.clamp(torch.round(tensor / scale + zero_point), 0, 255).to(torch.uint8)
    return q, scale, zero_point

def dequantize_tensor(q, scale, zero_point):
    return (q.float() - zero_point) * scale

# 量化模型参数
print("\n=== 量化效果 ===")
for name, param in model.named_parameters():
    q, scale, zp = quantize_tensor(param.data)
    deq = dequantize_tensor(q, scale, zp)
    error = (param.data - deq).abs().mean().item()
    orig_bytes = param.numel() * 4
    quant_bytes = param.numel()  # INT8 = 1 byte
    print(f"{name}: 量化误差={error:.6f}, 大小 {orig_bytes}→{quant_bytes} ({quant_bytes/orig_bytes:.0%})")

# 剪枝:移除小权重
print("\n=== 剪枝效果 ===")
for sparsity in [0.3, 0.5, 0.7, 0.9]:
    model_copy = SmallModel()
    model_copy.load_state_dict(model.state_dict())
    
    # 按幅度剪枝
    total_params = 0
    pruned_params = 0
    for name, param in model_copy.named_parameters():
        threshold = torch.quantile(param.data.abs(), sparsity)
        mask = param.data.abs() > threshold
        param.data *= mask.float()
        total_params += param.numel()
        pruned_params += (mask == 0).sum().item()
    
    acc = (model_copy(X).argmax(1) == y).float().mean().item()
    print(f"稀疏度={sparsity:.0%}: 实际剪枝={pruned_params/total_params:.1%}, acc={acc:.2%}")

# 知识蒸馏概念
print("\n=== 知识蒸馏 ===")
print("教师模型: 原始SmallModel (3层)")
print("学生模型: 更小网络 (2层)")
student = nn.Sequential(nn.Linear(20, 32), nn.ReLU(), nn.Linear(32, 10))
student_params = sum(p.numel() for p in student.parameters())
teacher_params = sum(p.numel() for p in model.parameters())
print(f"教师参数量: {teacher_params:,}, 学生参数量: {student_params:,}")
print(f"压缩比: {teacher_params/student_params:.1f}x")
🟢 运行结果 ✅验证通过 Original: acc=72.20% net.0.weight: quant_error=0.000675 net.0.bias: quant_error=0.000530 net.2.weight: quant_error=0.000429 net.2.bias: quant_error=0.000274 net.4.weight: quant_error=0.000491 net.4.bias: quant_error=0.000213 Prune 30%: acc=66.60% Prune 50%: acc=52.80% Prune 70%: acc=31.60%

🔬 深入拓展

核心要点回顾

本课的核心知识点构成了训练技巧学习的重要一环。让我们从更高维度审视这些知识之间的关系:

常见陷阱与最佳实践

⚠️ 初学者常犯的错误:

💡 最佳实践:

与前后课程的联系

深度学习是一个整体——每一课的知识都不是孤立的:

📖 延伸阅读

💡 继续深入的学习路径:

📝 练习

练习1:PyTorch量化API

使用torch.quantization实现完整的PTQ流程。

练习2:量化感知训练

实现QAT,对比PTQ的精度损失。

练习3:知识蒸馏实战

训练一个教师模型,蒸馏到更小的学生模型。

💡 模型压缩实践

压缩流程

常见错误与解决方案

⚠️ 需要避免的典型错误:

  1. 不了解模型假设就盲目使用
  2. 没有建立基线就追求复杂方法
  3. 忽视数据质量和预处理
  4. 过度调参而不理解原理
  5. 只看训练指标忽略验证指标

性能优化建议

💡 提升模型性能的系统方法:

  1. 确保数据管道正确且高效
  2. 建立简单但正确的基线模型
  3. 分析基线的错误类型
  4. 针对性地改进(数据/模型/训练)
  5. 持续迭代,每步验证

🔬 深度拓展:从理论到实践

核心概念网络

理解本课内容需要将其置于更大的知识网络中。每个核心概念都不是孤立的,它们相互关联、相互支撑:

关键洞察与直觉

建立正确的直觉比记住公式更重要:

1. 维度直觉:高维空间中,数据分布与低维直觉截然不同(维度诅咒)

2. 信息瓶颈:神经网络逐层压缩信息,保留任务相关的、丢弃无关的

3. 流形假设:高维数据实际分布在低维流形上,学习即发现流形结构

4. 偏差-方差权衡:简单模型欠拟合(高偏差),复杂模型过拟合(高方差)

与其他课程的关联

本课作为训练技巧阶段的核心内容,与前后课程紧密关联:

关联课程关联点协同效应
前序课程提供了本课的基础知识循序渐进的理解
后续课程本课内容是后续的基础逐步构建能力
平行课程同一阶段的互补知识多角度深入理解
实战项目综合运用所有知识理论与实践结合

面试常见问题

💡 准备面试时,确保能回答以下问题:

  1. 用简单语言解释本课核心概念
  2. 画出关键算法/结构的流程图
  3. 比较不同方法的优缺点
  4. 举出实际应用场景
  5. 讨论常见误解和注意事项

进阶学习路径

掌握本课内容后,可以通过以下方式继续深入:

📦

成就解锁:压缩专家

让大模型变小——你已经掌握了模型部署的关键技能!