附录 C 踩坑与 FAQ
|
本附录收录本项目实测中出现的问题与解法,按「环境 → 训练 → 数值 → 部署」组织。 遇到报错时,先在 C.5 快速诊断表里查症状:表内处方能直接处置的就地处理, 需要展开的再回到对应小节看详细解法。 |
C.1 环境:安装与下载
RE2 安装失败 / torchtext 分词器不可用
第 2 章可选使用 torchtext 官方 GPT2BPEEncoder,其正则引擎依赖 RE2:
sudo apt-get install libre2-dev
安装失败或平台不提供该包时,改用教程自带的 bpe_tokenizer.h:纯 C++ 实现,无外部依赖,数值与官方一致。全部章节默认使用它。
第 2 章的双实现交叉验证保证了这个替身可用:官方版缺席时,自研版结果可以直接对账。
HuggingFace 下载慢 / 403
所有下载脚本统一用 HF_MIRROR 开关选择源:
HF_MIRROR=hf-mirror ./scripts/download-weights.sh # 默认:hf-mirror.com
HF_MIRROR=huggingface ./scripts/download-weights.sh # HF 官方(需海外网络)
ALL_PROXY=socks5h://localhost:30000 ./scripts/download-data.sh # 走代理
默认源 hf-mirror.com 国内无代理可达,速度约 10 MB/s;下载失败时自动回退 huggingface.co。GitHub raw 数据(nl2bash 等)国内可直连但较慢,超时再用 ALL_PROXY 指定代理。
Ollama 起不来(7.8 节评分用)
./scripts/start-ollama.sh --pull # 启动 ollama serve,并拉取 llama3(4.7 GB)
ollama list # 此时应看到 llama3 在列
程序内 query_ollama 请求 http://localhost:11434/api/chat。Ollama 不可达时,第 7 章会打印跳过提示后继续,不会崩溃。评分是可选环节,跳过不影响其余章节。
C.2 训练:显存与耗时
GPT-2 medium 训练 OOM(16 GiB 卡)
medium(355M)全参微调加 AdamW,显存大头是优化器状态。动量与二阶矩约 2×355M×4B ≈ 2.8 GB(账目见第 9 章),此外还有梯度与激活。16 GiB 显卡实测安全配置:
SIZE=medium EPOCHS=3 BATCH=4 ./scripts/train-background.sh # 16 GiB 卡用 batch=4
batch 提到 8 及以上会 OOM;small(124M)用 batch=8 没有问题。显存不足时按此顺序缩减:减 batch → 减 max_length → 改用第 9 章的 LoRA(可训练参数降到约 2%)。换更大的卡放在最后。
训练耗时量级(RTX 4080/4090 级,供预期管理)
开跑前先核对下表,预估等待时间:
| 任务 | GPU 耗时 | 备注 |
|---|---|---|
第 5 章 124M × 10 epoch(The Verdict) |
分钟级 |
9 batch/epoch,很小 |
第 7 章 medium × 2 epoch(Alpaca 1100 条) |
3–4 分钟 |
参考:A100 级 GPU 约 0.86 分钟 |
第 8 章 demo 配置(CPU) |
1–2 分钟 |
emb=256 的小模型 |
第 13 章 small SFT 1 epoch(GSM8K) |
105 秒 / 1550 步 |
medium 335 秒 |
第 13 章 GRPO 100 步 |
208 秒 |
batch=1, group=2 |
C.3 数值:为什么我的 loss 与实测锚点不一样
TF32:GPU 上 loss 与 CPU 结果在第三位小数不一致
Ampere 及之后的 GPU 默认用 TF32 做 matmul,速度约快 8 倍,尾数只有 10 位。本项目所有 main.cpp 开头都有关闭代码:
at::globalContext().setAllowTF32CuBLAS(false);
不关闭时,GPU 结果与 CPU 数值会在 1e-2 量级上漂移。要复现书中数值,保持默认(关闭 TF32);要追求吞吐量,可以打开 TF32 并接受数值偏差。
C.4 部署:平台与进程
Windows 与 Linux 的差异清单
| 项 | Linux(本项目实测环境) | Windows 注意点 |
|---|---|---|
编译器 |
GCC 11 / C++17 |
MSVC 可编译但 CMake 脚本未适配;建议 WSL2 或 MSYS2 UCRT64 |
HTTP 服务 |
POSIX socket( |
|
popen |
|
|
路径分隔符 |
CMake 已用 |
注意 DATA_DIR 宏的默认值带 |
C.5 快速诊断表
遇到报错,先查下表的「症状」列,再按「处方」处理:
| 症状 | 最可能原因 | 处方 |
|---|---|---|
loss 第一步就 ≈ 12+ 且不降 |
数据目录没找到 / 词表文件缺失 |
检查 DATA_DIR 与 encoder.json(词表见第 2 章) |
GPU loss 与书对不上 |
TF32 未关 |
|
同 seed 结果不同 |
初始化顺序(先 to(device)) |
见上节「manual_seed」 |
medium 训练中途 OOM |
batch=8 太大 |
batch=4 或换 LoRA |
服务 400 bad request |
JSON body 未按 Content-Length 截断完 |
检查 curl 引号转义(解析实现见第 10 章) |
Ollama 评分全跳过 |
服务未启动 / llama3 未拉取 |
|
eval AST-match 全是 null |
未安装 bashlex |
|