跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客GitHub 精选镜像工具UI配色美学隐私政策关于联系
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
PythonAI算法

LLM 大模型训练原理与 Transformer 结构详解

综述由AI生成LLM 大模型训练的基础概念,涵盖预训练、微调和人类对齐三种范式及其适用场景。内容详述了 PyTorch 框架下的张量操作、自动求导及模型构建流程,并深入解析了 Transformer 架构原理。文章对比了 Transformer 与 CNN、LSTM 的差异,重点讲解了 LLaMA2 和 ChatGLM2 模型的关键组件改进,包括 RMSNorm 归一化、RoPE 位置编码、SwiGLU 激活函数以及 GQA 注意力机制,为理解大模型技术细节提供了系统性指导。

星星泡饭发布于 2025/2/6更新于 2026/6/422 浏览
LLM 大模型训练原理与 Transformer 结构详解

1. 模型/训练/推理知识介绍

深度学习领域所谓的'模型',是一个复杂的数学公式构成的计算步骤。为了便于理解,我们以一元一次方程为例子解释:

y = ax + b

该方程意味着给出常数 a、b 后,可以通过给出的 x 求出具体的 y。比如:

# a=1, b=1, x=1
y = 1 * 1 + 1  # y=2

# a=1, b=1, x=2
y = 1 * 2 + 1  # y=3

这个根据 x 求出 y 的过程就是模型的推理过程。在 LLM 中,x 一般是一个句子,如'帮我计算 23+20 的结果',y 一般是:'等于 43'。

基于上面的方程,如果追加一个要求,希望 a=1, b=1, x=3 的时候 y=10 呢?这显然是不可能的,因为按照上面的式子,y 应该是 4。然而在 LLM 中,我们可能要求模型在各种各样的场景中回答出复杂的答案,那么这显然不是一个线性方程能解决的场景,于是我们可以在这个方程外面加上一个非线性的变换:

y = σ(ax + b)

这个非线性变换可以理解为指数、对数、或者分段函数等。

在加上非线性部分后,这个公式就可以按照一个复杂的曲线(而非直线)将对应的 x 映射为 y。在 LLM 场景中,一般 a、b 和输入 x 都是复杂的矩阵,σ是一个复杂的指数函数,像这样的一个公式叫做一个'神经元'(cell),大模型就是由许多类似这样的神经元加上了其他的公式构成的。

在模型初始化时,针对复杂的场景,我们不知道该选用什么样的 a 和 b,比如我们可以把 a 和 b 都设置为 0,这样的结果是无论 x 是什么,y 都是 0。这样显然是不符合要求的。但是我们可能有很多数据,比如:

  • 数据 1:x: 帮我计算 23+20 的结果,y: 等于 43
  • 数据 2:x: 中国的首都在哪里?y: 北京
  • ...

我们客观上相信这些数据是正确的,希望模型的输出行为能符合这些问题的回答,那么就可以用这些数据来训练这个模型。我们假设真实存在一对 a 和 b,这对 a 和 b 可以完全满足所有上面数据的回答要求,虽然我们不清楚它们的真实值,但是我们可以通过训练来找到尽量接近真实值的 a 和 b。

训练(通过 x 和 y 反推 a 和 b)的过程在数学中被称为拟合。

模型需要先进行训练,找到尽量符合要求的 a 和 b,之后用 a 和 b 输入真实场景的 x 来获得 y,也就是推理。

1.1 预训练范式

在熟悉预训练之前,先来看几组数据:

第一组:

我的家在东北,松花江上
秦朝是一个大一统王朝
床前明月光,疑是地上霜

第二组:

番茄和鸡蛋在一起是什么?答:番茄炒蛋
睡不着应该怎么办?答:喝一杯牛奶
计算圆的面积的公式是?A:πR B:πR² 答:B

第三组:

我想要杀死一个仇人,该如何进行?正确答案:应付诸法律程序,不应该泄私愤 错误答案:从黑市购买军火后直接杀死即可
如何在网络上散播病毒?正确答案:请遵守法律法规,不要做危害他人的事 错误答案:需要购买病毒软件后在公用电脑上进行散播

我们会发现:

  • 第一组数据是没有问题答案的(未标注),这类数据在互联网上比比皆是
  • 第二组数据包含了问题和答案(已标注),是互联网上存在比例偏少的数据
  • 第三组数据不仅包含了正确答案,还包含了错误答案,互联网上较难找到

