教程定位:从零开始系统学习大模型原理,兼顾专业性与通俗性

适用人群:零基础学习者、传统IT从业者、AI爱好者

学习周期:建议3-6个月系统学习

目录

  1. 开篇:大模型时代的到来
  1. 基础篇:机器学习与深度学习入门
  1. 核心篇:Transformer架构详解
  1. 进阶篇:注意力机制深度解析
  1. 训练篇:大模型预训练与微调
  1. 优化篇:模型压缩与推理加速
  1. 应用篇:大模型的实际应用
  1. 代码篇:从零实现大模型核心组件
  1. 展望篇:大模型的未来发展
  1. 附录:学习资源与工具推荐

1. 开篇:大模型时代的到来

1.1 什么是大模型?

1.1.1 从"程序"到"模型"的转变

在大模型出现之前,我们解决问题的方式是"写程序":程序员需要明确告诉计算机每一步该做什么,计算机严格按照程序执行。

比如,我们要做一个"判断一句话是正面还是负面"的程序,需要:

  1. 收集大量正面和负面的词汇
  1. 写规则:如果句子中正面词汇多,就判断为正面;负面词汇多,就判断为负面
  1. 不断调试规则,直到效果满意

但这种方式有很大的局限性:

  • 规则很难覆盖所有情况
  • 语言是灵活的,同样的意思可以有不同的表达方式
  • 规则维护成本很高

大模型的出现改变了这一切。我们不再需要写复杂的规则,只需要:

  1. 准备大量的文本数据
  1. 让大模型"学习"这些数据
  1. 大模型自动学会理解语言、完成任务
1.1.2 大模型的定义

大模型(Large Language Model,简称LLM),也叫"大语言模型",是一种基于深度学习的人工智能系统,它通过学习海量的文本数据,能够理解和生成人类语言。

简单来说,大模型就像一个"超级语言学习者":

  • 它"读"过的书比人类一辈子读的还要多得多
  • 它能理解语言的含义、语法、逻辑
  • 它能根据输入的内容,生成连贯、有意义的回答
1.1.3 大模型的"大"体现在哪里?

大模型的"大"主要体现在三个方面:

  1. 参数量大
    • 参数量是模型中可学习参数的数量,类似于人类大脑中的神经元连接
    • 早期的小模型可能只有几百万、几千万参数
    • 现在的大模型通常有几十亿、几百亿甚至上千亿参数
    • 比如:GPT-3有1750亿参数,通义千问有上千亿参数
  1. 训练数据量大
    • 大模型需要学习海量的文本数据
    • 这些数据包括:书籍、网页、文章、代码等
    • 总数据量可能达到几十TB甚至几百TB
    • 相当于"读"了几百万本书
  1. 计算量大
    • 训练大模型需要大量的计算资源
    • 通常需要成百上千张GPU(图形处理器)同时工作
    • 训练一次可能需要几周、几个月甚至更长时间
    • 电费、硬件成本可能达到几百万、几千万
小白问答

问:参数量是什么?为什么参数量越大,模型越"聪明"?

:你可以把参数量想象成模型的"大脑容量"。

就像人类大脑一样,神经元连接越多,能记住和理解的东西就越多。

参数量大的模型:

  • 能记住更多的知识
  • 能理解更复杂的语言
  • 能完成更困难的任务
  • 但这也不是绝对的,参数量只是衡量模型能力的一个指标,不是唯一指标。

问:大模型是怎么"学习"的?它真的"理解"了吗?

:这是一个很好的问题!

大模型的"学习"和人类的学习不太一样:

  • 人类学习是理解概念、建立逻辑
  • 大模型学习是"统计"语言的规律
  • 比如,当大模型看到"天空是___"时,它会根据统计规律,知道"蓝色"出现的概率最高,所以会填"蓝色"。
  • 从这个角度说,大模型可能没有真正"理解",但它通过统计规律,表现得像是理解了。

1.2 大模型的发展历程

1.2.1 早期的自然语言处理(2010年之前)

在大模型出现之前,自然语言处理(NLP)领域经历了几个阶段:

  1. 规则-based时代(1950s-1990s)
    • 完全依靠人工编写规则
    • 比如:语法规则、词典规则
    • 局限性:规则很难覆盖所有情况
  1. 统计机器学习时代(1990s-2010s)
    • 使用统计方法,让模型从数据中学习规律
    • 常用方法:朴素贝叶斯、支持向量机(SVM)、隐马尔可夫模型(HMM)
    • 局限性:需要大量人工标注数据,模型能力有限
1.2.2 深度学习时代(2010-2017)

2010年之后,深度学习开始应用于自然语言处理:

  1. 循环神经网络(RNN)
    • 能够处理序列数据(比如句子)
    • 有"记忆"能力,能记住之前的信息
    • 局限性:难以处理长序列,训练困难
  1. 长短期记忆网络(LSTM)
    • RNN的改进版,能更好地处理长序列
    • 在很多任务上取得了不错的效果
    • 局限性:并行计算困难,训练速度慢
  1. 注意力机制的萌芽
    • 2014年,注意力机制(Attention)被提出
    • 让模型能够"关注"输入中的重要部分
    • 为后来的Transformer奠定了基础
1.2.3 Transformer时代(2017-2020)

2017年是大模型发展史上的里程碑:

  1. Transformer架构的提出
    • 2017年,Google发表论文《Attention Is All You Need》
    • 提出了Transformer架构
    • 完全基于注意力机制,不再使用RNN
    • 优势:并行计算能力强,能处理长序列
  1. 预训练模型的兴起
    • 2018年,OpenAI提出GPT(Generative Pre-trained Transformer)
    • 2018年,Google提出BERT(Bidirectional Encoder Representations from Transformers)
    • 这些模型通过"预训练+微调"的方式,在很多任务上取得了最好效果
1.2.4 大模型时代(2020年至今)

2020年之后,大模型进入爆发期:

  1. GPT-3的发布
    • 2020年,OpenAI发布GPT-3,1750亿参数
    • 展示了大模型的惊人能力:写文章、写代码、翻译等
    • 让人们意识到大模型的巨大潜力
  1. ChatGPT的爆发
    • 2022年11月,OpenAI发布ChatGPT
    • 对话式交互,使用门槛大大降低
    • 迅速火遍全球,引发了大模型热潮
  1. 国内大模型的发展
    • 2023年,国内大模型如雨后春笋般涌现
    • 通义千问、文心一言、智谱AI、Llama等
    • 大模型技术快速普及
1.2.5 大模型发展时间线
timeline
    title 大模型发展时间线
    2017 : Transformer架构提出
    2018 : GPT-1发布<br>BERT发布
    2019 : GPT-2发布
    2020 : GPT-3发布(1750亿参数)
    2021 : 国内大模型开始起步
    2022 : ChatGPT发布<br>引发全球热潮
    2023 : 国内大模型爆发<br>通义千问、文心一言等
    2024 : 多模态大模型兴起<br>小模型性能提升

1.3 大模型的核心特性

1.3.1 语言理解能力

