知识蒸馏是一种模型压缩技术,它通过将一个大型的、复杂的模型(称为“教师模型”)的知识传递给一个较小的模型(称为“学生模型”),从而使学生模型在保持较小规模和更快推理速度的同时,也具备接近甚至媲美教师模型的性能。

img

知识蒸馏的基本原理

在传统的神经网络训练中,我们使用的是原始的硬标签(hard labels)进行监督训练。

而在知识蒸馏中,除了使用原始的硬标签(hard labels)外,还使用了来自教师模型的软标签(soft labels)作为额外的监督信息。

与硬标签不同,软标签包含了更多的类别间关系信息,因此能为学生模型提供更多的学习信号,从而提高其性能。

软标签与硬标签
  • 硬标签(Hard Labels)

    硬标签是指类别的独热编码向量。

    例如,对于一个分类问题,真实标签为“猫” 则硬标签是一个具有“猫”类别为1,其余类别为0的向量。

    : 1,狐狸: 0,狗: 0
    
  • 软标签(Soft Labels)

    软标签是由教师模型生成的概率分布,反映了教师模型对每个类别的信心。

    这些概率分布包含了类别之间的相似性信息,可以帮助学生模型更好地进行学习。

    例如,一个图像的真实标签是“猫”,但教师模型可能输出:

    : 0.78,狐狸: 0.12,狗: 0.10
    

    这种概率分布包含了丰富的知识(比如“猫”和“狗”更相似),远比 one-hot 更有指导意义。

知识蒸馏的主要步骤

知识蒸馏通常包括以下几个步骤。

  1. 训练教师模型(Teacher Model)

    首先,训练一个性能较好的大型模型,作为教师模型。

    这个模型通常具有较高的准确度,但计算和存储开销较大。

  2. 生成软标签(Soft Targets)

    将训练数据输入到教师模型中,获取每个样本的预测输出(类别的概率分布)。

    这些概率分布作为软标签,包含了类别之间的相对关系信息。

  3. 训练学生模型(Student Model)

    使用教师模型的输出(软标签)来训练一个较小的学生模型。

    这个过程中,学生模型不仅使用真实标签(硬标签),还使用教师模型提供的软标签。

知识蒸馏的损失函数

知识蒸馏的损失函数包含两部分

  • 硬标签损失(Hard Label Loss)

    学生模型在训练过程中,需要对数据的真实标签进行拟合,通常采用交叉熵损失。

  • 软标签损失(Soft Label Loss)

    学生模型除了需要拟合真实标签,还需要通过学习教师模型输出的概率分布来捕获类别间的相似性,这部分损失使用 Kullback-Leibler(KL)散度来衡量学生模型输出与教师模型输出之间的差异。

img

硬标签损失

硬标签损失使用交叉熵损失函数,用于衡量学生模型的输出与真实标签之间的差距

设学生模型的预测为 ,真实标签为 y,那么硬标签损失可以表示为

软标签损失(蒸馏损失)

蒸馏损失衡量学生模型的输出与教师模型输出之间的差异。通常,教师模型的输出是一个软化的概率分布,这使得学生模型能够捕捉到更丰富的类别间关系。

蒸馏损失的目标是通过优化学生模型的输出 ,使其尽量接近教师模型的输出 。

教师模型输出通常会通过温度参数 T 进行软化,温度越高,输出的概率分布越平滑。

温度 T 是一个超参数,它用于控制教师模型输出的概率分布的平滑度。当 T 增加时,教师模型的输出变得更加平滑,使得类别间的差异更小。这有助于学生模型学习到类别之间的相对关系,而不仅仅是最可能的类别。

教师模型的输出经过温度缩放后,表示为:

其中, 是教师模型的 logits(未归一化的预测值),T 是温度系数。

同样地,学生模型的输出也会根据相同的温度进行缩放。

然后,学生模型的输出 与教师模型的输出 之间的差异使用 KL 散度来衡量,表示为:

其中 是一个缩放因子,用于平衡温度因子对梯度的影响。

组合损失

最终的知识蒸馏损失是两者的加权和

其中 是一个超参数,用于调整交叉熵损失和蒸馏损失的权重。

知识蒸馏的变种

除了传统的蒸馏,还有一些变种方式。

  1. 中间层蒸馏:除了输出,还让学生模型学习教师模型中间层的表示;
  2. 自蒸馏:同一模型自身不同阶段的知识迁移,比如深层指导浅层;
  3. 多教师蒸馏:利用多个教师模型来指导学生模型。
  4. 在线蒸馏:学生和教师同步训练;

