9.6 KiB
Day 1 问答笔记(实操记录)
本文件记录第一天实际操作中遇到的、有价值的问题与结论。区别于
01_prereading/02_deep_dive(课程材料),这里是「踩坑 + 解决」的真实记录。
Q1. 没有写权限装不了包:EnvironmentNotWritableError
现象: conda install torch 报 current user does not have write permissions to /opt/anaconda3。
笔记: 系统级 base 环境(
/opt/anaconda3)通常没有写权限,不要往 base 里装包。正确做法是建自己的虚拟环境(装在用户目录,有写权限)。
Q2. 虚拟环境是什么?python -m venv .venv 在干嘛?
笔记: 虚拟环境 = 一个「隔离的小盒子」,里面有独立的 python 和 pip,装的包只属于这个项目,不污染系统、不和别的项目冲突。
python -m venv 名字→ 创建(只需一次)。.venv是惯例名(开头.会隐藏)。- 环境名可自定义,用英文/数字/
-/_,别用空格中文。
Q3. venv 和 conda 的区别?怎么激活/退出?
笔记: 两种建环境方式,激活命令不同:
方式 创建 激活 退出 venv python -m venv minimind-envsource minimind-env/bin/activatedeactivateconda conda create -n minimind python=3.10conda activate minimindconda deactivate退出命令是
deactivate(不是inactivate)。conda 新建的环境默认装到~/.conda/envs(用户目录,有写权限),所以能绕开 base 没权限的问题。
Q4. 怎么判断包装进了虚拟环境,还是误装到 home?
笔记:核心判断方法——看路径,不要凭感觉。
which python # 带 .venv/bin/ 才对;显示 /opt/anaconda3/bin 说明没激活 which pip # 同上 pip show 包名 # 看 Location 字段在不在 .venv 里关键习惯: 每次新开终端,venv 都不会自动激活,必须先
source .venv/bin/activate,看到命令行前面有(.venv)再操作。没激活就pip install,包会装到~/.local(用户级),不在虚拟环境里。
Q5. pip install requirements 报错?
笔记: 装依赖文件要加
-r和完整文件名:pip install -r requirements.txt。 不加-r时,pip 以为你要装一个名叫requirements的包,报No matching distribution。 minimind 的requirements.txt里torch/torchvision被注释掉了,要单独装 GPU 版:pip install torch torchvision --index-url https://download.pytorch.org/whl/cu121
Q6. modelscope 数据集下到哪了?怎么下对地方?
笔记:
- 默认下到缓存
~/.cache/modelscope(和 Python 环境无关,是缓存目录)。- 下载中断时,大文件会卡在
._____temp临时目录里(没下完)。- 下对地方的技巧: 用
--local_dir直接下到项目的 dataset 目录:modelscope download --dataset gongjy/minimind_dataset pretrain_t2t_mini.jsonl --local_dir ./dataset- 只想快速跑通,下 mini 版即可(
pretrain_t2t_mini+sft_t2t_mini),不用下全量(pretrain_t2t 10GB / sft_t2t 14GB)。
Q7. 项目的数据流是怎么走的?怎么「打点」调试?
预训练数据流路线图:
jsonl ({"text":...})
→ PretrainDataset.__getitem__ [dataset/lm_dataset.py:47] 文字→编码→加bos/eos→pad
→ DataLoader [train_pretrain.py:162] 拼成batch input_ids[B,L]
→ .to(device) [train_pretrain.py:28]
→ model.forward(input_ids,labels) [model_minimind.py:443]
embed → Transformer → hidden[B,L,768] → lm_head → logits[B,L,6400]
→ logits[:-1] 预测 labels[1:] → cross_entropy → loss
→ backward + optimizer.step [train_pretrain.py:37-49]
→ 日志/保存 [train_pretrain.py:51-69]
笔记:打点 = 在关键位置加 print 看数据 shape 和内容。 推荐顺序:
- 先单独验证数据(不启动训练):写个
debug_data.py,建 Dataset → 取ds[0]看单条 → 取一个 batch 看 shape。- 再在训练里打点:
__getitem__里看编码对不对(解码回去对比原文 + labels 里 -100 是不是 pad 位);batch 处看input_ids.shape;forward 后看logits.shape和loss。- 打点加
if index < 2/if step <= 2限制,避免刷屏。 labels 里-100= 该位置不计算 loss(pad 位置)。
Q8. 现代大模型的数据是怎么处理和清洗的?
笔记:分两大阶段,逻辑完全不同。
预训练数据(海量、求量和广,TB~PB 级,全自动清洗)经典流水线:
- 抽取:从网页 HTML 抽正文(trafilatura),去标签/广告。
- 语种过滤:fastText 识别语言,留目标语言。
- 质量过滤(核心):启发式规则(Gopher/C4:太短、符号比例异常、重复行多→删)+ 模型打分(拿维基当正例训分类器打分)。
- 去重(关键!):精确去重(哈希)+ 近似去重——MinHash+LSH(
datasketch库) 估 Jaccard 相似度删相似文档;SimHash(simhash库) 指纹+汉明距离。⚠️ 这两个库就在 minimind 的 requirements.txt 里。去重防止模型死记重复内容、浪费算力。- 去隐私(PII)/有害内容:去邮箱手机号、过滤色情暴力。
- 去污染(Decontamination):把评测题(MMLU/CEval)从训练集删掉,否则评分虚高=作弊。
- 格式统一:→
{"text": "干净文字"}。后训练数据(少量、求质和准):
- SFT(
sft_t2t.jsonl):构造/筛选高质量问答对,来源含人工标注、公开数据、模型蒸馏合成(作者用 qwen3-4b 合成约10w条tool call)。筛选靠 LLM-as-a-judge 打分 + 多样性去重。格式{"conversations":[{role,content}]}。- RL/DPO(
dpo.jsonl):每条是「同一问题的好/坏回答对」(chosen/rejected),用于偏好对齐。一句话总结: 预训练清洗重在「质量过滤+去重+去污染」,SFT 重在「高质量问答对+格式统一」,DPO 重在「构造好坏对比对」。
minimind 的数据集是作者已清洗好的成品,直接训练即可。
Q9. 怎么看 GPU 利用率?nvidia-smi 表盘完整解读
命令: nvidia-smi(看一次);watch -n 1 nvidia-smi(每秒刷新实时盯,Ctrl+C 退出,不影响训练)。
表盘第一区(整卡状态):
| 59% 83C P1 300W / 300W | 7807MiB / 97887MiB | 97% Default |
↑ ↑ ↑ ↑ ↑ ↑
风扇 温度 性能 功耗/上限 显存用量/总量 算力利用率
笔记:关键看两个数,且它俩是两回事:
- Memory-Usage(显存用量):
7807/97887 MiB= 用了 7.8G / 共 96G。显存够不够「装得下」。- GPU-Util(算力利用率):
97%= 计算单元忙不忙。卡「算得快不快/有没有闲」。- 其他:风扇% / 温度(83℃偏高但安全) / Perf状态(P0最高~P8最低) / 功耗(300W已拉满=Max-Q功耗墙)。
- ECC、MIG 一般用不到。
表盘第二区(进程):
PID 42514 C python 7284MiB ← 你的训练进程占了 7.3G
PID 2898 G Xorg 175MiB ← 桌面系统占的,忽略
笔记:
Type列C=计算进程(你的训练),G=图形进程(桌面)。能看出显存被谁吃了。
Q10. 加大 batch_size 为什么没更快?为什么要同步调大学习率?
笔记:踩坑认知——「显存没满 ≠ 可以无脑加 batch 提速」。 判断卡有没有「吃饱」要看 GPU-Util,不是显存:
- 显存 8% 但 GPU-Util 已 97% → 算力已满载,加大 batch 不会提速(吞吐量/每秒token数已固定)。
- 只有 GPU-Util 偏低(卡在等数据/batch太小喂不饱)时,加 batch 才提速。
实测: batch 32(39695步/epoch) → 128(9924步/epoch),总时间基本不变甚至略增。因为每步算4倍活、总步数变1/4,乘起来≈不变。早期 epoch_time(ETA) 偏高是因为启动开销摊在少量步数上,不准,跑久了会降。
大 batch 的真正收益是「训练质量」不是「速度」: 梯度噪声更小、更稳,可配更大LR、用更少epoch收敛。
为什么 batch 和 LR 要一起放大:
- batch 大 → 梯度估计更准 → 敢迈更大步(大LR),不怕走偏。
- batch 大 → 总步数变少 → 每步不迈大点会欠训练,需大LR补偿。
缩放法则(batch 放大 k 倍):
法则 LR 调整 适用 线性缩放 ×k SGD 平方根缩放 ×√k Adam/AdamW(minimind用这个) batch 32→128(×4):AdamW 推荐 √4=×2,即 5e-4 → 1e-3。真正提速的手段(不是加batch):
--use_compile 1(torch.compile) / 减少--epochs。
今日待办状态
- 建立
.venv虚拟环境(~/Project/minimind/.venv) - modelscope 装进
.venv - 清理误装到 home 的包和缓存
- 下载数据集(全量已下到 ~/.cache,再 mv 进 ./dataset/;下载时漏了
--local_dir是坑) - 安装 PyTorch GPU 版(torch 2.11.0+cu128,Blackwell 必须 cu128)+ requirements.txt
- 成功跑通第一次预训练(loss 从 ~7.3 正常下降)✅
- 配置 VSCode 调试(已建 .vscode/launch.json,需装 Python 扩展,用 F5 而非
python xxx.py) - 跑完预训练 → 用 eval_llm.py 测试生成效果