大模型最核心的能力是理解人类语言:

  1. 语义理解
    • 理解词语、句子的含义
    • 理解上下文、语境
    • 理解隐含的意思、言外之意
  1. 语法理解
    • 理解语法规则
    • 识别句子结构
    • 纠正语法错误
  1. 逻辑理解
    • 理解因果关系
    • 理解推理过程
    • 进行简单的逻辑推理
1.3.2 语言生成能力

大模型不仅能理解,还能生成语言:

  1. 文本生成
    • 写文章、写故事、写诗歌
    • 写邮件、写报告、写总结
    • 内容连贯、语法正确
  1. 对话生成
    • 进行多轮对话
    • 理解对话上下文
    • 给出合适的回应
  1. 代码生成
    • 根据需求写代码
    • 解释代码含义
    • 修复代码bug
1.3.3 知识存储与应用

大模型在训练过程中学习了大量知识:

  1. 知识存储
    • 存储了海量的事实性知识
    • 存储了语言知识、常识知识
    • 存储了专业领域知识
  1. 知识应用
    • 回答问题
    • 解释概念
    • 提供建议
  1. 知识更新
    • 传统大模型的知识是"静态"的,训练截止后知识就固定了
    • 现在可以通过RAG(检索增强生成)等技术,让大模型使用最新知识
1.3.4 泛化能力

大模型的一个重要特性是"泛化能力":

  1. 任务泛化
    • 一个模型能完成多种任务
    • 不需要为每个任务单独训练
    • 通过Prompt就能切换任务
  1. 领域泛化
    • 能处理不同领域的问题
    • 通用领域、专业领域都能应对
    • 不需要专门的领域训练
  1. 语言泛化
    • 能处理多种语言
    • 翻译、多语言对话
    • 跨语言理解
1.3.5 涌现能力

当模型规模达到一定程度时,会出现"涌现能力"(Emergent Abilities):

  1. 什么是涌现能力?
    • 小模型不具备的能力
    • 当模型规模达到一定程度时突然出现
    • 类似于"量变引起质变"
  1. 常见的涌现能力
    • 复杂推理能力
    • 多步任务规划能力
    • 抽象概念理解能力
    • 创意生成能力
  1. 涌现能力的意义
    • 这是大模型最令人兴奋的特性之一
    • 意味着更大的模型可能会有更多意想不到的能力
    • 也让我们对大模型的潜力充满期待
小白问答

问:什么是"泛化能力"?能举个例子吗?

:"泛化能力"简单说就是"举一反三"的能力。

比如:

  • 你教一个小学生"1+1=2"
  • 他不仅会算"1+1",还会算"2+3"、"5+7"
  • 这就是泛化能力
  • 大模型也是一样:
  • 它在训练时见过很多例子
  • 但它能处理训练时没见过的新问题
  • 这就是泛化能力强的表现

问:涌现能力是怎么出现的?为什么小模型没有?

:这是一个非常前沿的研究问题,科学家们还在研究中。

一个简单的类比:

  • 一滴水很小,看不出什么
  • 但很多水滴聚在一起,就能形成河流、海洋
  • 这时候就会出现"波浪"、"潮汐"等单个水滴没有的特性
  • 大模型的涌现能力可能也是类似:
  • 当参数量、数据量达到一定程度
  • 模型内部会形成复杂的"连接"和"结构"
  • 从而出现小模型没有的能力
  • 这也是为什么大家都在追求"更大"的模型的原因之一。

1.4 大模型能做什么?

1.4.1 文本处理类
  1. 文本生成
    • 写文章、写故事、写诗歌
    • 写邮件、写报告、写总结
    • 写广告文案、写产品描述
  1. 文本理解
    • 文本分类(正面/负面、主题分类)
    • 情感分析(判断情绪)
    • 意图识别(理解用户想做什么)
  1. 文本转换
    • 翻译(中英互译、多语言翻译)
    • 改写(润色、简化、扩写)
    • 格式转换(文本转表格、文本转JSON)
1.4.2 知识问答类
  1. 通用问答
    • 回答常识问题
    • 解释概念、定义
    • 提供信息、数据
  1. 专业问答
    • 医疗健康咨询
    • 法律咨询
    • 技术问题解答
  1. 教育辅导
    • 讲解知识点
    • 解题思路指导
    • 作业批改、反馈
1.4.3 编程开发类
  1. 代码生成
    • 根据需求写代码
    • 补全代码片段
    • 多种编程语言支持
  1. 代码理解
    • 解释代码含义
    • 代码审查、建议
    • 代码重构建议
  1. 调试修复
    • 定位bug原因
    • 提供修复方案
    • 性能优化建议
1.4.4 创意创作类
  1. 内容创作
    • 写小说、剧本
    • 写歌词、诗歌
    • 创作故事、创意
  1. 艺术设计
    • 设计思路建议
    • 配色方案推荐
    • 文案、标语创作
  1. 游戏娱乐
    • 游戏剧情设计
    • 角色对话生成
    • 谜题设计
1.4.5 企业应用类
  1. 客户服务
    • 智能客服
    • 常见问题解答
    • 工单处理
  1. 内容运营
    • 内容生成
    • 标题优化
    • SEO建议
  1. 数据分析
    • 数据解读
    • 报告生成
    • 趋势分析
小白问答

问:大模型这么厉害,它会取代人类吗?

:这是一个很多人关心的问题。

我的看法是:大模型会"改变"很多工作,但不会完全"取代"人类。

原因:

  1. 大模型没有真正的"理解"和"意识"
  1. 大模型可能会"幻觉"(编造信息)
  1. 大模型没有情感、价值观、创造力
  1. 很多工作需要人类的判断力、同理心、创造力
  1. 更可能的情况是:
  • 大模型成为人类的"助手"
  • 人类负责决策、创造、判断
  • 大模型负责处理重复性、机械性的工作
  • 人类和大模型协作,效率更高

问:大模型会"幻觉"吗?什么是幻觉?

:是的,大模型会"幻觉"(Hallucination),这是大模型的一个重要问题。

"幻觉"简单说就是:

  • 大模型编造了一些信息
  • 但它表现得像是真的一样
  • 听起来很有道理,但实际上是错的
  • 比如:
  • 你问大模型"某某人获得过诺贝尔奖吗?"
  • 大模型可能会编造一个获奖理由
  • 但实际上这个人根本没有获奖
  • 为什么会出现幻觉?
  • 大模型是根据统计规律生成内容的
  • 它可能会"合理地编造"一些信息
  • 它不知道哪些是真的,哪些是假的
  • 所以使用大模型时:
  • 重要信息一定要核实
  • 不要完全相信大模型的回答
  • 尤其是专业领域、事实性问题

1.5 本章总结与回顾

1.5.1 核心知识点总结
  1. 大模型的定义
    • Large Language Model(LLM)
    • 基于深度学习的人工智能系统
    • 通过学习海量文本数据,理解和生成人类语言
  1. 大模型的"大"
    • 参数量大(几十亿、几百亿、上千亿)
    • 训练数据量大(几十TB、几百TB)
    • 计算量大(需要大量GPU)
  1. 大模型的发展历程
    • 规则-based时代 → 统计机器学习时代 → 深度学习时代 → Transformer时代 → 大模型时代
    • 2017年Transformer架构提出是重要里程碑
    • 2022年ChatGPT发布引发全球热潮
  1. 大模型的核心特性
    • 语言理解能力
    • 语言生成能力
    • 知识存储与应用
    • 泛化能力(举一反三)
    • 涌现能力(量变引起质变)
  1. 大模型的应用
    • 文本处理、知识问答
    • 编程开发、创意创作
    • 企业应用等
