一个人用纯PyTorch从零手写了一整套大模型



代码地址:https://github.com/FareedKhan-dev/train-llm-from-scratch

GitHub上有个仓库这周突然冲上趋势榜,叫train-llm-from-scratch,一个巴基斯坦开发者用纯PyTorch从零手写了一整套大模型训练流程,从预训练到对齐全覆盖,5400多颗星还在往上窜,我花了一晚上把代码翻了一遍,说说我的判断。

先说这项目干了什么,作者FareedKhan没有用Hugging Face的transformers库,没有用任何现成的训练框架,就是原生PyTorch,从头到尾一行一行把Attention is All You Need那篇论文实现了出来,多头注意力机制是自己写的,MLP是自己搭的,Transformer Block是自己拼的,连位置编码都是手动的,然后往上垒成了完整的语言模型,用The Pile数据集开训,单张显卡就能跑,13M参数的模型一天之内能训完,输出结果已经有模有样了,至少语法是对的,正确标点也能用上了,甚至偶尔能冒出几句前后连贯的话来,虽然跟GPT-2那种流畅度还差着距离,但作为一个从零开始在单卡上跑出来的东西,已经算是跨过了从噪声到文字的那道坎。

到这里如果能停住,其实已经是个不错的教程项目了,Karpathy的nanoGPT干的事儿差不多,llm.c也是类似的思路用C直接写,但FareedKhan往前又走了一大步,他这段时间加了整套后训练流程,SFT监督微调,Reward Model奖励模型,PPO近端策略优化,DPO直接偏好优化,GRPO群组相对策略优化,五个阶段全部纯PyTorch手写,不用trl不用peft,每个算法都能跑通,数据集用的是Alpaca,Dolly,Anthropic HH-RLHF,UltraFeedback,GSM8K这些公开的,多GPU并行也支持了,DDP加bf16混合精度训练都接好了。

我之所以觉得这事儿值得聊,不是因为又一个从零训练的项目出现了,而是因为这背后有个一直存在的争论,到底有没有必要从零训练一个LLM,市面上开源模型一大堆Llama,Qwen,DeepSeek,Mistral,拿过来微调一下不就完了吗,从零训练又费钱又费电,图什么呢。

我先说自己的经历,我之前试过用Llama做垂直领域的微调,LoRA那种,几百条数据跑几下,跑出来的效果看着还行,但总觉得差点意思,模型在特定场景下偶尔会冒出一些完全不相关的知识,像是预训练阶段记住了什么东西擦不干净,你微调只是在上面铺了一层薄漆,底下的旧纹路还是会透出来,尤其是当你想模型不要做某件事的时候,微调的约束力特别弱,模型会在你不注意的时候恢复默认行为,这个问题在领域特别窄的场景下尤其明显,比如医疗,比如法律,那些通用预训练语料里的「常识」有时候恰好是你要避免的错误。

FareedKhan的项目给了另一种可能性,你自己控制每一步,从数据选择到词表大小,从上下文长度到注意力头数,全是你说了算,没有预训练阶段的遗留问题,因为预训练也是你做的,这种掌控感是微调给不了的。

当然了,掌控感归掌控感,现实问题也得面对,FareedKhan的数据集用的是The Pile,825GB的语料,他只用了5%到10%来训练,他的实验结论是13M参数大概是能输出可读文本的门槛,再小就开始胡言乱语了,这跟我自己之前拿小模型做实验的体感是吻合的,大概在千万参数这个量级确实是语言模型开始「说话」的临界点,可13M是什么概念的模型呢,GPT-2 Small是117M,现在大家用的起码是7B起步,差了几个数量级,而他从13M训练到2B就需要A100或者RTX 4090了,这不是普通个人开发者随便能折腾的规模。

不过他给的GPU兼容表倒是让我多看了几眼,从GTX 1080 Ti一路列到RTX 5090,每个卡能训多大的模型都标了,RTX 5090那边有社区跑过,13M模型峰值显存0.6GB,我当时看到这个数愣了一下,我自己的经验里这种从零实现的项目显存管理通常都很粗糙,他这个明显是花过心思的,有些仓库你看完README兴冲冲地clone下来,跑起来发现一块卡半天才出一轮loss,这种落差体验过的人都知道。