知识蒸馏的应用场景

  • 模型压缩:深度学习模型部署到资源受限设备,如手机、嵌入式设备等。
  • 模型加速:减小模型规模同时维持精度以提高推理速度。
  • 模型融合:多个教师模型蒸馏到一个学生模型中,提升泛化性能。

案例分享

下面是一个基于 PyTorch 实现的知识蒸馏的完整示例代码。

首先,加载数据集

import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
from torchvision import datasets, transforms
from torch.utils.data import DataLoader

# 设置设备
device = torch.device("cuda"if torch.cuda.is_available() else"cpu")

# 数据加载
transform = transforms.Compose([
    transforms.ToTensor(),
    transforms.Normalize((0.1307,), (0.3081,))
])

train_dataset = datasets.MNIST('./data', train=True, download=True, transform=transform)
test_dataset = datasets.MNIST('./data', train=False, transform=transform)

train_loader = DataLoader(train_dataset, batch_size=64, shuffle=True)
test_loader = DataLoader(test_dataset, batch_size=1000, shuffle=False)

构建教师模型

# 教师模型(复杂的卷积神经网络)
class TeacherNet(nn.Module):
    def __init__(self):
        super(TeacherNet, self).__init__()
        self.conv1 = nn.Conv2d(1, 32, 3, 1)
        self.conv2 = nn.Conv2d(32, 64, 3, 1)
        self.fc1 = nn.Linear(9216, 128)
        self.fc2 = nn.Linear(128, 10)

    def forward(self, x):
        x = F.relu(self.conv1(x))
        x = F.relu(self.conv2(x))
        x = F.max_pool2d(x, 2)
        x = torch.flatten(x, 1)
        x = F.relu(self.fc1(x))
        return self.fc2(x)

构建学生模型

# 学生模型(简单的卷积神经网络)
class StudentNet(nn.Module):
    def __init__(self):
        super(StudentNet, self).__init__()
        self.conv1 = nn.Conv2d(1, 16, 3, 1)
        self.fc1 = nn.Linear(2704, 64)
        self.fc2 = nn.Linear(64, 10)

    def forward(self, x):
        x = F.relu(self.conv1(x))
        x = F.max_pool2d(x, 2)
        x = torch.flatten(x, 1)
        x = F.relu(self.fc1(x))
        return self.fc2(x)

训练教师模型

def train_teacher(model, optimizer, epochs=5):
    model.train()
    for epoch in range(epochs):
        for data, target in train_loader:
            data, target = data.to(device), target.to(device)
            optimizer.zero_grad()
            output = model(data)
            loss = F.cross_entropy(output, target)
            loss.backward()
            optimizer.step()
        print(f"Epoch {epoch+1} Teacher Loss: {loss.item():.4f}")

def test(model):
    model.eval()
    correct = 0
    with torch.no_grad():
        for data, target in test_loader:
            data, target = data.to(device), target.to(device)
            output = model(data)
            pred = output.argmax(dim=1)
            correct += pred.eq(target).sum().item()
    accuracy = 100. * correct / len(test_loader.dataset)
    print(f"Test Accuracy: {accuracy:.2f}%")
    
teacher = TeacherNet().to(device)
optimizer_teacher = optim.Adam(teacher.parameters())
train_teacher(teacher, optimizer_teacher)
print("Teacher Evaluation:")
test(teacher)

训练学生模型(使用知识蒸馏)

def train_student(student, teacher, optimizer, T=5.0, alpha=0.7, epochs=5):
    teacher.eval()
    student.train()
    for epoch in range(epochs):
        for data, target in train_loader:
            data, target = data.to(device), target.to(device)

            # 学生输出
            student_output = student(data)

            # 教师输出(不参与梯度计算)
            with torch.no_grad():
                teacher_output = teacher(data)

            # 蒸馏损失
            loss_kd = nn.KLDivLoss(reduction='batchmean')(
                F.log_softmax(student_output / T, dim=1),
                F.softmax(teacher_output / T, dim=1)
            ) * (T * T)

            # 学生自身的交叉熵损失
            loss_ce = F.cross_entropy(student_output, target)

            # 总损失:加权和
            loss = alpha * loss_kd + (1. - alpha) * loss_ce

            optimizer.zero_grad()
            loss.backward()
            optimizer.step()

        print(f"Epoch {epoch+1} Student Loss: {loss.item():.4f}")