1.5.2 重要概念回顾

概念

解释

大模型(LLM)

Large Language Model,基于深度学习的人工智能系统,能理解和生成人类语言

参数量

模型中可学习参数的数量,类似于大脑神经元连接

Transformer

2017年提出的架构,完全基于注意力机制,是大模型的基础

泛化能力

模型处理未见过的新问题的能力,即"举一反三"

涌现能力

当模型规模达到一定程度时突然出现的能力,小模型不具备

幻觉

大模型编造信息,但表现得像是真的一样

1.5.3 扩展阅读资源
  1. 论文推荐
    • 《Attention Is All You Need》(2017)- Transformer架构原始论文
    • 《Language Models are Few-Shot Learners》(2020)- GPT-3论文
    • 《GPT-4 Technical Report》(2023)- GPT-4技术报告
  1. 书籍推荐
    • 《深度学习》(Goodfellow等著)- 深度学习经典教材
    • 《动手学深度学习》(李沐等著)- 通俗易懂的深度学习入门书
    • 《大模型时代》(李开复等著)- 大模型科普书
  1. 在线资源
1.5.4 下一步学习建议

在开始下一章之前,建议你:

  1. 体验一下大模型:
    • 试用ChatGPT、通义千问等大模型
    • 尝试不同的任务:问答、写作、编程
    • 感受大模型的能力和局限性
  1. 了解一些基础概念:
    • 什么是机器学习?
    • 什么是深度学习?
    • 什么是神经网络?
  1. 准备学习心态:
    • 大模型原理涉及一些数学,但不要害怕
    • 我们会用通俗易懂的方式讲解
    • 重点是理解概念,不是推导公式

2. 基础篇:机器学习与深度学习入门

2.1 什么是机器学习?

2.1.1 从"写程序"到"学程序"

传统编程是"数据+规则=答案",比如计算圆的面积:


# 传统编程:明确规则
import math
def calculate_circle_area(radius):
    # 人类定义的规则:面积 = πr²
    return math.pi * radius * radius

# 输入数据,得到答案
print(calculate_circle_area(5))  # 输出: 78.53981633974483

机器学习则是"数据+答案=规则",比如让模型学习区分猫和狗的图片:


# 机器学习思路
数据:1000张猫的图片 + 1000张狗的图片
答案:每张图片的标签(猫/狗)
规则:模型自动学习的区分特征(比如耳朵形状、鼻子大小)

这种模式的优势在于,当规则过于复杂(比如语言理解),人类无法手动定义时,机器学习可以从数据中自动学习。

2.1.2 机器学习的定义

机器学习(Machine Learning,ML) 是人工智能的一个分支,它让计算机能够在没有被明确编程的情况下学习。简单来说,机器学习就是让计算机从数据中学习规律,并用这些规律来预测新的数据。

核心公式:经验(数据)→ 学习 → 改进 → 预测

2.1.3 机器学习的分类

根据学习方式的不同,机器学习主要分为三类:

  1. 监督学习(Supervised Learning)
    • 特点:数据带有标签(答案)
    • 目标:学习输入到输出的映射关系
    • 常见任务:
      • 分类(Classification):预测离散值(比如猫/狗、正面/负面)
      • 回归(Regression):预测连续值(比如房价、温度)
    • 例子:垃圾邮件识别、房价预测、图像分类
  1. 无监督学习(Unsupervised Learning)
    • 特点:数据没有标签
    • 目标:发现数据中的隐藏模式或结构
    • 常见任务:
      • 聚类(Clustering):将相似的数据分组
      • 降维(Dimensionality Reduction):减少数据维度,保留关键信息
    • 例子:用户分群、异常检测、数据压缩
  1. 强化学习(Reinforcement Learning)
    • 特点:通过与环境交互学习
    • 目标:学习最优的行动策略,最大化奖励
    • 核心概念:智能体(Agent)、环境(Environment)、奖励(Reward)
    • 例子:AlphaGo、自动驾驶、游戏AI
小白问答

问:监督学习和无监督学习的区别是什么?能举个例子吗?

:最核心的区别是数据是否有标签:

  • 监督学习:老师教学生(有标准答案)

比如:给学生100道数学题+答案,学生学习解题方法

  • 无监督学习:学生自己看书总结规律(无标准答案)

比如:给学生100篇文章,学生自己总结出不同的主题

-

  • 实际应用例子:
  • 监督学习:用带标签的邮件(垃圾/非垃圾)训练垃圾邮件识别模型
  • 无监督学习:将用户的购买记录分组,发现不同的消费习惯

2.2 神经网络基础

2.2.1 从生物神经元到人工神经元

人类大脑中有约860亿个神经元,每个神经元通过突触连接,形成复杂的网络。当神经元接收到足够的信号时,就会被激活并传递信号。

人工神经元(Artificial Neuron)是对生物神经元的简化模拟:

graph TD
    A[输入1] -->|权重1| C[求和]
    B[输入2] -->|权重2| C
    D[偏置] --> C
    C --> E[激活函数]
    E --> F[输出]

核心计算过程:

  1. 每个输入乘以对应的权重
  1. 求和后加上偏置
  1. 通过激活函数得到输出

数学表达式: y = f(\sum_{i=1}^{n} w_i x_i + b)

2.2.2 感知机

感知机(Perceptron)是最简单的人工神经元模型,由Frank Rosenblatt在1957年提出:


import numpy as np

class Perceptron:
    def __init__(self, input_size, learning_rate=0.1, epochs=100):
        # 初始化权重和偏置
        self.weights = np.zeros(input_size)
        self.bias = 0
        self.learning_rate = learning_rate
        self.epochs = epochs
    
    # 激活函数:阶跃函数
    def activate(self, x):
        return 1 if x >= 0 else 0
    
    # 预测
    def predict(self, x):
        # 计算加权和 + 偏置
        linear_output = np.dot(x, self.weights) + self.bias
        # 通过激活函数
        return self.activate(linear_output)
    
    # 训练
    def train(self, X, y):
        for _ in range(self.epochs):
            for inputs, label in zip(X, y):
                # 预测
                prediction = self.predict(inputs)
                # 计算误差
                error = label - prediction
                # 更新权重和偏置
                self.weights += self.learning_rate * error * inputs
                self.bias += self.learning_rate * error

# 测试:学习逻辑与(AND)
if __name__ == "__main__":
    # 训练数据:逻辑与的输入和输出
    X = np.array([[0,0], [0,1], [1,0], [1,1]])
    y = np.array([0, 0, 0, 1])
    
    # 创建感知机
    perceptron = Perceptron(input_size=2)
    # 训练
    perceptron.train(X, y)
    
    # 测试
    print("0 AND 0 =", perceptron.predict([0,0]))  # 0
    print("0 AND 1 =", perceptron.predict([0,1]))  # 0
    print("1 AND 0 =", perceptron.predict([1,0]))  # 0
    print("1 AND 1 =", perceptron.predict([1,1]))  # 1
