PyTorch:张量与自动求导入门
本文面向 PyTorch 新手扫盲:从标量、向量、矩阵讲到张量,再到自动求导的基本原理,帮助刚接触 LLM/深度学习的读者建立最基础的概念地图。
目录
| 章节 | 说明 |
|---|---|
| 是什么 | PyTorch 的定位与核心特性 |
| 核心概念 | 标量、向量、矩阵、张量与自动求导 |
| 快速上手 | 安装、创建张量、基础运算 |
| 常见场景 | 一个能跑通的最小示例 |
| 对比与选型 | PyTorch 与 NumPy、TensorFlow 的区别 |
是什么
PyTorch 是一个开源的深度学习框架,最核心的能力是两件事:
- 张量计算:提供类似 NumPy 的多维数组运算,并且可以无缝跑在 GPU 上加速。
- 自动求导(Autograd):自动记录计算过程,反向传播时自动算出梯度,不需要手写求导公式。
训练一个神经网络(包括 LLM)本质上就是:不断做张量运算 → 自动求出梯度 → 用梯度更新参数,这三步循环。PyTorch 把这三步都做成了简单的 API。
一句话定位:PyTorch 是"会自动求导的 NumPy + 一套搭建神经网络的工具箱",适合研究和训练深度学习模型;不太适合追求前端推理极致轻量部署的场景(那通常会导出为 ONNX 等格式再部署)。
核心概念
标量、向量、矩阵、张量
这四个词描述的是同一件事——"数据装在几维数组里"——只是维度不同:
| 名称 | 维度 | 通俗理解 | 示例 |
|---|---|---|---|
| 标量(Scalar) | 0 维 | 一个数字 | 5 |
| 向量(Vector) | 1 维 | 一排数字 | [1, 2, 3] |
| 矩阵(Matrix) | 2 维 | 一张表格 | [[1, 2], [3, 4]] |
| 张量(Tensor) | N 维(N ≥ 0) | 上面所有情况的统称 | 常见形状如一批彩色图片:[批次, 通道, 高, 宽](4 维,即 NCHW) |
张量是 PyTorch 中最核心的数据结构:标量、向量、矩阵都只是张量在维度为 0、1、2 时的特例。在 PyTorch 代码里,不管是一个数字还是一批图片,都用同一个类型表示:torch.Tensor(Dataset、DataLoader、nn.Parameter 等是在张量基础上搭建的更高层工具,本文暂不展开)。
在 LLM 场景中最常见的张量形状是 [batch_size, seq_len, hidden_dim](批次数 × 序列长度 × 隐藏层维度),本质也只是一个 3 维张量。
张量的核心属性
每个张量除了存数据本身,还带着四个关键属性:
| 属性 | 含义 | 常见取值 |
|---|---|---|
shape | 每个维度的大小 | 如 torch.Size([2, 3]) 表示 2 行 3 列 |
dtype | 元素的数据类型 | torch.float32(浮点默认类型)、torch.float16、torch.int64 等;用整数列表创建的张量会自动推断为 torch.int64 |
device | 数据存放的设备 | cpu 或 cuda:0(第一块 GPU) |
requires_grad | 是否需要跟踪梯度 | True(需要训练的参数)/ False(普通数据) |
⚠️ 常见误区:两个张量做运算时,
device通常必须一致,否则会直接报错(比如一个张量在 CPU、另一个在 GPU 上);dtype不一致时有些运算会自动类型提升(如 int 和 float 相加),但矩阵乘法等运算通常要求dtype一致。这些都是 PyTorch 新手最容易踩的坑。另外,
requires_grad=True只能用在浮点或复数张量上,整数张量(如torch.tensor([1, 2, 3]))不能设置。
自动求导(Autograd)
深度学习训练的核心是"根据误差反过来调整参数",这一步依赖求导(梯度)。PyTorch 用 Autograd 机制自动完成这件事,不需要手推数学公式:
构建张量(requires_grad=True)
↓
做一系列运算(PyTorch 在背后偷偷记录计算图)
↓
调用 .backward()(沿着计算图反向传播)
↓
在叶子张量的 .grad 属性里拿到梯度
关键心智模型:在默认梯度模式下,只要某个浮点/复数张量的 requires_grad=True,PyTorch 就会把它参与的可导运算记在一张隐藏的"计算图"里(torch.no_grad() 内部或调用了 .detach() 的部分除外);调用 .backward() 时,PyTorch 沿着这张图反向走一遍,用链式法则自动算出每个叶子张量(用户直接创建、requires_grad=True 的张量,比如下面例子里的 x)的梯度。
快速上手
安装
# CPU 版本(先跑通概念,不追求速度可以先用这个)
pip install torch
# 如果有 NVIDIA GPU,去 PyTorch 官网按 CUDA 版本选择对应命令安装
# https://pytorch.org/get-started/locally/
创建张量
import torch
a = torch.tensor(5) # 标量,0 维
b = torch.tensor([1, 2, 3]) # 向量,1 维
c = torch.tensor([[1, 2], [3, 4]]) # 矩阵,2 维
print(a.shape) # torch.Size([])
print(b.shape) # torch.Size([3])
print(c.shape) # torch.Size([2, 2])
zeros = torch.zeros(2, 3) # 全 0 张量,形状 (2, 3)
rand = torch.rand(2, 3) # [0, 1) 区间的随机张量
基础运算
x = torch.tensor([1.0, 2.0, 3.0])
y = torch.tensor([4.0, 5.0, 6.0])
print(x + y) # 逐元素相加:tensor([5., 7., 9.])
print(x * y) # 逐元素相乘:tensor([4., 10., 18.])
print(x @ y) # 向量点积:tensor(32.)
m = torch.rand(2, 3)
n = torch.rand(3, 4)
print(m @ n) # 矩阵乘法,结果形状 (2, 4)
GPU 加速
device = "cuda" if torch.cuda.is_available() else "cpu"
x = torch.tensor([1.0, 2.0, 3.0]).to(device) # 搬到可用设备:有 GPU 用 GPU,没有就留在 CPU
常见场景
一个能跑通的最小示例:用 Autograd 求梯度
用一个最简单的表达式 y = x^2,让 PyTorch 自动算出 dy/dx:
import torch
x = torch.tensor(3.0, requires_grad=True) # 声明需要跟踪梯度
y = x ** 2
y.backward() # 反向传播,触发自动求导
print(x.grad) # tensor(6.) —— dy/dx = 2x,代入 x=3 得 6
这三行(构建带梯度的张量 → 做运算 → .backward())就是训练任何神经网络(包括 LLM)时,参数更新前必经的核心步骤。
⚠️ 两个新手常踩的坑:
.backward()默认要求结果是标量,如果是向量通常要先.sum()/.mean()再调用;.grad默认会累积,训练循环里每轮通常要先optimizer.zero_grad()清零,否则梯度会越加越多。
对比与选型
| 维度 | NumPy | PyTorch | TensorFlow |
|---|---|---|---|
| 核心数据结构 | ndarray | Tensor | Tensor |
| 自动求导 | ❌ 不支持 | ✅ 内置 Autograd | ✅ 内置 |
| GPU 加速 | ❌ 原生不支持(需 CuPy 等) | ✅ 原生支持 | ✅ 原生支持 |
| 上手难度 | 低 | 低~中 | 中 |
| 主要用途 | 通用科学计算 | 深度学习研究、训练 | 深度学习训练与工业部署 |
一句话选型:只做数值计算用 NumPy;要训练神经网络(含 LLM 相关的微调、实验)优先选 PyTorch,社区和论文实现覆盖率最高;追求端到端工业级部署链路可以考虑 TensorFlow / TFLite。
参考资料
评论 (0)