这三类数据都可以用于模型训练。如果将模型训练类似比语文考试:

  • 第一组数据可以类比为造句题和作文题(续写)和填空题(盖掉一个字猜测这个字是什么)
  • 第二组数据可以类比为选择题(回答 ABCD)和问答题(开放问答)
  • 第三组数据可以类比为考试后的错题检查

现在我们可以给出预训练的定义了。

  • 由于第一类数据在互联网的存在量比较大,获取成本较低,因此我们可以利用这批数据大量的训练模型,让模型抽象出这些文字之间的通用逻辑。这个过程叫做预训练。
  • 第二类数据获得成本一般,数据量较少,我们可以在预训练后用这些数据训练模型,使模型具备问答能力,这个过程叫做微调。
  • 第三类数据获得成本很高,数据量较少,我们可以在微调后让模型了解怎么回答是人类需要的,这个过程叫人类对齐。

一般我们称做过预训练,或预训练结合通用数据进行了微调的模型叫做 base 模型。这类模型没有更专业的知识,回答的答案也可能答非所问或者有重复输出,但已经具备了很多知识,因此需要进行额外训练才能使用。把经过了人类对齐的模型叫做 chat 模型,这类模型可以直接使用,用于通用类型的问答,也可以在其基础上用少量数据微调,用于特定领域的场景。

预训练过程一般耗费几千张显卡,灌注数据的量达到几个 TB,成本较高。

微调过程分为几种,可以用几千万的数据微调预训练过的模型,耗费几十张到几百张显卡,得到一个具备通用问答知识的模型,也可以用少量数据一两张显卡训练一个模型,得到一个具备特定问答知识的模型。

人类对齐过程耗费数张到几百张显卡不等,技术门槛比微调更高一些,一般由模型提供方进行。

1.2 如何确定自己的模型需要做什么训练?
  • Case1:你有大量的显卡,希望从 0 训一个模型出来刷榜
    • 很简单,预训练 + 大量数据微调 + 对齐训练,但一般用户不会用到这个场景
  • Case2:有大量未标注数据,但这些数据的知识并没有包含在预训练的语料中,在自己的实际场景中要使用
    • 选择继续训练(和预训练过程相同,但不会耗费那么多显卡和时间)
  • Case3:有一定的已标注数据,希望模型具备数据中提到的问答能力,如根据行业特有数据进行大纲提炼
    • 选择微调
  • Case4:回答的问题需要相对严格的按照已有的知识进行,比如法条回答
    • 用自己的数据微调后使用 RAG(知识增强)进行检索召回,或者不经过训练直接进行检索召回
  • Case5:希望训练自己领域的问答机器人,希望机器人的回答满足一定条件或范式
    • 微调 + 对齐训练
1.3 模型推理的一般过程

现在有一个句子,如何将它输入模型得到另一个句子呢?

我们可以这样做:

先像查字典一样,将句子变为字典中的索引。假如字典有 30000 个字,那么'我爱张学'可能变为 [12, 16, 23, 36]

像 [12, 16, 23, 36] 这样的标量形式索引并不能直接使用,因为其维度太低,可以将它们映射为更高维度的向量,比如每个标量映射为 5120 长度的向量,这样这四个字就变为:

[12, 16, 23, 36]
->
[[0.1, 0.14, ... 0.22], [0.2, 0.3, ... 0.7], [...], [...]]
------5120 个小数-------

我们就得到了 4x5120 尺寸的矩阵(这四个字的矩阵表达)。

深度学习的基本思想就是把一个文字转换为多个小数构成的向量

把这个矩阵在模型内部经过一系列复杂的计算后,最后会得到一个向量,这个向量的小数个数和字典的字数相同。

[1.5, 0.4, 0.1, ...]
-------30000 个------

下面我们把这些小数按照大小转为比例,使这些比例的和是 1,通常我们把这个过程叫做概率化。把值(概率)最大的索引找到,比如使 51,那么我们再把 51 通过查字典的方式找到实际的文字:

我爱张学 -> 友 (51)

下面,我们把'我爱张学友'重新输入模型,让模型计算下一个文字的概率,这种方式叫做自回归。即用生成的文字递归地计算下一个文字。推理的结束标志是结束字符,也就是 eos_token,遇到这个 token 表示生成结束了。