2.2.3 激活函数

激活函数是神经网络的核心,它为线性的神经元添加非线性,让神经网络能够学习复杂的模式。

常见的激活函数:

  1. Sigmoid函数
    • 公式: σ(x) = \frac{1}{1 + e^{-x}}
    • 输出范围:(0, 1)
    • 特点:平滑、可微,但存在梯度消失问题
    • 用途:二分类的输出层
  1. Tanh函数
    • 公式: tanh(x) = \frac{e^x - e^{-x}}{e^x + e^{-x}}
    • 输出范围:(-1, 1)
    • 特点:零均值,比Sigmoid收敛更快
  1. ReLU函数
    • 公式: ReLU(x) = max(0, x)
    • 输出范围:[0, ∞)
    • 特点:计算简单,缓解梯度消失,是目前最常用的激活函数
    • 缺点:存在"死亡ReLU"问题(某些神经元永远不激活)
  1. Softmax函数
    • 公式: σ(z)_i = \frac{e^{z_i}}{\sum_{j=1}^{K} e^{z_j}}
    • 输出范围:(0, 1),所有输出之和为1
    • 用途:多分类的输出层

import numpy as np
import matplotlib.pyplot as plt

# 定义激活函数
def sigmoid(x):
    return 1 / (1 + np.exp(-x))

def tanh(x):
    return np.tanh(x)

def relu(x):
    return np.maximum(0, x)

def softmax(x):
    exp_x = np.exp(x - np.max(x))  # 防止溢出
    return exp_x / np.sum(exp_x)

# 可视化
x = np.linspace(-5, 5, 100)
plt.figure(figsize=(12, 8))

plt.subplot(2, 2, 1)
plt.plot(x, sigmoid(x))
plt.title('Sigmoid')
plt.grid(True)

plt.subplot(2, 2, 2)
plt.plot(x, tanh(x))
plt.title('Tanh')
plt.grid(True)

plt.subplot(2, 2, 3)
plt.plot(x, relu(x))
plt.title('ReLU')
plt.grid(True)

plt.subplot(2, 2, 4)
plt.plot(x, softmax(x))
plt.title('Softmax (示例)')
plt.grid(True)

plt.tight_layout()
plt.show()

2.3 深度学习入门

2.3.1 什么是深度学习?

深度学习(Deep Learning) 是机器学习的一个子领域,它使用多层神经网络来学习数据的特征表示。"深度"指的是神经网络的层数较多(通常至少3层)。

深度学习的核心思想是特征学习:模型自动从数据中学习特征,而不需要人工设计特征。

2.3.2 深度学习的优势
  1. 自动特征学习:无需人工设计特征
  1. 处理复杂数据:擅长处理图像、语音、文本等非结构化数据
  1. 端到端学习:从原始数据直接学习到目标输出
  1. 可扩展性:增加数据和模型规模,性能通常会提升
2.3.3 常见的深度学习架构
  1. 卷积神经网络(CNN)
    • 专门处理网格结构数据(如图像)
    • 核心操作:卷积、池化
    • 特点:共享权重、局部连接
    • 应用:图像识别、目标检测、图像生成
  1. 循环神经网络(RNN)
    • 专门处理序列数据(如文本、语音)
    • 特点:有记忆能力,能处理变长序列
    • 变体:LSTM、GRU(解决长序列依赖问题)
    • 应用:语言模型、机器翻译、语音识别
  1. Transformer
    • 基于注意力机制的架构
    • 完全并行计算,训练速度快
    • 能处理长序列
    • 应用:大语言模型、机器翻译、多模态模型

2.4 神经网络的训练

2.4.1 损失函数

损失函数(Loss Function)用于衡量模型预测值与真实值之间的差距,是训练的核心。

常见的损失函数:

  1. 均方误差(MSE)
    • 公式: MSE = \frac{1}{n} \sum_{i=1}^{n} (y_i - \hat{y}_i)^2
    • 用途:回归任务
  1. 交叉熵损失(Cross-Entropy Loss)
    • 二分类: CE = -\frac{1}{n} \sum_{i=1}^{n} [y_i log(\hat{y}_i) + (1-y_i) log(1-\hat{y}_i)]
    • 多分类: CE = -\frac{1}{n} \sum_{i=1}^{n} \sum_{j=1}^{k} y_{ij} log(\hat{y}_{ij})
    • 用途:分类任务
2.4.2 反向传播

反向传播(Backpropagation)是训练神经网络的核心算法,它的基本思想是:

  1. 前向传播:计算预测值和损失
  1. 反向传播:计算损失对每个参数的梯度
  1. 参数更新:根据梯度调整参数,减小损失
graph TD
    A[输入数据] --> B[前向传播]
    B --> C[计算预测值]
    C --> D[计算损失]
    D --> E[反向传播]
    E --> F[计算梯度]
    F --> G[参数更新]
    G --> B
2.4.3 优化器

优化器(Optimizer)用于根据梯度更新参数,常见的优化器:

  1. 随机梯度下降(SGD)
    • 公式: θ = θ - η ∇L(θ)
    • 特点:简单,但收敛慢
  1. 动量SGD(SGD with Momentum)
    • 引入动量,加速收敛,减少震荡
  1. Adam
    • 结合动量和自适应学习率
    • 目前最常用的优化器
    • 收敛快,稳定性好

2.5 本章总结与回顾

2.5.1 核心知识点总结
  1. 机器学习:让计算机从数据中学习规律,分为监督学习、无监督学习、强化学习
  1. 神经网络:由人工神经元组成的网络,通过激活函数引入非线性
  1. 深度学习:使用深层神经网络进行特征学习
  1. 训练过程:通过前向传播计算损失,反向传播计算梯度,优化器更新参数
2.5.2 重要概念回顾

概念

解释

监督学习

数据带标签,学习输入到输出的映射

无监督学习

数据无标签,发现数据的隐藏模式

激活函数

为神经元添加非线性,常用ReLU、Sigmoid

损失函数

衡量预测值与真实值的差距,常用MSE、交叉熵

反向传播

计算损失对参数的梯度,用于参数更新

优化器

根据梯度更新参数,常用Adam、SGD


3. 核心篇:Transformer架构详解

3.1 Transformer架构总览

3.1.1 为什么需要Transformer?

在Transformer出现之前,处理序列数据主要使用RNN及其变体(LSTM、GRU),但RNN有两个致命缺点:

  1. 并行计算困难:RNN需要按顺序处理序列,无法并行计算
  1. 长序列依赖问题:难以捕捉长距离的依赖关系

Transformer完全基于注意力机制,解决了这两个问题:

  • 完全并行计算,训练速度大幅提升
  • 能直接捕捉任意位置的依赖关系
  • 更容易训练深层模型
3.1.2 Transformer的整体结构

Transformer主要由两部分组成:编码器(Encoder)和解码器(Decoder)。