student = StudentNet().to(device)
optimizer_student = optim.Adam(student.parameters())
train_student(student, teacher, optimizer_student)

# 测试学生模型
print("Student Evaluation:")
test(student)

如何学习大模型 AI ?

由于新岗位的生产效率,要优于被取代岗位的生产效率,所以实际上整个社会的生产效率是提升的。

但是具体到个人,只能说是:

“最先掌握AI的人,将会比较晚掌握AI的人有竞争优势”。

这句话,放在计算机、互联网、移动互联网的开局时期,都是一样的道理。

我在一线互联网企业工作十余年里,指导过不少同行后辈。帮助很多人得到了学习和成长。

我意识到有很多经验和知识值得分享给大家,也可以通过我们的能力和经验解答大家在人工智能学习中的很多困惑,所以在工作繁忙的情况下还是坚持各种整理和分享。但苦于知识传播途径有限,很多互联网行业朋友无法获得正确的资料得到学习提升,故此将并将重要的AI大模型资料包括AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频免费分享出来。

在这里插入图片描述

第一阶段(10天):初阶应用

该阶段让大家对大模型 AI有一个最前沿的认识,对大模型 AI 的理解超过 95% 的人,可以在相关讨论时发表高级、不跟风、又接地气的见解,别人只会和 AI 聊天,而你能调教 AI,并能用代码将大模型和业务衔接。

  • 大模型 AI 能干什么?
  • 大模型是怎样获得「智能」的?
  • 用好 AI 的核心心法
  • 大模型应用业务架构
  • 大模型应用技术架构
  • 代码示例:向 GPT-3.5 灌入新知识
  • 提示工程的意义和核心思想
  • Prompt 典型构成
  • 指令调优方法论
  • 思维链和思维树
  • Prompt 攻击和防范

第二阶段(30天):高阶应用

该阶段我们正式进入大模型 AI 进阶实战学习,学会构造私有知识库,扩展 AI 的能力。快速开发一个完整的基于 agent 对话机器人。掌握功能最强的大模型开发框架,抓住最新的技术进展,适合 Python 和 JavaScript 程序员。

  • 为什么要做 RAG
  • 搭建一个简单的 ChatPDF
  • 检索的基础概念
  • 什么是向量表示(Embeddings)
  • 向量数据库与向量检索
  • 基于向量检索的 RAG
  • 搭建 RAG 系统的扩展知识
  • 混合检索与 RAG-Fusion 简介
  • 向量模型本地部署

第三阶段(30天):模型训练

恭喜你,如果学到这里,你基本可以找到一份大模型 AI相关的工作,自己也能训练 GPT 了!通过微调,训练自己的垂直大模型,能独立训练开源多模态大模型,掌握更多技术方案。

到此为止,大概2个月的时间。你已经成为了一名“AI小子”。那么你还想往下探索吗?

  • 为什么要做 RAG
  • 什么是模型
  • 什么是模型训练
  • 求解器 & 损失函数简介
  • 小实验2:手写一个简单的神经网络并训练它
  • 什么是训练/预训练/微调/轻量化微调
  • Transformer结构简介
  • 轻量化微调
  • 实验数据集的构建

第四阶段(20天):商业闭环

对全球大模型从性能、吞吐量、成本等方面有一定的认知,可以在云端和本地等多种环境下部署大模型,找到适合自己的项目/创业方向,做一名被 AI 武装的产品经理。

  • 硬件选型
  • 带你了解全球大模型
  • 使用国产大模型服务
  • 搭建 OpenAI 代理
  • 热身:基于阿里云 PAI 部署 Stable Diffusion
  • 在本地计算机运行大模型
  • 大模型的私有化部署
  • 基于 vLLM 部署大模型
  • 案例:如何优雅地在阿里云私有部署开源大模型
  • 部署一套开源 LLM 项目
  • 内容安全
  • 互联网信息服务算法备案

学习是一个过程,只要学习就会有挑战。天道酬勤,你越努力,就会成为越优秀的自己。

如果你能在15天内完成所有的任务,那你堪称天才。然而,如果你能完成 60-70% 的内容,你就已经开始具备成为一名大模型 AI 的正确特征了。

这份完整版的大模型 AI 学习资料已经上传CSDN,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费

在这里插入图片描述

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