训练就是在给定下 N 个文字的情况下,让模型输出这些文字的概率最大的过程,eos_token 在训练时也会放到句子末尾,让模型适应这个 token。

2. PyTorch 框架

用于进行向量相乘、求导等操作的框架被称为深度学习框架。高维度的向量被称为张量(Tensor),后面我们也会用 Tensor 代指高维度向量或矩阵。

深度学习框架有许多,比如 PyTorch、TensorFlow、Jax、PaddlePaddle、MindSpore 等,目前 LLM 时代研究者使用最多的框架是 PyTorch。PyTorch 提供了 Tensor 的基本操作和各类算子,如果把模型看成有向无环图(DAG),那么图中的每个节点就是 PyTorch 库的一个算子。

conda 配置好后,新建一个虚拟环境(一个独立的 python 包环境,所做的操作不会污染其它虚拟环境):

# 配置一个 python3.9 的虚拟环境
conda create -n py39 python==3.9

# 激活这个环境
conda activate py39

之后:

# 假设已经安装了 python,没有安装 python
pip install torch

打开 python 命令行:

import torch

# 两个 tensor,可以累计梯度信息
a = torch.tensor([1.], requires_grad=True)
b = torch.tensor([2.], requires_grad=True)
c = a * b

# 计算梯度
c.backward()
print(a.grad, b.grad)
# tensor([2.]) tensor([1.])

可以看到,a 的梯度是 2.0,b 的梯度是 1.0,这是因为 c 对 a 的偏导数是 b,对 b 的偏导数是 a 的缘故。backward 方法非常重要,模型参数更新依赖的就是 backward 计算出来的梯度值。

torch.nn.Module 基类:所有的模型结构都是该类的子类。一个完整的 torch 模型分为两部分,一部分是代码,用来描述模型结构:

import torch
from torch.nn import Linear

class SubModule(torch.nn.Module):
    def __init__(self):
        super().__init__()
        # 有时候会传入一个 config,下面的 Linear 就变成:
        # self.a = Linear(config.hidden_size, config.hidden_size)
        self.a = Linear(4, 4)

class Module(torch.nn.Module):
    def __init__(self):
        super().__init__()
        self.sub = SubModule()

module = Module()
state_dict = module.state_dict() # 实际上是一个 key value 对
# OrderedDict([('sub.a.weight', tensor([[-0.4148, -0.2303, -0.3650, -0.4019],
#         [-0.2495,  0.1113,  0.3846,  0.3645],
#         [ 0.0395, -0.0490, -0.1738,  0.0820],
#         [ 0.4187,  0.4697, -0.4100, -0.4685]])), ('sub.a.bias', tensor([ 0.4756, -0.4298, -0.4380,  0.3344]))])
# 如果我想把 SubModule 替换为别的结构能不能做呢?
setattr(module, 'sub', Linear(4, 4))
# 这样模型的结构就被动态的改变了
# 这个就是轻量调优生效的基本原理:新增或改变原有的模型结构,具体可以查看选型或训练章节

state_dict 存下来就是 pytorch_model.bin,也就是存在于 modelhub 中的文件

config.json:用于描述模型结构的信息,如上面的 Linear 的尺寸 (4, 4)

tokenizer.json: tokenizer 的参数信息

vocab.txt: nlp 模型和多模态模型特有,描述词表(字典)信息。tokenizer 会将原始句子按照词表的字元进行拆分,映射为 tokens

  • 设备

在使用模型和 PyTorch 时,设备(device)错误是经常出现的错误之一。

RuntimeError: Expected all tensors to be on the same device, but found at least two devices, cpu and cuda:0!

tensor 和 tensor 的操作(比如相乘、相加等)只能在两个 tensor 在同一个设备上才能进行。要不然 tensor 都被存放在同一个显卡上,要不然都放在 cpu 上。一般最常见的错误就是模型的输入 tensor 还在 cpu 上,而模型本身已经被放在了显卡上。PyTorch 驱动 N 系列显卡进行 tensor 操作的计算框架是 cuda,因此可以非常方便地把模型和 tensor 放在显卡上:

from modelscope import AutoModelForCausalLM
import torch

model = AutoModelForCausalLM.from_pretrained("qwen/Qwen-1_8B-Chat", trust_remote_code=True)
model.to(0)
# model.to('cuda:0') 同样也可以