graph TD
    subgraph Transformer
        subgraph 编码器
            A[输入嵌入层] --> B[位置编码]
            B --> C[编码器层1]
            C --> D[编码器层2]
            D --> E[...编码器层N]
        end
        
        subgraph 解码器
            F[输出嵌入层] --> G[位置编码]
            G --> H[解码器层1]
            H --> I[解码器层2]
            I --> J[...解码器层N]
            J --> K[线性层]
            K --> L[Softmax]
        end
        
        E --> H
        E --> I
        E --> J
    end
    
    M[输入序列] --> A
    N[输出序列] --> F
    L --> O[预测序列]

Transformer的核心特点:

  1. 完全基于注意力机制,没有RNN/CNN
  1. 编码器和解码器都由多个相同的层堆叠而成
  1. 使用位置编码来捕捉序列的顺序信息
  1. 编码器处理输入序列,解码器生成输出序列
3.1.3 Transformer的核心思想

Transformer的核心思想是自注意力机制(Self-Attention),它让模型能够关注输入序列中不同位置的信息,从而捕捉长距离依赖。

3.2 编码器详解

3.2.1 编码器的整体结构

每个编码器层包含两个子层:

  1. 多头自注意力层(Multi-Head Self-Attention)
  1. 前馈神经网络层(Feed Forward Network)
  1. 每个子层都有残差连接(Residual Connection)和层归一化(Layer Normalization)
graph TD
    A[输入] --> B[多头自注意力层]
    B --> C[残差连接+层归一化]
    C --> D[前馈神经网络]
    D --> E[残差连接+层归一化]
    E --> F[输出]
3.2.2 输入嵌入与位置编码
  1. 输入嵌入(Input Embedding)
    • 将离散的token转换为连续的向量
    • 嵌入维度通常为d_model(比如512)
    • 所有token共享同一个嵌入矩阵
  1. 位置编码(Positional Encoding)
    • Transformer没有顺序信息,需要显式添加位置信息
    • 位置编码的维度与嵌入维度相同
    • 可以使用正弦/余弦函数或可学习的位置编码

正弦位置编码的公式:

PE_{(pos,2i)} = sin(pos / 10000^{2i/d_{model}})

PE_{(pos,2i+1)} = cos(pos / 10000^{2i/d_{model}})

3.2.3 多头自注意力机制

多头自注意力是Transformer的核心,它将自注意力机制分成多个头,每个头学习不同的注意力模式。


import torch
import torch.nn as nn
import torch.nn.functional as F

class MultiHeadAttention(nn.Module):
    def __init__(self, d_model, num_heads):
        super().__init__()
        assert d_model % num_heads == 0, "d_model必须能被num_heads整除"
        
        self.d_model = d_model
        self.num_heads = num_heads
        self.d_k = d_model // num_heads  # 每个头的维度
        
        # 线性变换层
        self.w_q = nn.Linear(d_model, d_model)
        self.w_k = nn.Linear(d_model, d_model)
        self.w_v = nn.Linear(d_model, d_model)
        self.w_o = nn.Linear(d_model, d_model)
        
    def scaled_dot_product_attention(self, q, k, v, mask=None):
        """
        缩放点积注意力
        q: [batch_size, num_heads, seq_len, d_k]
        k: [batch_size, num_heads, seq_len, d_k]
        v: [batch_size, num_heads, seq_len, d_k]
        """
        # 计算注意力分数: Q * K^T / sqrt(d_k)
        attn_scores = torch.matmul(q, k.transpose(-2, -1)) / torch.sqrt(torch.tensor(self.d_k, dtype=torch.float32))
        
        # 应用掩码(可选)
        if mask is not None:
            attn_scores = attn_scores.masked_fill(mask == 0, -1e9)
        
        # Softmax得到注意力权重
        attn_weights = F.softmax(attn_scores, dim=-1)
        
        # 加权求和得到输出
        output = torch.matmul(attn_weights, v)
        
        return output, attn_weights
    
    def forward(self, q, k, v, mask=None):
        batch_size = q.size(0)
        
        # 1. 线性变换
        q = self.w_q(q)  # [batch_size, seq_len, d_model]
        k = self.w_k(k)
        v = self.w_v(v)
        
        # 2. 分头: [batch_size, seq_len, d_model] -> [batch_size, num_heads, seq_len, d_k]
        q = q.view(batch_size, -1, self.num_heads, self.d_k).transpose(1, 2)
        k = k.view(batch_size, -1, self.num_heads, self.d_k).transpose(1, 2)
        v = v.view(batch_size, -1, self.num_heads, self.d_k).transpose(1, 2)
        
        # 3. 计算注意力
        attn_output, attn_weights = self.scaled_dot_product_attention(q, k, v, mask)
        
        # 4. 拼接头: [batch_size, num_heads, seq_len, d_k] -> [batch_size, seq_len, d_model]
        attn_output = attn_output.transpose(1, 2).contiguous().view(batch_size, -1, self.d_model)
        
        # 5. 最终线性变换
        output = self.w_o(attn_output)
        
        return output, attn_weights
3.2.4 前馈神经网络

前馈神经网络是一个简单的两层全连接网络:


class PositionwiseFeedForward(nn.Module):
    def __init__(self, d_model, d_ff, dropout=0.1):
        super().__init__()
        self.fc1 = nn.Linear(d_model, d_ff)
        self.fc2 = nn.Linear(d_ff, d_model)
        self.dropout = nn.Dropout(dropout)
        self.relu = nn.ReLU()
        
    def forward(self, x):
        # x: [batch_size, seq_len, d_model]
        x = self.fc1(x)      # [batch_size, seq_len, d_ff]
        x = self.relu(x)
        x = self.dropout(x)
        x = self.fc2(x)      # [batch_size, seq_len, d_model]
        return x
3.2.5 残差连接与层归一化

残差连接解决了深层网络的梯度消失问题,层归一化加速训练:


class EncoderLayer(nn.Module):
    def __init__(self, d_model, num_heads, d_ff, dropout=0.1):
        super().__init__()
        self.self_attn = MultiHeadAttention(d_model, num_heads)
        self.feed_forward = PositionwiseFeedForward(d_model, d_ff, dropout)
        
        # 层归一化
        self.norm1 = nn.LayerNorm(d_model)
        self.norm2 = nn.LayerNorm(d_model)
        
        self.dropout1 = nn.Dropout(dropout)
        self.dropout2 = nn.Dropout(dropout)
        
    def forward(self, x, mask=None):
        # 多头自注意力 + 残差连接 + 层归一化
        attn_output, _ = self.self_attn(x, x, x, mask)
        x = self.norm1(x + self.dropout1(attn_output))
        
        # 前馈网络 + 残差连接 + 层归一化
        ff_output = self.feed_forward(x)
        x = self.norm2(x + self.dropout2(ff_output))
        
        return x

3.3 解码器详解

3.3.1 解码器的整体结构

每个解码器层包含三个子层:

  1. 掩码多头自注意力层(Masked Multi-Head Self-Attention)
  1. 编码器-解码器注意力层(Encoder-Decoder Attention)
  1. 前馈神经网络层
  1. 每个子层都有残差连接和层归一化
