第 1 章 环境准备与首次运行 本章目标:5 分钟把项目跑通,建立「能跑」的信心,再回头抠细节。 1.1 环境要求 组件 | 要求 | 说明 Python | ≥ 3.9 | 3.10/3.11 更佳 GPU | 可选 | 有 CUDA 显著加速;CPU 也能跑,只是慢 内存 | ≥ 4GB | 数据集才 1MB,主要吃模型 磁盘 | 500MB | 数据 + checkpoint(25M 模型约 100MB) 操作系统支持 系统 | 支持度 | 注意 Linux | ✅ 最佳 | 多进程、CUDA 都顺畅 macOS | ✅ 良好 | Apple Silicon 用 MPS 后端 Windows | ⚠️ 可用 | 多进程有坑(见 1.4) 1.
本章目标:5 分钟把项目跑通,建立「能跑」的信心,再回头抠细节。
| 组件 | 要求 | 说明 |
|---|---|---|
| Python | ≥ 3.9 | 3.10/3.11 更佳 |
| GPU | 可选 | 有 CUDA 显著加速;CPU 也能跑,只是慢 |
| 内存 | ≥ 4GB | 数据集才 1MB,主要吃模型 |
| 磁盘 | ~500MB | 数据 + checkpoint(25M 模型约 100MB) |
| 系统 | 支持度 | 注意 |
|---|---|---|
| Linux | ✅ 最佳 | 多进程、CUDA 都顺畅 |
| macOS | ✅ 良好 | Apple Silicon 用 MPS 后端 |
| Windows | ⚠️ 可用 | 多进程有坑(见 1.4) |
# GPT 训练与推理项目依赖 # 安装: pip install -r requirements.txt # ---- 深度学习框架 ---- torch>=2.0.0 # transformers 提供 GPT2LMHeadModel / GPT2Config transformers>=4.36.0 # ---- 分词器 ---- tiktoken>=0.5.0 # ---- 数据处理 ---- datasets>=2.14.0 numpy>=1.23.0 # ---- Web UI ---- gradio>=4.0.0 # ---- 进度条与工具 ---- tqdm>=4.65.0 # ---- 注意 ---- # CPU 训练较慢,建议在支持 CUDA 的 GPU 环境下运行。 # Windows 用户若 num_workers>0,请确保训练入口在 if __name__ == "__main__": 中。
| 依赖 | 干啥用的 | 缺了会怎样 |
|---|---|---|
torch |
张量、自动求导、GPU | 啥都干不了 |
transformers |
提供 GPT2LMHeadModel |
模型构建失败 |
tiktoken |
BPE 分词 | 数据编码失败 |
datasets |
HF 数据集加载 | 优雅降级,会回退到 GitHub 直链下载 |
numpy |
set_seed 用 | seed 设置失败 |
gradio |
Web UI | 仅 app.py 受影响 |
tqdm |
进度条 | 训练循环里报 ImportError |
注意 datasets 的特殊性:项目用 try/except ImportError 把它的 import 包起来(见 dataset.py:22-26),缺失时会优雅降级,不影响训练。
# 1.(推荐)创建虚拟环境,隔离依赖 python -m venv .venv # Windows 激活 .venv\Scripts\activate # Linux / macOS 激活 source .venv/bin/activate # 2. 安装依赖 pip install -r requirements.txt
pip install torch 默认装 CPU 版。要装 CUDA 版(Linux/Windows)去 PyTorch 官网「Get Started」页面,按你的 CUDA 版本选择对应的安装命令(官网会给出形如 pip install torch --index-url ... 的命令),复制执行即可。
验证 CUDA 是否可用:
python -c "import torch; print(torch.cuda.is_available(), torch.cuda.get_device_name(0) if torch.cuda.is_available() else 'CPU only')"
用一个超小配置快速验证环境:
python train.py --max-iters 50 --n-layer 2 --n-embd 64 --n-head 2 --block-size 32
预期输出(大致):
[train] 使用设备: cuda [dataset] 从本地缓存读取: data/tiny_shakespeare.txt [dataset] 文本共 338025 tokens,可构造 337992 个长度为 32 的样本。 [train] 模型可训练参数量: 0.21M [train] 开始训练: 共 50 步, 每个 epoch = 10562 步 训练: 10%|██ | 5/50 [00:02<00:18, 2.45 step/s] [train] step 10/50 | avg_loss=4.3210 | lr=2.70e-04 | speed=4.12 step/s ... [train] 训练完成。 [train] 最终模型已保存: checkpoints/gpt_final.pt
每行含义:
N = 总 token − block_size − 1。python inference.py --prompt "To be, or" --max-tokens 50
预期输出(50 步训练的模型只会输出乱码,这正常):
[inference] 已加载: checkpoints/gpt_final.pt [inference] prompt: 'To be, or' ===== 生成结果 ===== To be, or the sould the day the day the day the day...
💡 乱码是预期的——50 步训练远不够。这一步只是验证端到端流程通:训练 → 存盘 → 加载 → 推理。
python app.py # 浏览器打开 本地端口 7860
界面长这样:
┌──────────────────────────────────────────────────┐ │ # 🤖 GPT 文本生成器 │ ├────────────────────────────┬─────────────────────┤ │ 提示词 (Prompt) │ 最大生成长度 ───●── │ │ ┌────────────────────────┐ │ 温度 ──●─── │ │ │ To be, or │ │ Top-K ──●─── │ │ └────────────────────────┘ │ Checkpoint 路径 │ │ [生成] │ ┌─────────────────┐ │ │ 生成结果 │ │checkpoints/... │ │ │ ┌────────────────────────┐ │ └─────────────────┘ │ │ │ │ │ │ │ └────────────────────────┘ │ │ └────────────────────────────┴─────────────────────┘
到这里三步全通,工程链路就验证完成了。下一步可以正式训练。
默认配置(约 25M 参数、5000 步):
python train.py
单 GPU 大约 10-30 分钟,CPU 几小时。
训练过程中关注 loss 走势:
step 100 | avg_loss=4.85 ← 刚预热完,还在乱猜 step 500 | avg_loss=3.21 ← 开始学到模式 step 1000 | avg_loss=2.54 ← 学到常见词 step 2500 | avg_loss=1.88 ← 学到句子结构 step 5000 | avg_loss=1.52 ← 接近收敛
💡 经验值:tiny_shakespeare 上一个 25M 模型训到 loss ~1.5 就能生成「像莎士比亚风格」的伪文本了。loss < 1.0 需要更大模型或更多数据。
⚠️ 如果你用 Windows 且把
--num-workers设大于 0,必须确保训练入口位于if __name__ == "__main__":保护块内。
Windows 没有 fork(),多进程用 spawn 启动子进程:子进程会重新导入主模块。如果训练调用 train() 不在 if __name__ == "__main__": 下,会发生:
主进程 import train.py ──► 执行 train() ──► 起 DataLoader 子进程 │ ▼ 子进程重新 import train.py 执行 train() ──► 起 DataLoader 子进程 │ ▼ 递归...
最终要么卡死、要么 OOM、要么端口冲突。
train.py 末尾:
if __name__ == "__main__": train()
这行保护下,子进程 import 时 __name__ 不是 "__main__",不会重复执行 train()。
TrainConfig.num_workers = 0(不开子进程),无论哪个平台都安全。Windows 用户没特殊需求就用默认值。
error: Microsoft Visual C++ 14.0 or greater is required
Windows 上 tiktoken 编译需要 C++ build tools。两个解法:
pip install tiktoken --prefer-binary。>>> torch.cuda.is_available() False # 但你明明有 NVIDIA 卡
pip install torch 默认 CPU 版。卸载重装 CUDA 版(见 1.2)。
urllib.error.URLError: <urlopen error ...>
GitHub 网络连接不稳定时可能失败。手动方案:
dataset.py 中的 _TINY_SHAKESPEARE_URL)data/tiny_shakespeare.txt(UTF-8 编码)python train.py,会命中本地缓存。把下面这段存成 check_env.py,运行 python check_env.py,全过则环境 OK:
import sys print("Python:", sys.version) import torch print("PyTorch:", torch.__version__) print("CUDA available:", torch.cuda.is_available()) if torch.cuda.is_available(): print("CUDA device:", torch.cuda.get_device_name(0)) import transformers print("transformers:", transformers.__version__) import tiktoken enc = tiktoken.get_encoding("p50k_base") print("tiktoken vocab size:", enc.n_vocab) print("encode('hello'):", enc.encode("hello")) import gradio print("gradio:", gradio.__version__) print("\n✅ 环境检查通过")
--num-workers 设为 2(Windows),观察是否会报错或卡死,理解 if __name__ == "__main__" 的作用。--device cpu 强制 CPU 训练 100 步,对比与 GPU 的速度差异(用 tqdm 显示的 step/s)。--max-iters 改成 10,确认 checkpoint 是否在最后一步被保存到 checkpoints/。pip install -r requirements.txt 一键装齐,GPU 用户额外装 CUDA 版 torch。python train.py --max-iters 50 --n-layer 2 --n-embd 64 --n-head 2 --block-size 32。num_workers=0 或遵守 if __name__ == "__main__": 保护。环境 OK 后,去 第 2 章 配置体系 搞懂所有超参数的含义。