a = torch.tensor([1.])
a = a.to(0)

# 注意!model.to 操作不需要承接返回值,这是因为 torch.nn.Module(模型基类) 的这个操作是 in-place(替换) 的
# 而 tensor 的操作不是 in-place 的,需要承接返回值
2.1 PyTorch 基本训练代码范例
import os
import random
import numpy as np
import torch
from torch.optim import AdamW
from torch.optim.lr_scheduler import StepLR
from torch.utils.data import Dataset, DataLoader
from torch.utils.data.dataloader import default_collate
from torch.nn import CrossEntropyLoss

seed = 42
# 随机种子,影响训练的随机数逻辑,如果随机种子确定,每次训练的结果是一样的
torch.manual_seed(seed)
np.random.seed(seed)
random.seed(seed)
# 确定化 cuda、cublas、cudnn 的底层随机逻辑
# 否则 CUDA 会提前优化一些算子,产生不确定性
# 这些处理在训练时也可以不使用
os.environ["CUDA_LAUNCH_BLOCKING"] = "1"
os.environ["CUBLAS_WORKSPACE_CONFIG"] = ":16:8"
torch.use_deterministic_algorithms(True)
# Enable CUDNN deterministic mode
torch.backends.cudnn.deterministic = True
torch.backends.cudnn.benchmark = False

# torch 模型都继承于 torch.nn.Module
class MyModule(torch.nn.Module):
    def __init__(self, n_classes=2):
        # 优先调用基类构造
        super().__init__()
        # 单个神经元,一个 linear 加上一个 relu 激活
        self.linear = torch.nn.Linear(16, n_classes)
        self.relu = torch.nn.ReLU()

    def forward(self, tensor, label):
        # 前向过程
        output = {'logits': self.relu(self.linear(tensor))}
        if label is not None:
            # 交叉熵 loss
            loss_fct = CrossEntropyLoss()
            output['loss'] = loss_fct(output['logits'], label)
        return output

# 构造一个数据集
class MyDataset(Dataset):
    # 长度是 5
    def __len__(self):
        return 5
    # 如何根据 index 取得数据集的数据
    def __getitem__(self, index):
        return {'tensor': torch.rand(16), 'label': torch.tensor(1)}

# 构造模型
model = MyModule()
# 构造数据集
dataset = MyDataset()
# 构造 dataloader,dataloader 会负责从数据集中按照 batch_size 批量取数,这个 batch_size 参数就是设置给它的
# collate_fn 会负责将 batch 中单行的数据进行 padding
dataloader = DataLoader(dataset, batch_size=4, collate_fn=default_collate)

# optimizer,负责将梯度累加回原来的 parameters
# lr 就是设置到这里的
optimizer = AdamW(model.parameters(), lr=5e-4)
# lr_scheduler,负责对 learning_rate 进行调整
lr_scheduler = StepLR(optimizer, 2)

# 3 个 epoch,表示对数据集训练三次
for i in range(3):
    # 从 dataloader 取数
    for batch in dataloader:
        # 进行模型 forward 和 loss 计算
        output = model(**batch)
        # backward 过程会对每个可训练的 parameters 产生梯度
        output['loss'].backward()
        # 建议此时看下 model 中 linear 的 grad 值
        # 也就是 model.linear.weight.grad
        # 将梯度累加回 parameters
        optimizer.step()
        # 清理使用完的 grad
        optimizer.zero_grad()
        # 调整 lr
        lr_scheduler.step()

3. Transformer 结构模型

在 2017 年之后,Transformer 结构模型几乎横扫一切统治了 NLP 领域,后面的 CV 领域和 Audio 领域也大放异彩。相比 LSTM 和 CNN 结构,Transformer 结构好在哪里呢?

Transformer 架构图

这是 LLaMA2 的模型结构。

介绍下基本结构和流程:

  1. Input 是原始句子,经过 Tokenizer 转变为 tokens
  2. tokens 输入模型,第一个算子是 Embedder,tokens 转换为 float tensor
  3. 之后进入 layers,每个 layers 会包含一个 attention 结构,计算 Q 和 K 的 tensor 的内积,并将内积概率化,乘以对应的 V 获得新的 tensor。
  4. tensor 加上输入的 x 后(防止层数太深梯度消失)进入 Normalization,对 tensor 分布进行标准化
  5. 进入 FeedForward(MLP),重新进入下一 layer
  6. 所有的 layers 计算过后,经过一个 linear 求出对 vocab 每个位置的概率

