train-llm-from-scratch
从零手写 Transformer + 完整 RLHF 管线,PyTorch 驱动的 LLM 训练实战
加载项目详情…
本应用为开源项目,仅供学习研究,请遵守其开源协议。
从零手写 Transformer + 完整 RLHF 管线,PyTorch 驱动的 LLM 训练实战
加载项目详情…
本应用为开源项目,仅供学习研究,请遵守其开源协议。
想象你坐在一台有显卡的电脑前,看着屏幕上几行代码从零开始训练出一个能够写作、对话甚至推理的语言模型——这个场景,正是 train-llm-from-scratch 所要呈现的。这是一个从数据下载、Tokenization、模型架构、预训练到后训练(SFT/PPO/DPO)全流程覆盖的开源项目,8012 个 GitHub Stars 背后,是无数 AI 学习者"亲手训练一个真正属于自己模型"的渴望。
当今开源社区已有大量现成的开源模型——Llama、Mistral、Qwen——下载权重文件、几行推理代码就能跑起来。然而,正是这种"黑箱调用",让很多学习者始终停留在"会用但不懂原理"的层面。FareedKhan-dev/train-llm-from-scratch 项目的诞生,恰恰是为了打破这一困境。
作者 Fareed Khan 在 GitHub 项目中明确表示,自己正在寻找 PhD 职位,并希望这个项目能成为深度学习研究者的实操指南。与 Andrej Karpathy 的 makemore 系列教程一脉相承,但覆盖面更广——从 Pile 数据集的 825GB 原始语料,经过数据清洗、Tokenization、模型训练,到最终 RLHF 对齐,每一步都有可运行的 Python 脚本支撑。
项目 topics 包含 large-language-models、llm、training、transformers,与 gemini 和 openai 的关联说明其定位是通用 LLM 训练框架,不绑定特定 API 或云平台。
项目的技术栈极为纯粹:Python 3.9+、PyTorch(无 transformers、trl、peft 等第三方训练库)。这意味着你看到的每一行代码,都直接对应着大模型训练的核心原理。
从目录结构来看,核心代码分为两条主线:
主线一:预训练(Pretraining)
整个预训练流程建立在 src/models/ 下的四个模块之上:
token_embed / position_embed:分别处理词表嵌入和位置编码,与标准 Transformer 完全一致Block(多头注意力 + MLP):每个 Transformer 块包含 Multi-Head Self-Attention 和前馈网络,中间穿插残差连接和 LayerNormTransformer 主类:整合所有块,最终通过 lm_head(线性层)输出词汇表大小的 logits配置文件支持可调节的参数包括:n_head(注意力头数)、n_embed(嵌入维度)、N_BLOCKS(Block 数量)、context_length(上下文窗口)和 vocab_size。默认 400M 参数配置(n_embed=1024, n_head=16, n_blocks=24, context_length=1024)在单卡 H100 上可训练。
主线二:后训练(Post-Training)
src/post_training/ 目录是这个项目最令人印象深刻的部分——实现了完整的 RLHF 训练管线,且全部手写:
| 阶段 | 核心文件 | 功能 |
|---|---|---|
| SFT | sft.py | 有监督微调,通过 loss_mask 仅对 assistant 回复部分计算损失 |
| Reward Model | reward_model.py / reward_train.py | 训练一个标量奖励模型,用于评估回复质量 |
| PPO | ppo.py | 近端策略优化,用 reward model 反馈更新策略 |
| DPO | dpo.py | 直接偏好优化,绕过 reward model 直接用人类偏好数据训练 |
| GRPO | grpo.py | DeepSeek 开源的群体相对策略优化,用 GSM8K 验证数学推理能力 |
| Inference | inference.py | 推理脚本,支持采样和贪心解码 |
图1:Transformer 完整架构(来源:项目 images/)
整个后训练管线在 sft_rlhf_guide.ipynb 中以 Jupyter Notebook 形式详细记录,数据集涵盖 Alpaca、Dolly、Anthropic HH-RLHF、UltraFeedback 和 GSM8K 等真实公开数据集。
训练 LLM 的第一步,是把互联网语料变成模型能吃的数字。项目中 data_loader/ 目录处理了这一步骤:
data_loader.py:原始数据加载器,支持 HDF5 格式的批量数据读取tokenizer 训练:使用 tiktoken(OpenAI 开源的 BPE 分词器)从训练数据中学习词表数据处理流程如下:原始 Pile 语料 → Zstandard 压缩解压 → tiktoken BPE 分词 → HDF5 存储 → DataLoader 批量加载。每一步都有独立脚本支持。
图2:数据 Tokenization 流程
项目提供四种安装方式:
pip install -e . # 基础安装
pip install -e ".[train]" # + 数据集下载 + wandb 日志
pip install -e ".[ui]" # + Streamlit 可视化控制面板
pip install -e ".[all]" # 全部安装
虽然没有 Dockerfile 或 docker-compose(不支持容器化一键部署),但 pip install -e . 的 editable 模式已经将 config、src、data_loader 等目录自动加入 Python 路径,省去了手动配置 PYTHONPATH 的麻烦。
Streamlit UI(ui/app.py)提供了图形化控制面板,可以监控训练进度、调整超参数、查看指标曲线——这是项目体验上的加分项。
图3:训练循环可视化
| 维度 | 评估 |
|---|---|
| 部署难度 | 中等(需配置 Python + CUDA) |
| 预估时间 | 30 分钟 |
| GPU 需求 | 必需(13M 模型单卡可跑;2B 模型需多卡 H100) |
| Web UI | 可选(Streamlit) |
| 容器化 | 不支持 |
纯 PyTorch + 无第三方训练库意味着代码透明、原理清晰,但同时也意味着你要自己处理 CUDA 版本、内存溢出、分布式训练等问题。对于初学者,从 13M 参数的小模型开始是更稳妥的选择。
项目 README 中有一段难得的坦诚声明:
"a ~400M model pretrained from scratch on 2×H100 is coherent and instruction-followable and shows real before/after gains at each stage, but its absolute GSM8K score stays modest — frontier numbers need far more pretraining compute."
这说明了几件事:
train-llm-from-scratch 的价值不在于复现一个 GPT-4,而在于降低理解门槛。当你能亲手训练一个 100M 参数的语言模型、理解 SFT 和 DPO 的梯度更新差异、看到 reward model 如何影响生成策略时,再去看 HuggingFace 的 Trainer API,你会发现自己对底层机制的理解已经完全不同。
这也是为什么项目能在一年多时间内积累 8000+ Stars——在 LLM 训练"黑箱化"趋势愈演愈烈的当下,这个坚持"每一行代码都可读"的项目显得格外珍贵。
图4:训练损失曲线