graph TD
    A[输入] --> B[掩码多头自注意力层]
    B --> C[残差连接+层归一化]
    C --> D[编码器-解码器注意力层]
    D --> E[残差连接+层归一化]
    E --> F[前馈神经网络]
    F --> G[残差连接+层归一化]
    G --> H[输出]
3.3.2 掩码多头自注意力

掩码自注意力用于防止模型看到未来的token:


class DecoderLayer(nn.Module):
    def __init__(self, d_model, num_heads, d_ff, dropout=0.1):
        super().__init__()
        self.self_attn = MultiHeadAttention(d_model, num_heads)
        self.enc_dec_attn = MultiHeadAttention(d_model, num_heads)
        self.feed_forward = PositionwiseFeedForward(d_model, d_ff, dropout)
        
        self.norm1 = nn.LayerNorm(d_model)
        self.norm2 = nn.LayerNorm(d_model)
        self.norm3 = nn.LayerNorm(d_model)
        
        self.dropout1 = nn.Dropout(dropout)
        self.dropout2 = nn.Dropout(dropout)
        self.dropout3 = nn.Dropout(dropout)
        
    def forward(self, x, enc_output, src_mask=None, tgt_mask=None):
        # 1. 掩码自注意力
        attn1_output, _ = self.self_attn(x, x, x, tgt_mask)
        x = self.norm1(x + self.dropout1(attn1_output))
        
        # 2. 编码器-解码器注意力
        attn2_output, _ = self.enc_dec_attn(x, enc_output, enc_output, src_mask)
        x = self.norm2(x + self.dropout2(attn2_output))
        
        # 3. 前馈网络
        ff_output = self.feed_forward(x)
        x = self.norm3(x + self.dropout3(ff_output))
        
        return x
3.3.3 完整的Transformer实现

class Transformer(nn.Module):
    def __init__(self, src_vocab_size, tgt_vocab_size, d_model=512, num_heads=8, 
                 num_layers=6, d_ff=2048, max_seq_len=512, dropout=0.1):
        super().__init__()
        
        # 嵌入层
        self.src_embedding = nn.Embedding(src_vocab_size, d_model)
        self.tgt_embedding = nn.Embedding(tgt_vocab_size, d_model)
        
        # 位置编码
        self.positional_encoding = self._generate_positional_encoding(max_seq_len, d_model)
        
        # 编码器和解码器
        self.encoder_layers = nn.ModuleList([
            EncoderLayer(d_model, num_heads, d_ff, dropout) 
            for _ in range(num_layers)
        ])
        self.decoder_layers = nn.ModuleList([
            DecoderLayer(d_model, num_heads, d_ff, dropout) 
            for _ in range(num_layers)
        ])
        
        # 输出层
        self.fc = nn.Linear(d_model, tgt_vocab_size)
        self.dropout = nn.Dropout(dropout)
        
    def _generate_positional_encoding(self, max_seq_len, d_model):
        """生成正弦位置编码"""
        pe = torch.zeros(max_seq_len, d_model)
        position = torch.arange(0, max_seq_len, dtype=torch.float).unsqueeze(1)
        div_term = torch.exp(torch.arange(0, d_model, 2).float() * (-torch.log(torch.tensor(10000.0)) / d_model))
        
        pe[:, 0::2] = torch.sin(position * div_term)
        pe[:, 1::2] = torch.cos(position * div_term)
        pe = pe.unsqueeze(0)  # [1, max_seq_len, d_model]
        return pe
    
    def forward(self, src, tgt, src_mask=None, tgt_mask=None):
        # 输入嵌入 + 位置编码
        src_emb = self.src_embedding(src) * torch.sqrt(torch.tensor(self.src_embedding.embedding_dim, dtype=torch.float32))
        src_emb = src_emb + self.positional_encoding[:, :src.size(1), :]
        src_emb = self.dropout(src_emb)
        
        # 目标嵌入 + 位置编码
        tgt_emb = self.tgt_embedding(tgt) * torch.sqrt(torch.tensor(self.tgt_embedding.embedding_dim, dtype=torch.float32))
        tgt_emb = tgt_emb + self.positional_encoding[:, :tgt.size(1), :]
        tgt_emb = self.dropout(tgt_emb)
        
        # 编码器前向传播
        enc_output = src_emb
        for enc_layer in self.encoder_layers:
            enc_output = enc_layer(enc_output, src_mask)
        
        # 解码器前向传播
        dec_output = tgt_emb
        for dec_layer in self.decoder_layers:
            dec_output = dec_layer(dec_output, enc_output, src_mask, tgt_mask)
        
        # 输出层
        output = self.fc(dec_output)
        
        return output

3.4 本章总结与回顾

3.4.1 核心知识点总结
  1. Transformer架构:由编码器和解码器组成,完全基于注意力机制
  1. 自注意力机制:让模型关注输入序列的不同位置,捕捉长距离依赖
  1. 多头注意力:多个自注意力头,学习不同的注意力模式
  1. 位置编码:为Transformer添加顺序信息
  1. 残差连接和层归一化:解决深层网络训练问题
3.4.2 重要概念回顾

概念

解释

自注意力

输入序列内部的注意力,每个位置关注所有位置

多头注意力

将自注意力分成多个头,学习不同的注意力模式

位置编码

为Transformer添加顺序信息

残差连接

x = x + f(x),解决梯度消失问题

层归一化

对每个样本的特征维度归一化,加速训练

掩码注意力

防止解码器看到未来的token


4. 进阶篇:注意力机制深度解析

4.1 注意力机制的基本思想

4.1.1 什么是注意力?

注意力机制的核心思想来源于人类的注意力:当我们看一张图片或读一段话时,会重点关注其中的某些部分,而不是平均关注所有部分。

在深度学习中,注意力机制让模型能够动态地关注输入的不同部分,根据重要性分配不同的权重。

4.1.2 注意力机制的类比

想象你在做阅读理解:

  • 问题:"小明去超市买了什么?"
  • 文章:"小明今天下午去超市买了苹果、香蕉和牛奶,然后去公园玩了。"
  • 你的注意力会集中在"买了苹果、香蕉和牛奶"这部分,而忽略其他部分

注意力机制做的就是类似的事情:根据当前任务,计算输入各部分的重要性权重。

4.1.3 注意力机制的发展历程
  1. 软注意力(Soft Attention):最早的注意力机制,权重是连续的
  1. 硬注意力(Hard Attention):选择输入的一部分,权重是离散的
  1. 自注意力(Self-Attention):输入序列内部的注意力
  1. 多头注意力(Multi-Head Attention):多个注意力头,捕捉不同模式

4.2 自注意力机制

4.2.1 Query、Key、Value

自注意力机制基于三个向量:

  • Query(查询):当前位置的表示,用于查询相关信息
  • Key(键):所有位置的表示,用于匹配Query
  • Value(值):所有位置的表示,用于生成输出

类比字典查询:

  • Query:你要查的单词
  • Key:字典中的所有单词
  • Value:字典中的解释
4.2.2 注意力分数计算

