从梯度到大模型(005):彻底理解 PyTorch Tensor、dtype、device 与 shape
课程:《从梯度到大模型:LLM 系统实践课》
建议用时:90~120 分钟
环境:Python 3、NumPy、PyTorch;本课默认 CPU
前置课程:Lesson 004——数值梯度检查
一、上节作业答案与讲解
作业 1:一个参数的中心差分
L(w)=(w-3)²,w=1,epsilon=0.1:
L(1.1)=(1.1-3)²=3.61
L(0.9)=(0.9-3)²=4.41
数值梯度=(3.61-4.41)/0.2=-4
解析梯度=2×(1-3)=-4
两条路线一致。梯度为负意味着附近适当增大 w 可以降低 Loss,不表示任意大的更新都有效。
作业 2:两个参数的检查
x=[1,2,3],y=[3,5,7],w=1,b=0:
预测=[1,2,3]
误差=[-2,-3,-4]
dw=[2×(-2)×1+2×(-3)×2+2×(-4)×3]/3
=(-4-12-24)/3=-13.3333333
db=(-4-6-8)/3=-6
检查 db 时,保持 w 不变:
db_numeric = (
loss(w, b + epsilon) - loss(w, b - epsilon)
) / (2 * epsilon)
作业 3:分母错误
中心差分的取样点距离是 2*epsilon。若仅除以 epsilon,结果会变成正确中心差分的两倍,不能与解析梯度匹配。
作业 4:步长实验
固定 w=1、b=0,本机 NumPy float64 的实测结果如下。不同设备可能出现末位差异。
| epsilon | 数值 dw | 数值 db | dw 绝对误差 | db 绝对误差 | 结果 |
|---|---|---|---|---|---|
| 1e-3 | -13.33333333 | -6.00000000 | 约 1.47e-12 | 约 6.61e-13 | PASS |
| 1e-5 | -13.33333333 | -6.00000000 | 约 1.47e-12 | 约 4.95e-11 | PASS |
| 1e-9 | -13.33333444 | -6.00000050 | 约 1.10e-6 | 约 4.96e-7 | PASS |
| 1e-15 | -14.21085472 | -5.32907052 | 约 0.878 | 约 0.671 | FAIL |
判断采用 rtol=1e-5、atol=1e-7。极小 epsilon 使两个 Loss 太接近,相减时浮点误差被放大。本课二次函数在精确算术下的中心差分没有截断误差,不代表一般函数也如此。
作业 5:检查故意错误
用两个非最优点比较:
| 检查位置 | 正确 dw | 正确 db | dw 漏乘 x | 两个梯度漏乘 2 | 反转误差符号 |
|---|---|---|---|---|---|
| w=0,b=0 | -22.6667 | -10 | dw=-10,失败 | 各变成一半,失败 | 各变成正数,失败 |
| w=1,b=0 | -13.3333 | -6 | dw=-6,失败 | 各变成一半,失败 | 各变成正数,失败 |
漏乘 x 只破坏 dw;若 db 仍写正确,它应通过。漏乘 2 指 dw、db 的公式都遗漏系数 2。最优点的零梯度可能掩盖上述错误,因此不能只检查最优点。
二、本课的实际问题:把任务数据变成模型能处理的对象
假设你希望估算软件任务工时,每个任务记录三个数值特征:
- 代码规模:例如按百行计的规模,需在真实项目中明确单位。
- 接口数量。
- 测试场景数量。
两条模拟数据:
任务 A:[2,1,3]
任务 B:[4,2,5]
它们不是可靠的真实工时数据,只用于演示。
前几课使用 NumPy 组织数据和计算。进入深度学习框架后,我们需要一种能被框架统一处理的数据对象:Tensor。
本课先解决“数据如何表示和运算”,不急着训练。自动求导放在第 6 课。
三、Tensor 是什么
Tensor 通常译为“张量”。在本课程中,可先把它理解为具有形状、数据类型和计算设备的多维数值容器。
import torch
x = torch.tensor([[2., 1., 3.], [4., 2., 5.]])
print(x)
不要因为“张量”这个词就觉得需要重新学一套完全不同的数组数学。你已经学过的 shape、广播、逐元素计算和矩阵乘法仍然重要。
同时,Tensor 不只是 NumPy 数组的别名。它属于 PyTorch 计算体系,可以参与设备运算与自动求导。
四、先认识三个属性
print(x.shape)
print(x.dtype)
print(x.device)
一般会看到:
torch.Size([2, 3])
torch.float32
cpu
- shape:数据结构。
- dtype:元素类型。
- device:数据在哪个计算设备上。
业务含义仍需自己约定:这里第一维是任务数,第二维是每个任务的特征数。
五、创建 Tensor 的几种方式
1. 从 Python 数据创建
x = torch.tensor([1., 2., 3.], dtype=torch.float32)
ids = torch.tensor([1, 2, 3], dtype=torch.int64)
显式 dtype 能减少推断带来的意外。
2. 创建固定值
zeros = torch.zeros((2, 3), dtype=torch.float32)
ones = torch.ones((2, 3), dtype=torch.float32)
3. 创建随机值
torch.manual_seed(42)
random_values = torch.rand((2, 3))
设随机种子便于实验,但不能承诺跨设备、跨版本所有运算都完全一致。
4. 继承已有 Tensor 的属性
same_shape = torch.zeros_like(x)
它便于创建与 x 同形状、同类型、同设备的零 Tensor,减少手动填写错误。
六、dtype:为什么数字类型重要
常用类型:
| dtype | 典型用途 |
|---|---|
| float32 | 常见模型输入和参数 |
| float64 | 高精度的小实验、梯度检查 |
| int64 | 类别索引、Token ID |
| bool | 条件判断、部分掩码 |
不要把这个表当作所有模型的固定规则。具体任务的 API 决定输入要求。
整数不是小数
a = torch.tensor([1, 2, 3])
b = torch.tensor([1., 2., 3.])
print(a.dtype)
print(b.dtype)
通常分别是 int64 和 float32。默认浮点类型可以被设置改变,因此严谨示例最好显式指定。
转换类型需要接收结果
a_float = a.to(dtype=

:彻底理解 PyTorch Tensor、dtype、device 与 shape&spm=1001.2101.3001.5002&articleId=165890679&d=1&t=3&u=03f1eed99c8543e3b7d61cbf93ba1dbb)
427

被折叠的 条评论
为什么被折叠?