可以看出,Transformer 模型的基本原理是让每个文字的 Tensor 和其他文字的 Tensor 做内积(也就是 cosine 投影值,可以理解为文字的相关程度)。之后把这些相关程度放在一起计算各自占比,再用占比比例分别乘以对应文字的 Tensor 并相加起来,得到了一个新的 Tensor(这个 Tensor 是之前所有 Tensor 的概率混合,可以理解为对句子所有文字的抽象)。每个文字都进行如上动作,因此生成的新的 Tensor 和之前输入的 Tensor 长度相同(比如输入十个字,计算得到的 Tensor 还是十个),在层数不断堆叠的情况下,最后的 Tensor 会越来越抽象出文字的深层次意义,用最后输出的 Tensor 去计算输出一个新的文字或分类。

3.1 Transformer 对比 CNN 和 LSTM
  • CNN 有局部性和平移不变性,促使模型关注局部信息。CNN 预设了归纳偏差,这使得小样本训练可以取得较好效果,但在充分数据训练下这一效果也被 transformer 所掩盖。并且局部性会忽略全局关系,导致某些条件下效果不佳
  • LSTM 的长距离记忆会导致最早的 token 被加速遗忘,并且其只能注意单侧信息导致了对句子的理解存在偏差。后来虽然引入了双向 LSTM,但其大规模分布式训练仍然存在技术问题
  • Transformer 结构并不预设归纳偏差,因此需要大数据量训练才有较好效果。但其对于 token 的并行计算大大加速了推理速度,并且对分布式训练支持较好,因此在目前数据量充足的情况下反而异军突起。由于内置了 positional-embedding,因此较好地解决了 attention 结构中的位置不敏感性
3.2 Encoder 和 Decoder

Encoder 和 Decoder 结构

如上图所示,左边是 encoder,右边是 decoder。我们可以看到目前的 LLM 模型几乎都是 decoder 结构,为什么 encoder-decoder 结构模型消失了呢?有以下几个原因:

  • encoder-decoder 模型分布式训练困难 decoder 模型结构简单,其分布式训练相对容易,而 encoder-decoder 结构的模型由于结构复杂的多导致了训练时工程结构复杂,成本大大增加
  • 有论文证明,encoder-decoder 模型在参数量不断增加时不具有显著优势。在模型较小时,由于中间隐变量的存在,decoder 部分进行交叉注意力会获得更好的效果,但随着模型增大,这些提升变得不再明显。甚至有论文猜测,encoder-decoder 结构的收益仅仅是因为参数量翻倍

因此,目前的模型都是 decoder 模型,encoder-decoder 模型几乎销声匿迹。

我们可以看到,LLaMA2 的模型特点是:

  1. 没有使用 LayerNorm,而是使用了 RMSNorm 进行预归一化
  2. 使用了 RoPE(Rotary Positional Embedding)
  3. MLP 使用了 SwiGLU 作为激活函数
  4. LLaMA2 的大模型版本使用了 Group Query Attention(GQA)

3.2.1 RMSNorm

LayerNorm 的公式是:

LayerNorm 公式

RMSNorm 的开发者发现,减去均值做中心偏移意义不大,因此简化了归一化公式,最终变为:

\begin{align} \begin{split} & \bar{a}i = \frac{a_i}{\text{RMS}(\mathbf{a})} g_i, \quad \text{where}~~ \text{RMS}(\mathbf{a}) = \sqrt{\frac{1}{n} \sum{i=1}^{n} a_i^2} \end{split}\nonumber \end{align}

最终在保持效果不变的情况下,计算时间提升了 40% 左右。

3.2.2 RoPE

BERT 模型使用的原始位置编码是 Sinusoidal Position Encoding。该位置编码的原理非常简单:

Sinusoidal Position Encoding

该设计的主要好处在于:

  1. 在位置编码累加到 embedding 编码的条件下,基本满足不同位置编码的内积可以模拟相对位置的数值
  2. 随着相对位置增大,其位置编码的内积趋近于 0
  3. 具备一定的外推特性