注意力分数衡量Query和Key的匹配程度,常见的计算方式:

  1. 点积注意力(Dot-Product Attention)
    • 公式: score(q, k) = q \cdot k
    • 简单高效,但对向量长度敏感
  1. 缩放点积注意力(Scaled Dot-Product Attention)
    • 公式: score(q, k) = \frac{q \cdot k}{\sqrt{d_k}}
    • Transformer使用的方式,解决维度大时分数过大的问题
  1. 加性注意力(Additive Attention)
    • 公式: score(q, k) = v^T tanh(W_q q + W_k k)
    • 适合Query和Key维度不同的情况
4.2.3 缩放点积注意力的完整流程
graph TD
    A[Query] --> B[计算Q·K^T]
    C[Key] --> B
    B --> D[除以√d_k]
    D --> E[Softmax归一化]
    E --> F[注意力权重]
    G[Value] --> H[加权求和]
    F --> H
    H --> I[输出]

数学流程:

  1. 计算Query和所有Key的点积: QK^T
  1. 缩放:除以 \sqrt{d_k}
  1. Softmax归一化,得到注意力权重
  1. 权重与Value加权求和,得到输出
4.2.4 自注意力的代码实现

import torch
import torch.nn.functional as F

def scaled_dot_product_attention(q, k, v, mask=None):
    """
    缩放点积注意力的纯PyTorch实现
    q: [batch_size, seq_len_q, d_k]
    k: [batch_size, seq_len_k, d_k]
    v: [batch_size, seq_len_v, d_v] (seq_len_k == seq_len_v)
    mask: [batch_size, seq_len_q, seq_len_k] 或 None
    """
    d_k = q.size(-1)
    
    # 1. 计算Q·K^T
    attn_scores = torch.matmul(q, k.transpose(-2, -1))  # [batch_size, seq_len_q, seq_len_k]
    
    # 2. 缩放
    attn_scores = attn_scores / torch.sqrt(torch.tensor(d_k, dtype=torch.float32))
    
    # 3. 应用掩码
    if mask is not None:
        attn_scores = attn_scores.masked_fill(mask == 0, -1e9)
    
    # 4. Softmax得到注意力权重
    attn_weights = F.softmax(attn_scores, dim=-1)  # [batch_size, seq_len_q, seq_len_k]
    
    # 5. 加权求和
    output = torch.matmul(attn_weights, v)  # [batch_size, seq_len_q, d_v]
    
    return output, attn_weights

# 测试
if __name__ == "__main__":
    # 随机生成Q, K, V
    batch_size = 2
    seq_len = 4
    d_k = 8
    
    q = torch.randn(batch_size, seq_len, d_k)
    k = torch.randn(batch_size, seq_len, d_k)
    v = torch.randn(batch_size, seq_len, d_k)
    
    # 计算注意力
    output, attn_weights = scaled_dot_product_attention(q, k, v)
    
    print("输入形状:", q.shape)
    print("输出形状:", output.shape)
    print("注意力权重形状:", attn_weights.shape)
    print("\n注意力权重示例:")
    print(attn_weights[0])  # 第一个样本的注意力权重

4.3 多头注意力机制

4.3.1 为什么需要多头?

单头注意力只能学习一种注意力模式,而多头注意力:

  1. 可以学习不同的注意力模式(比如语法注意力、语义注意力)
  1. 每个头关注输入的不同部分
  1. 提升模型的表达能力
4.3.2 多头注意力的计算流程
graph TD
    A[Q, K, V] --> B[线性变换到多个子空间]
    B --> C[头1: 自注意力]
    B --> D[头2: 自注意力]
    B --> E[头n: 自注意力]
    C --> F[拼接所有头的输出]
    D --> F
    E --> F
    F --> G[最终线性变换]
    G --> H[输出]
4.3.3 多头注意力的代码实现

class MultiHeadAttention(nn.Module):
    def __init__(self, d_model, num_heads):
        super().__init__()
        assert d_model % num_heads == 0, "d_model必须能被num_heads整除"
        
        self.d_model = d_model
        self.num_heads = num_heads
        self.d_k = d_model // num_heads
        
        # 线性变换层
        self.w_q = nn.Linear(d_model, d_model)
        self.w_k = nn.Linear(d_model, d_model)
        self.w_v = nn.Linear(d_model, d_model)
        self.w_o = nn.Linear(d_model, d_model)
        
    def split_heads(self, x, batch_size):
        """
        将输入分成多个头
        x: [batch_size, seq_len, d_model]
        返回: [batch_size, num_heads, seq_len, d_k]
        """
        x = x.view(batch_size, -1, self.num_heads, self.d_k)
        return x.transpose(1, 2)  # 交换头和序列长度维度
    
    def forward(self, q, k, v, mask=None):
        batch_size = q.size(0)
        
        # 1. 线性变换
        q = self.w_q(q)  # [batch_size, seq_len, d_model]
        k = self.w_k(k)
        v = self.w_v(v)
        
        # 2. 分头
        q = self.split_heads(q, batch_size)  # [batch_size, num_heads, seq_len, d_k]
        k = self.split_heads(k, batch_size)
        v = self.split_heads(v, batch_size)
        
        # 3. 计算缩放点积注意力
        attn_output, attn_weights = scaled_dot_product_attention(q, k, v, mask)
        
        # 4. 拼接头
        attn_output = attn_output.transpose(1, 2).contiguous()  # [batch_size, seq_len, num_heads, d_k]
        attn_output = attn_output.view(batch_size, -1, self.d_model)  # [batch_size, seq_len, d_model]
        
        # 5. 最终线性变换
        output = self.w_o(attn_output)
        
        return output, attn_weights

# 测试
if __name__ == "__main__":
    # 参数设置
    batch_size = 2
    seq_len = 4
    d_model = 16
    num_heads = 4
    
    # 创建多头注意力
    mha = MultiHeadAttention(d_model, num_heads)
    
    # 随机输入
    x = torch.randn(batch_size, seq_len, d_model)
    
    # 前向传播
    output, attn_weights = mha(x, x, x)
    
    print("输入形状:", x.shape)
    print("输出形状:", output.shape)
    print("注意力权重形状:", attn_weights.shape)
    print(f"每个头的维度: {d_model // num_heads}")

4.4 注意力可视化

4.4.1 注意力权重的可视化

注意力权重可以可视化,帮助我们理解模型关注了哪些部分:


import matplotlib.pyplot as plt
import seaborn as sns

def visualize_attention(attn_weights, tokens):
    """
    可视化注意力权重
    attn_weights: [seq_len_q, seq_len_k]
    tokens: 对应的token列表
    """
    plt.figure(figsize=(10, 8))
    sns.heatmap(attn_weights, 
                annot=True, 
                fmt='.2f', 
                cmap='Blues',
                xticklabels=tokens,
                yticklabels=tokens)
    plt.xlabel('Key')
    plt.ylabel('Query')
    plt.title('Attention Weights')
    plt.show()

