阶段:S7-问题排查 | 预计耗时:60 分钟 | 前置:S7-01 不收敛排查清单 代码:本篇代码要你自己敲成
model-learn/s7_error_zoo.py——一个脚本依次触发 4 种经典报错
学习目标
- 掌握读 traceback 的固定三步:最后一行(病名)→ 往上找第一处你自己的文件(案发点)→ 看该行数字/形状
- 亲手触发 4 种高频报错,把"病名→病因→解法"写成自己的手册
- 会诊断
loss=nan(LLM 训练最常见的幽灵)
核心知识
报错速查表(本篇要全部亲手触发一遍)
| # | 报错关键词 | 病因 | 解法 |
|---|---|---|---|
| 1 | mat1 and mat2 shapes cannot be multiplied |
输入形状和 Linear 的 in_features 不符(忘 Flatten / 通道维丢了) | 逐层追 shape(S3-01 的技能) |
| 2 | object too deep ... long / CE 相关 dtype 报错 |
CrossEntropyLoss 要 long 标签,喂了 float | y.long();回归才用 float |
| 3 | loss = nan(不报错但废了) | lr 太大 / 数据里有 NaN / log(0) | 减 lr;torch.isnan(x).any() 排查 |
| 4 | size mismatch for ... / Missing key(s) |
load_state_dict 时结构对不上 | 先建同结构模型(S3-03 破坏实验见过) |
读 traceback 的三步法(背下来)
- 最后一行:异常类型 + 一句话——"病名"
- 从下往上找第一个属于你文件的行号——"案发点"(库内部的几十层调用不用管)
- 看案发行里的具体数字——"证据"(往往就是两个 shape 对不上)
本机补充:内存类报错
- CPU 训练一般不会
CUDA out of memory(面试常问,答:减 batch / 减序列长度 / 梯度累积) - 本机可能的
MemoryError/卡死:后台大程序占内存——任务管理器先看一眼
实验任务
任务 1:写"报错动物园"脚本(30 分钟)
# s7_error_zoo.py —— 4 种报错,逐个 try/except 捕获并打印前 120 字符
import torch, torch.nn as nn
model = nn.Sequential(nn.Flatten(), nn.Linear(784, 128), nn.ReLU(), nn.Linear(128, 10))
# 1) 形状不匹配:忘 Flatten 的效果——直接喂 4 维输入给 Linear
# 2) dtype 错误:nn.CrossEntropyLoss()(out, torch.rand(64)) ← float 标签
# 3) nan 现场:w 初始化放大 + lr=100,跑 5 步打印 loss
# 4) 加载错配:model.load_state_dict(torch.load("mnist_cnn.pt")) ← 结构不同
每个触发点打印:病名一句话 + 案发点在哪个调用 + 你的诊断。
任务 2:nan 三连查(15 分钟)
制造 nan 后按顺序查:torch.isnan(输入).any() → 减 lr 重跑 → 检查是不是 log/sqrt 吃到了 0 或负数。三步写成注释留在脚本里。
任务 3:格式化你的手册(15 分钟)
把 4 个触发点的信息整理成你自己的表(病名/一句话诊断/解法),放进本阶段文件夹的笔记——以后报错先查自己的手册再问我。
验收标准
衔接下一阶段
会诊病会修 bug → 毕业层:S8-01 CIFAR-10 完整项目,把全部技能串成一个真项目。