后训练那块有个东西让我觉得他确实不只是想写个教程,GRPO这个算法是DeepSeek R1论文里提的,用来让模型自己学会推理,说实话我没想到会有人把这个也手写出来,PPO和DPO已经够折腾了,GRPO的采样逻辑比那两个还要绕,group怎么切,组内reward怎么排,kl惩罚贴在损失函数的哪个位置,说实话我看了两遍才理清楚,他等于把预训练之后的整条路都铺完了,SFT到Reward Model到PPO到DPO到GRPO,你现在找教程,预训练的满大街都是,后训练能讲清楚两个阶段的都少见,五个阶段全手写的,反正我是没碰到过。

Karpathy的nanoGPT在这块算是标杆了,代码极简,几千行完事,看一遍基本上Transformer的核心就清楚了,llm.c走的是另一条路,直接拿C写,追求极致速度,但也就只管了预训练那一段,litgpt我之前用过一阵,现成的脚本和配置倒是方便,但出了问题你得去翻它封装好的逻辑,改起来很不顺手,FareedKhan这个代码量比nanoGPT大不少 ولی读起来不算费劲,关键是覆盖的面广太多了,预训练到对齐都跑了,你想在哪一步做实验改参数都很方便下手,不像litgpt那样有时候想改个loss函数都得先研究半天它的代码结构。

我自己看完代码之后的感觉,刚入行的人真该跑一遍,注意力权重那块你用transformers库调用的时候就是一行代码,但你自己写的时候会发现QKV矩阵乘完还要scale,scale完要mask,mask完才做softmax,这一串操作光看论文你记不住的,跑一遍代码每一步的tensor shape都打印出来,很多东西瞬间就通了,至于说拿这个项目去训一个能用的模型替代Llama什么的,那肯定不现实,人家几千张A100跑了几个月,你拿一张4090从头训,产出质量和效率都不是一个档次的事,但话说回来,你自己走一遍预处理数据、搭模型、训loss、做对齐这个流程,以后用Llama微调出问题的时候你至少知道问题大概出在哪一环。

还有个细节,作者在GitHub简介里放了求职信息,在找AI方向的博士职位,我翻了翻他的提交记录和issue回复,确实是个认真写代码的人,不是那种fork完改两行就当自己项目的人。

说回那个核心问题,从零训练到底值不值得,这事儿不能一刀切,你只是想用大模型干点活的话,Llama加LoRA大概率够用了,没必要折腾,但我想说的是另一件事,我之前理解RLHF只知道那是让模型更听话的技术,直到我自己写了reward model的损失函数,才意识到那个训练过程本身就是用人类偏好数据去拟合一个打分器,打分器的好坏直接决定了模型学偏了还是学对了,这个理解不看代码是真的建立不起来的,所以值不值得取决于你想停留在哪个层面,用是一层,理解是另一层,从零走一遍是通往后面那层的路。

FareedKhan做的事倒是有个实际的落地价值,这张路线图普通开发者真的能跑起来,GTX 1080 Ti就行,跟着走一圈从数据下载到生成文本到对齐,全流程体验一遍,这个过程本身学到的东西比到头来那个13M参数的模型值钱太多了。

说个可能得罪人的观察,我接触过不少用大模型但完全不想了解训练细节的人,prompt工程玩得很溜,效果一差就换模型,从来不思考为什么这个模型不行那个行,另一边做训练的朋友呢,loss曲线烂熟于心但是没法跟下游用户解释为什么某个case表现差,你问他为什么模型在这个prompt上胡说八道,他大概率会跟你说数据有问题或者对齐没做好,但具体是哪个环节谁也说不准,这两拨人其实很需要一座桥,从零跑一遍训练流程至少能让你站在桥中间,两边的话都能听懂一点。


来源

  1. [FareedKhan-dev/train-llm-from-scratch] — GitHub,2026年6月
  2. [Attention Is All You Need] — Vaswani et al.,NeurIPS 2017
  3. [nanoGPT] — Karpathy,GitHub
  4. [llm.c] — Karpathy,GitHub
  5. [DeepSeek-R1: Incentivizing Reasoning Capability in LLMs via Reinforcement Learning] — DeepSeek,2025年1月

以上,既然看到这里了,如果觉得不错,随手点个赞,在看,转发三连吧,想早点收到推送,也可以给我个星标⭐~
谢谢你的阅读,下次再见。

作者 AISet

阅读全文