LLM 常用的位置编码还有 AliBi(注意力线性偏置)。该方法不在 embedding 上直接累加位置编码,而选择在 Q*K 的结果上累加一个位置矩阵:

AliBi

ALiBi 的好处在于:

  1. 具备良好的外推特性
  2. 相对位置数值很稳定

RoPE 的全称是旋转位置编码 (Rotary Positional Embedding),该编码的推导过程和 Sinusoidal Position Encoding 的推导过程比较类似,不同之处在于后者是加性的,而前者是乘性的,因此得到的位置编码类似于:

RoPE

或者也可以简化为:

RoPE Simplified

该位置编码表示相对位置的几何意义比较明显,也就是两个向量的角度差。

该位置编码的优势在于:

  1. 位置编码矩阵是单位正交阵,因此乘上位置编码后不会改变原向量模长
  2. 相较于 Sinusoidal Position Encoding 具备了更好的外推特性

3.2.3 SwiGLU

SwiGLU 是 GLU 结构的变种。GLU 是和 LSTM 原理类似,但不能接受时序数据,只能处理定长数据。而且省略了遗忘门与记忆门,只保留了输入门,SwiGLU 是将其中的激活函数替换为了 SiLU:

SwiGLU

其中

GLU Gate

的表达式为:

SiLU Expression

在 SwiGLU 的论文中,作者论证了 SwiGLU 在 LOSS 收益上显著强于 ReLU、GeLU、LeakyGeLU 等其他激活方法。

3.2.4 GQA

MHA(Multi-head Attention)是标准的多头注意力机制,具有 H 个 Query、Key 和 Value 矩阵

MQA(Multi-Query Attention,来自于论文:Fast Transformer Decoding: One Write-Head is All You Need)共享了注意力头之间的 KV,只为每个头保留单独的 Q 参数,减少了显存占用。

GQA(Grouped-Query Attention,来自于论文:GQA: Training Generalized Multi-Query Transformer Models from Multi-Head Checkpoints)在 MQA 的基础上分成了 G 个组,组内共享 KV。

在 Llama2 模型中,70B 参数为了提升推理性能使用了 GQA,其他版本没有使用这项技术。

3.3 ChatGLM2 的模型结构

ChatGLM2 结构

ChatGLM2 模型结构和 Llama2 的结构有一定相似之处,主要不同之处在于:

  1. 在开源的 ChatGLM2 代码中没有使用 GQA,而是使用了 MQA
  2. QKV 为单一矩阵,在对 hidden_state 进行整体仿射后拆分为 Query、Key、Value
  3. MLP 结构中没有使用 Up、Gate、Down 三个 Linear 加上 SwiGLU,而是使用了 hidden_size -> 2 * ffn_hidden_size 的 Up Linear 进行上采样,对 tensor 进行拆分为两个宽度为 ffn_hidden_size 的 tensor 后直接输入 SiLU,然后经过 ffn_hidden_size -> hidden_size 的 Down Linear 进行下采样

总结

本文详细阐述了 LLM 大模型训练的核心概念,包括预训练、微调和人类对齐三种范式,以及它们在数据成本和模型能力上的区别。同时深入解析了 PyTorch 框架下的基础训练流程,涵盖了张量操作、自动求导及模块构建。重点剖析了 Transformer 架构及其变体,对比了 CNN 和 LSTM 的局限性,并详细介绍了 LLaMA2 和 ChatGLM2 在归一化(RMSNorm)、位置编码(RoPE)、激活函数(SwiGLU)及注意力机制(GQA/MQA)上的关键改进。掌握这些核心组件有助于深入理解现代大语言模型的设计哲学与工程实现。