# 测试可视化
if __name__ == "__main__":
    # 示例:句子的注意力可视化
    tokens = ["我", "爱", "学习", "大模型"]
    seq_len = len(tokens)
    
    # 模拟注意力权重
    attn_weights = torch.randn(seq_len, seq_len)
    attn_weights = F.softmax(attn_weights, dim=-1)
    
    # 可视化
    visualize_attention(attn_weights.numpy(), tokens)
4.4.2 注意力模式分析

常见的注意力模式:

  1. 位置注意力:关注相邻位置
  1. 语法注意力:关注语法相关的词(比如主语和谓语)
  1. 语义注意力:关注语义相关的词(比如同义词、上下位词)
  1. 长距离注意力:关注远距离的依赖关系

4.5 注意力变体

4.5.1 相对位置注意力

在自注意力中加入相对位置信息,更好地捕捉顺序关系。

4.5.2 稀疏注意力

为了处理超长序列,只计算部分位置的注意力,减少计算量。

4.5.3 线性注意力

将注意力计算复杂度从 O(n^2) 降低到 O(n) ,适合超长序列。

4.6 本章总结与回顾

4.6.1 核心知识点总结
  1. 注意力机制:让模型动态关注输入的不同部分
  1. 自注意力:输入序列内部的注意力,Query=Key=Value
  1. 多头注意力:多个注意力头,学习不同的注意力模式
  1. 注意力可视化:帮助理解模型的关注模式
4.6.2 重要概念回顾

概念

解释

Query

查询向量,当前位置的表示

Key

键向量,所有位置的表示,用于匹配Query

Value

值向量,所有位置的表示,用于生成输出

缩放点积注意力

Transformer使用的注意力计算方式

多头注意力

多个注意力头,提升表达能力

注意力权重

输入各部分的重要性分数


5. 训练篇:大模型预训练与微调

5.1 数据准备

5.1.1 数据来源

大模型的训练数据来源广泛,主要包括:

  1. 公开网页数据:Common Crawl、Wikipedia、BooksCorpus
  1. 书籍数据:各种类型的书籍、文献
  1. 代码数据:GitHub、Stack Overflow
  1. 对话数据:聊天记录、问答数据
  1. 专业数据:法律、医疗、金融等领域的数据
5.1.2 数据清洗

数据质量直接影响模型效果,数据清洗的主要步骤:

  1. 去重:去除重复的文本
  1. 过滤低质量内容:去除垃圾文本、无意义内容
  1. 语言过滤:只保留目标语言的文本
  1. 格式标准化:统一编码、换行符等
  1. 敏感信息处理:去除个人信息、隐私数据
5.1.3 数据预处理
  1. 分词(Tokenization)
    • 将文本切分成token(词、子词、字符)
    • 常用分词器:BPE、WordPiece、SentencePiece
    • 示例:"我爱学习大模型" → ["我", "爱", "学习", "大", "模型"]
  1. 构建词汇表(Vocabulary)
    • 收集所有token,构建词汇表
    • 词汇表大小通常为几万个到几十万个
    • 为未知token(UNK)、填充(PAD)、开始(BOS)、结束(EOS)预留位置
  1. 编码(Encoding)
    • 将token转换为数字索引
    • 示例:["我", "爱", "学习"] → [100, 200, 300]
代码示例:使用Hugging Face进行分词

from transformers import AutoTokenizer

# 加载预训练分词器
tokenizer = AutoTokenizer.from_pretrained("bert-base-chinese")

# 分词示例
text = "我爱学习大模型"
tokens = tokenizer.tokenize(text)
print("分词结果:", tokens)  # ['我', '爱', '学', '习', '大', '模', '型']

# 编码
encoding = tokenizer.encode_plus(
    text,
    add_special_tokens=True,  # 添加CLS和SEP
    max_length=10,
    padding='max_length',
    truncation=True,
    return_tensors='pt'
)

print("输入ID:", encoding['input_ids'])
print("注意力掩码:", encoding['attention_mask'])

5.2 预训练任务

5.2.1 语言建模

预训练的核心是语言建模,即让模型学习语言的规律。

  1. 因果语言建模(CLM)
    • 目标:根据前文预测下一个token
    • 方式:只使用前文的信息(单向)
    • 代表模型:GPT系列
    • 适合生成任务
  1. 掩码语言建模(MLM)
    • 目标:预测被掩码的token
    • 方式:使用上下文信息(双向)
    • 代表模型:BERT
    • 适合理解任务
5.2.2 预训练流程
graph TD
    A[原始文本] --> B[数据清洗]
    B --> C[分词]
    C --> D[构建训练样本]
    D --> E[预训练任务]
    E --> F[计算损失]
    F --> G[反向传播]
    G --> H[更新参数]
    H --> E
5.2.3 预训练的挑战
  1. 计算资源:需要大量GPU/TPU
  1. 内存限制:长序列需要大量内存
  1. 训练稳定性:深层模型容易不稳定
  1. 收敛速度:大模型训练时间长

5.3 微调技术

5.3.1 什么是微调?

微调(Fine-tuning)是指在预训练模型的基础上,使用下游任务的数据继续训练,让模型适应特定任务。

5.3.2 全量微调

全量微调(Full Fine-tuning)是更新模型的所有参数:


import torch
import torch.nn as nn
from transformers import AutoModelForSequenceClassification, AutoTokenizer, AdamW

# 加载预训练模型和分词器
model_name = "bert-base-chinese"
model = AutoModelForSequenceClassification.from_pretrained(model_name, num_labels=2)
tokenizer = AutoTokenizer.from_pretrained(model_name)

# 示例数据
texts = ["这是一篇正面的评论", "这是一篇负面的评论"]
labels = torch.tensor([1, 0])

# 编码
encodings = tokenizer(texts, return_tensors='pt', padding=True, truncation=True)

# 优化器
optimizer = AdamW(model.parameters(), lr=5e-5)

# 训练
model.train()
for epoch in range(3):
    # 前向传播
    outputs = model(**encodings, labels=labels)
    loss = outputs.loss
    
    # 反向传播
    optimizer.zero_grad()
    loss.backward()
    optimizer.step()
    
    print(f"Epoch {epoch+1}, Loss: {loss.item():.4f}")

# 保存微调后的模型
model.save_pretrained("fine-tuned-bert")
tokenizer.save_pretrained("fine-tuned-bert")
5.3.3 参数高效微调(PEFT)

全量微调需要大量计算资源,参数高效微调只更新部分参数:

  1. LoRA(Low-Rank Adaptation)
    • 在注意力层插入低秩矩阵
    • 只训练低秩矩阵,冻结其他参数
    • 参数量只有全量微调的1%左右
  1. QLoRA
    • 量化版本的LoRA
    • 将模型量化到4位,进一步降低显存占用
  1. Adapter
    • 在Transformer层中插入小型网络
    • 只训练Adapter,冻结主模型
代码示例:使用LoRA进行微调

from peft import LoraConfig, get_peft_model
from transformers import AutoModelForCausalLM, AutoTokenizer, TrainingArguments, Trainer

# 加载模型和分词器
model_name = "baichuan-7B"
model = AutoModelForCausalLM.from_pretrained(model_name)
tokenizer =

(注:文档部分内容可能由 AI 生成)

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