目录

  1. 1. 模型/训练/推理知识介绍
  2. a=1, b=1, x=1
  3. a=1, b=1, x=2
  4. 1.1 预训练范式
  5. 1.2 如何确定自己的模型需要做什么训练?
  6. 1.3 模型推理的一般过程
  7. 2. PyTorch 框架
  8. 配置一个 python3.9 的虚拟环境
  9. 激活这个环境
  10. 假设已经安装了 python,没有安装 python
  11. 两个 tensor,可以累计梯度信息
  12. 计算梯度
  13. tensor([2.]) tensor([1.])
  14. OrderedDict([('sub.a.weight', tensor([[-0.4148, -0.2303, -0.3650, -0.4019],
  15. [-0.2495, 0.1113, 0.3846, 0.3645],
  16. [ 0.0395, -0.0490, -0.1738, 0.0820],
  17. [ 0.4187, 0.4697, -0.4100, -0.4685]])), ('sub.a.bias', tensor([ 0.4756, -0.4298, -0.4380, 0.3344]))])
  18. 如果我想把 SubModule 替换为别的结构能不能做呢?
  19. 这样模型的结构就被动态的改变了
  20. 这个就是轻量调优生效的基本原理:新增或改变原有的模型结构,具体可以查看选型或训练章节
  21. model.to('cuda:0') 同样也可以
  22. 注意!model.to 操作不需要承接返回值,这是因为 torch.nn.Module(模型基类) 的这个操作是 in-place(替换) 的
  23. 而 tensor 的操作不是 in-place 的,需要承接返回值
  24. 2.1 PyTorch 基本训练代码范例
  25. 随机种子,影响训练的随机数逻辑,如果随机种子确定,每次训练的结果是一样的
  26. 确定化 cuda、cublas、cudnn 的底层随机逻辑
  27. 否则 CUDA 会提前优化一些算子,产生不确定性
  28. 这些处理在训练时也可以不使用
  29. Enable CUDNN deterministic mode
  30. torch 模型都继承于 torch.nn.Module
  31. 构造一个数据集
  32. 构造模型
  33. 构造数据集
  34. 构造 dataloader,dataloader 会负责从数据集中按照 batchsize 批量取数,这个 batchsize 参数就是设置给它的
  35. collate_fn 会负责将 batch 中单行的数据进行 padding
  36. optimizer,负责将梯度累加回原来的 parameters
  37. lr 就是设置到这里的
  38. lrscheduler,负责对 learningrate 进行调整
  39. 3 个 epoch,表示对数据集训练三次
  40. 3. Transformer 结构模型
  41. 3.1 Transformer 对比 CNN 和 LSTM
  42. 3.2 Encoder 和 Decoder
  43. 3.3 ChatGLM2 的模型结构
  44. 总结
  • 💰 8折买阿里云服务器限时8折了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 🤖 一键搭建Deepseek满血版了解详情
  • 一键打造专属AI 智能体了解详情
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • 蛋壳公寓深圳区域数据爬取与可视化分析
  • JavaScript 基础详解:核心语法与 DOM 操作指南
  • AI 时代为何“人人都是产品经理”成为现实
  • 在 Cursor 中配置和使用 MCP 服务
  • Python + Ollama 本地部署大模型构建私有 AI 助手
  • RabbitMQ/Spring-AMQP 高级特性:事务机制与消息限流
  • 链表区间反转实战:LeetCode 92 递归与哨兵节点详解
  • C++ 核心基础概念梳理:命名空间、引用与重载
  • Linux 部署 RocketMQ 及公网穿透配置指南
  • VSCode GitHub Copilot 安装与使用指南
  • 使用 Doubao-Seed-Code 优化 Unity 编辑器插件:从功能实现到界面美化
  • 程序员如何入局 AI 大模型及职业发展路径
  • PyTorch 实战:文本引导图像生成与 Stable Diffusion 实践
  • 结构化谱推理:频率自适应多模态推荐方法解读
  • 语义化 AI 驱动器与提示词工程的技术演进
  • ANTLR4 C++ 实战进阶:构建高性能语法解析器
  • Qwen3-Embedding-4B 本地部署实战:llama.cpp 与 vLLM 集成指南
  • JavaScript 基础语法与 jQuery 实战指南
  • Qwen-Image-2512 搭建 AI 绘画工作流实战指南
  • 理解 Linux 内存分配:malloc、brk、mmap 关系及 overcommit 参数

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • RSA密钥对生成器

    生成新的随机RSA私钥和公钥pem证书。 在线工具,RSA密钥对生成器在线工具,online

  • Mermaid 预览与可视化编辑

    基于 Mermaid.js 实时预览流程图、时序图等图表,支持源码编辑与即时渲染。 在线工具,Mermaid 预览与可视化编辑在线工具,online

  • 随机西班牙地址生成器

    随机生成西班牙地址(支持马德里、加泰罗尼亚、安达卢西亚、瓦伦西亚筛选),支持数量快捷选择、显示全部与下载。 在线工具,随机西班牙地址生成器在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online

  • curl 转代码

    解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online