首页
/
行业洞察
/
正文
INDUSTRY INSIGHT · 深度
从零实现AI工程:手写神经网络与Transformer核心组件
📅 2026/11/2 18:09:05
✍️ 爱科研究院
👁 阅读 3,247
说实话我最近在帮团队做技术面试时越来越有一种焦虑感。来面试的人简历上都写着“熟悉PyTorch”“熟悉Transformer”可真坐下来聊两句很多人连Softmax在计算时为什么要做数值稳定处理都答不上来。更别提让他现场推一下反向传播的链式法则了。这不怪候选人要怪就怪现在这个时代封装太好了好到大多数人的“AI工程能力”其实只是“调API能力”。这也是我对“ai-engineering-from-scratch”这类项目特别有感觉的原因。它说的不是“从零训练一个大模型”这种口号而是一种学习路径把AI工程里那些被框架封装好的核心组件一个个亲手拆开、亲手实现、亲手跑通。这篇文章我想完整聊聊这条路径到底该怎么走、每一步要做什么、会遇到哪些坑、以及它最终能给你带来什么。如果你是一个有点Python基础、想真正理解AI工程底层逻辑的开发者这篇文章应该对你有用。1. 为什么市面上AI教程那么多我还是建议你“从零开始”1.1 黑盒式学习的隐患你看过很多模型但你没有工程判断力我先说说现在的学习氛围。打开B站、知乎、各类知识付费平台最不缺的就是AI课程。今天教你用LangChain搭一个客服机器人明天教你用几行代码微调一个开源大模型。说实话这些课程有它的价值——它让你的“应用视野”拓宽了你知道原来这个东西能这样做。但问题也很明显你解决问题的能力是片段化的。一旦出现文档里没有的情况一旦环境报一个你从没见过的错你就懵了。因为你没有“底层模型”。打个比方你开过很多款车但从来没打开过引擎盖。有一天仪表盘上亮起一个陌生的灯你只知道“好像有问题”却不知道是机油、水温还是传感器的事。AI工程也一样Loss不下降你知道是学习率的问题还是数据的问题吗梯度爆炸你知道该去哪一层找原因吗训练显存溢出除了调小batch size你知道还有其他解法吗这些判断力不是靠“看教程”能获得的必须靠“亲手实现一遍”来获得。1.2 “from-scratch”不是重复造轮子是给轮子做一次“爆炸图”很多人一听到“从零实现”就皱眉说这不就是重复造轮子吗有PyTorch不用非自己写个神经网络图什么这里我想澄清一个概念。“ai-engineering-from-scratch”的“从零”不是为了生产环境去替代框架而是为了学习去复刻框架。你的目的不是写一个比PyTorch更好的库而是理解PyTorch里那些设计决策到底是什么。比如你手写过一个两层的神经网络你才会真正明白nn.Linear做了什么它不过是在做矩阵乘法加偏置W x b然后喂给激活函数。你手写过一个训练循环你才会真正理解optimizer.zero_grad()为什么训练前必须调用——因为PyTorch的梯度是累积的不清零上一次的梯度就会一直叠加。这种“原来如此”的时刻是看多少文档都换不来的。我把它比作看手表。你平时戴表看时间from-scratch就是拆开表盘、看那些齿轮怎么咬合的那一步。它不会让你变成一个修表师傅但它会让你在表出问题时至少知道问题大概出在哪一环。1.3 这套路径到底适合谁不适合谁说实话我不建议所有人都去走这条路。得先判断自己的情况。比较适合的人是这些有一定Python基础会写循环、函数、类但机器学习经验不多的人。这条路能帮你建立完整的知识骨架而不是东一榔头西一棒子地学碎片。已经在用PyTorch、TensorFlow做项目但总觉得心里没底、遇到问题只能靠上网搜的人。从零实现一遍会补上你缺失的底层的拼图。有强烈好奇心不甘心只做“调包侠”的人。这条路的驱动力很依赖兴趣没有好奇心很难走完。不太适合的人是这些目标和紧迫性很强、需要一两周内交付商业Demo的人。请不要绕远路直接用现成框架和现成模型怎么快怎么来。完全零编程基础的人。这条路默认你会Python如果你连pip install都还不熟悉建议先去补一个月编程基础再回来。记住这是一个“打地基”的路径它的回报周期比较长但回报是复利式的。2. 从数学到LLM应用这条路线图到底分几步2.1 第一站线性代数与概率论要学到什么程度很多人一听到数学就头大直接劝退。我在这里给你吃一颗定心丸——“ai-engineering-from-scratch”路线里的数学不需要你达到数学系本科的水平。你只需要精通这几样向量和矩阵的乘法尤其是多维张量的维度变换。这个最核心因为它就是神经网络的前向传播的本质。偏导数和链式法则。这是反向传播的数学基础。简单的概率知识比如条件概率、最大似然估计的基本概念。这能帮你理解交叉熵损失函数和softmax函数是从哪来的。我自己学习时的经验是不要先去啃一整本《线性代数》教材那太耗时了而且大部分内容比如特征值、奇异值分解的证明你暂时用不上。更好的方式是用什么学什么。比如你要写一个线性回归你发现代码里有一行np.linalg.inv(X.T X) X.T y这时你再去查“正规方程”是什么、矩阵法求解线性回归的原理是什么。这种“以用带学”的方式效率极高而且因为有你自己的代码做锚点理解也更深刻。另外我要特别强调不要用符号恐惧症吓唬自己。你第一次看到一个损失函数的数学表达式时会觉得头皮发麻。但一旦你把它一步步翻译成Python代码你发现它不过是一组循环和加法乘法。数学符号只是语言的缩写不是魔法。2.2 第二站经典机器学习的手写实现这是必修课进入代码之前第一件值得做的事是不调Sklearn手写经典机器学习算法。我建议至少写这四个线性回归用梯度下降实现而不是直接套“正规方程”。梯度下降是往后所有深度学习训练的雏形你把这个流程跑熟了后面全都是它的变体。逻辑回归它是分类模型的基础而且和神经网络的最后一层Sigmoid输出直接相关。注意区分它和线性回归在损失函数上的差异——回归用均方误差分类用交叉熵。K-Means聚类这个简单但能让你理解“无监督学习”的思考方式没有标签怎么通过数据本身的分布来发现结构。决策树或朴素贝叶斯任选其一体会一下非神经网络类的机器学习模型长什么样。每写一个算法都要在sklearn的make_classification等玩具数据集上测试和库版本的结果对比精度。这个对比过程非常重要它是你验证自己理解是否正确的金标准。这一站的意义在于你建立了“训练”这个概念的完整心智模型。你知道训练一个模型包含四个步骤——前向传播计算预测、计算损失、反向传播求梯度、更新参数。后面所有的模型无论多复杂都是这四个步骤的重复和扩展。2.3 第三站手写神经网络和反向传播先自己推一遍再谈框架这是很多人的坎也是最值得跨过去的一道坎。这一站的经典任务用NumPy手写一个两层的神经网络在MNIST数据集如果你有硬件限制取一个子集比如6000张图上做手写数字识别。你需要自己实现的组件包括参数初始化。你会遇到“全零初始化导致无法学习”的问题然后你会真正理解为什么需要随机初始化以及为什么常用Xavier或He初始化——因为合适的初始化方差能防止前向传播时信号的消失或爆炸。前向传播。包括全连接层、ReLU激活函数、Softmax输出层。反向传播。这是最痛苦也最精华的部分你要手动写出每个参数的梯度公式并且用代码实现。梯度下降更新。包括batch size的选择——这就是batch gradient descent、stochastic gradient descent、mini-batch gradient descent的区别所在。一个非常推荐做的验证步骤数值梯度检查gradient check。就是用数值方法来近似验证你手推的梯度对不对对某个参数的梯度用(loss(wepsilon) - loss(w-epsilon)) / (2*epsilon)来近似。如果这个值和你的解析梯度不一致你的反向传播代码里一定有bug。这个技巧我当年用了不知道多少次它能精准定位你在链式法则中算错的那个位置。当你完成这一站你已经具备了独立的深度学习实现能力。往后的Transformer、GPT也好底层都是这些拼积木的重复一个组件接一个组件每个组件都要能前向算输出、反向算梯度。2.4 第四站从Transformer到LLM应用从零实现一个“迷你GPT”到了这一站就是标题另一个关键词“ai-engineering”的真正含义了——把现代AI工程最热门的LLM方向也纳入进来。这里我不建议一上来就搞几千亿参数的大模型那既不现实也没必要。正确做法是实现一个极简的GPT组件尽量少、参数尽量小但结构必须完整。我称之为“教学版GPT”它包含文本预处理构建词表。你可以从一个很小的语料开始比如几百首歌的歌词或者莎士比亚的一小段文本。Tokenization先用最朴素的“按字符切分”或“按空格切分”实现一个简单的tokenizer。理解了token是什么、词表怎么构建之后再了解BPE字节对编码的原理你会对现代tokenizer的设计逻辑一目了然。Embedding层把token变成一个稠密向量。你可以实现一个可训练的nn.Embedding的简化版本。多头自注意力机制这是整个Transformer的核心。要理解Q、K、V三个矩阵分别是什么注意力权重怎么计算、为什么要除以sqrt(d_k)缩放点积注意力以及因果掩码causal mask对于GPT这类生成模型为什么必不可少。Transformer Block把多头注意力和前馈网络、残差连接、LayerNorm组装起来。彻底理解了LayerNorm做的是什么对每个样本的特征做归一化而不是仅仅把它当成一个“提出LayerNorm性能就涨了”的黑盒子。训练与生成用交叉熵损失训练然后实现一个简单的自回归生成——每个时间步输出下一个token的概率分布采样后拼回去继续生成。我把这个完整项目做完时大概的代码核心部分也就五六百行基于NumPy或基础PyTorch。当你在这个小模型上看到一个句子生成效果逐渐变得“有人样”的时候那种满足感是看任何教程都给不了的。这一站学完之后你再去读HuggingFace上任何一个小模型的源码或者去读GPT-2论文你会有种“这我熟”的感觉它无非是把教学版做了工程化扩展——更大的词表、更多的层数、更多的头数、更长的上下文。3. 实操笔记我跑通这套路径时的环境与关键实验3.1 基础环境别在环境上浪费时间也别过度依赖GPU整个from-scratch过程大部分实验在普通笔记本电脑上就能完成。我给一个保险的配置建议Python版本3.10或3.11都可以。新版向下兼容性都做得不错。包管理直接用venv或conda创建独立虚拟环境。我习惯用conda create -n ai-from-scratch python3.11原因很简单——conda在解决一些非Python的依赖比如特定版本的NumPy、MKL时更省心。核心依赖numpy、matplotlib用于数据生成和可视化。在开始阶段不需要PyTorch。等到了Transformer阶段如果手写反向传播太吃力可以先转换到PyTorch的自动微分——但请注意我强烈建议你至少在NumPy阶段把MLP的反向传播手写一遍那才是真正的理解。关于GPU教学版GPT参数量控制在几十万以内用CPU训练几十个step完全可行。我自己的经验是单核CPU训练一个两层MLP在MNIST子集上几分钟就能完成。不要一开始就被“必须用GPU”吓住。当然如果你有Colab或者本机有CUDA环境训练速度会快很多但这绝对不是前期的硬门槛。3.2 数据准备很多教程不会写清楚的细节数据是AI工程的起点但也是教学中最容易被一带而过的部分。这里有几个细节值得注意第一不要一上来就用完整MNIST的6万张图。开发阶段先用一个小子集比如1000张保证代码能在一个循环内快速跑通。模型训练是否收敛、Loss是否下降这些信号比“训练多少万步”更重要。等你确认代码逻辑没问题再逐步放大数据量。第二数据归一化几乎是必做的。比如MNIST图像的像素值是0-255的整数如果不缩放到0-1之间输入信号的量级偏大模型初始化出来的输出通常就处在Softmax的饱和区梯度会非常小训练几乎不动。最简单的做法是除以255.0就够。很多代码讨论里“Loss不下降”的问题根源就在这里。第三划分训练集和验证集。哪怕是学习项目也要养成这个习惯——训练集上表现好但验证集上变差的时刻就是你亲眼看见“过拟合”发生的时刻。这种亲身经历比背十遍“过拟合是模型泛化能力差”的定义都管用。3.3 核心实验一手写两层神经网络识别手写数字把训练过程画出来在这个实验里除了最终精度我特别建议你把训练过程可视化出来——画Loss曲线、画验证集精度变化。为什么因为训练的本质是“Loss曲线的下降”。一旦你习惯了盯着Loss看你对模型训练的感觉会完全不一样。以后再用PyTorch、用大模型你的第一反应就是“训练日志里的曲线是对的才谈后面的调参”而不是“代码好像跑起来了就够了”。具体的操作路径是加载MNIST子集把图片展平成784维向量。自定义一个随机初始化参数的两层网络Linear(784, 128) - ReLU - Linear(128, 10)输出接Softmax。用交叉熵损失。注意手写交叉熵时需要加一个极小值epsilon防止log(0)的出现。训练循环每次迭代计算梯度更新参数记录loss。每迭代若干次在验证集上计算一次准确率。 -用matplotlib把loss曲线画出来你会看到一个指数衰减的漂亮曲线。这个实验给我个人的最大收获是我彻底不再怕反向传播了。因为我已经亲手在草稿纸上画过计算图、写了每一层的梯度推导、又在代码里验证过它与数值梯度的一致。之后不管看到什么论文里的新模块我都能条件反射式地去想“这个模块的梯度应该怎么传”。3.4 核心实验二搭建一个极简Transformer做文本生成当你能手写MLP之后进入Transformer其实是水到渠成的。我的建议是不要用现成的框架代码要自己组装。我的做法是这样的选一个小语料比如把某一部公版小说的前几章作为训练数据。几百KB的文本足够教学用。构建一个字符级词表大概几十个字符这样词表不大会让训练更轻松。定义好超参数n_embd64embedding维度n_head4注意力头数n_layer2Transformer层数block_size128上下文长度。依次实现Attention类含causal mask、Block类Attention 两层前馈 LayerNorm 残差连接、GPT类Embedding Blocks 最后的Linear输出层。训练每次取一批长度为128的文本片段目标是预测下一个字符。让交叉熵损失稳定下降到一个合理值比如2.0以下直觉参考如果词表64个字符随机预测的loss约log(64)≈4.16降到2.0说明平均每步候选字符从64个缩小到约7个。生成从任意字符开始进行自回归采样。可以加一个temperature温度参数控制生成多样性与确定性。我用这个教学版GPT在本地生成的“仿莎士比亚”段落虽然语法不通但已经能看出单词规律和长短短句结构了。那一刻你会真正意识到ChatGPT离我并不遥远它就是这条路径放大到极致的结果。4. 在这条路上最容易翻车的四个坑我都替你踩过了4.1 数学符号恐惧症别被公式劝退先用代码理解再回补理论你得有个心理准备这条路中途一定会遇到让你想关掉网页的公式。比如Transformer论文里的这一个Attention(Q, K, V) softmax(QK^T / sqrt(d_k)) V第一次看到这个公式人很容易懵。我当时也懵。但后来我找到了一个特别适合工程思维的学习法先把公式的每一部分都对应到代码变量上。你看这段话可以这样对应Q、K、V是输入分别乘上三个可学习矩阵得到的矩阵每行是一个位置的向量。在代码里就是q x W_q。Q K.T是计算两两位置之间的“匹配度”代码里是torch.matmul(q, k.transpose(-2, -1))。除以sqrt(d_k)是为了缩放防止内积过大导致softmax进入饱和区、梯度消失。Softmax是归一化成概率。最后乘上V就是按注意力权重对信息做加权求和。当你把公式每一块都翻译成代码“公式恐惧症”就会消失。不要试图先学会全部理论再动手敲代码这不是工程思维的玩法。工程思维是先看到代码再理解为什么它会这样设计。4.2 训练不收敛、Loss不下降定位问题的标准排查链路这是所有人在这条路上几乎100%会遇到的现象。我当初手写GPT时Loss卡在4.2左右纹丝不动急得抓耳挠腮。后来总结出了排查链路以后遇到类似问题我都是走这套流程效率奇高第一步检查数据本身有没有问题。标签对不对输入没有归一化数据是不是打乱了普通字符太重复导致模型学到的是“复制上一句”之类的trivial捷径。第二步检查梯度是否正确。这就是前面说的数值梯度检查。如果解析梯度和数值梯度的误差超过1e-4量级那说明你的反向传播实现有bug别急着调超参数。第三步检查损失的数值稳定性。Softmax后接交叉熵时不要让模型直接输出概率改用logits输入配合log_softmax把数值往安全区推。如果你的实现里出现了log(0)或softmax溢出Loss显示为nan都不意外。第四步尝试调小学习率。训练初期Loss不降很常见的原因是学习率过大导致loss震荡或者学习率过小导致下降缓慢。我习惯的攻击范围是1e-4到1e-1之间按数量级试。第五步检查初始化。权重初始化太大会导致激活值饱和梯度消失全零初始化会导致对称性问题神经元无法差异化。用Xavier或He初始化往往能解决一大部分问题。按这个顺序排查90%以上的“训练不动”问题都能定位。如果这五步都没问题但loss仍不降那大概率是你模型结构自身逻辑有误回头检查维度拼接是否一致。4.3 “从零实现”和“生产可用的工程”之间的鸿沟这条路径有一个隐含的巨大陷阱我必须说出来你手写的MLP或者教学版GPT性能非常差而且不要拿它去拥抱生产环境。它的核心目的是教育不是替代。举个例子。我手写的教学版GPT训练速度远低于HuggingFace的GPT-2。为什么因为我的实现没有做KV Cache键值缓存生成每个token都要重新计算前面所有token的注意力复杂度是二次方而工业级实现会缓存之前的K、V避免重复计算。又比如我的DataLoader每次都要做随机的数据打乱而工业级实现会精细设计采样策略、动态填充、多进程预取等优化。所以请你务必想清楚跑通这套路径的目标是“建立认知地图”。以后当你面对真实工程项目时你在手写过程中建立的心智模型会让你更快理解工业级代码的设计动机但你真正写生产代码时还是要站在巨人肩膀上用成熟框架、成熟模型、成熟工具链。4.4 学习节奏的失控别做完美主义者固定产出比固定时长更重要我在自学的过程中还有个很深的感觉这条路非常考验节奏感。很多人学着学着就陷入“完美主义循环”——总想把每一个组件都理解到极致再往下走结果卡在一个点上好几个星期最后放弃。我的建议是给自己定一个“最小产出”原则。举个例子今天我不要求把Transformer讲得完美只要求把因果mask的实现代码写出来。明天我不要求把生成效果调到惊艳只要能把从开头到20个字符的生成流程跑通。产出要足够小小到今天一定能完成且完成之后能看到一个结果。这个结果可能是几行代码、一张loss曲线、一段生成的文本。正是这些看得见的反馈才支撑你走完这条长路。5. 从“从零开始”到真实工程落地这套路径的最终价值5.1 迁移到PyTorch实战时你将自动获得“源码阅读能力”很多人问我我花那么多时间手写最终在平时工作里到底能用在哪最直接的收益就是你在使用PyTorch时会从一个“只会查文档的搬运工”变成一个“能读懂源码的人”。举个例子。以前你看到nn.TransformerEncoder的时候你可能只会查参数、按文档调用。但当你从零实现过Transformer之后你会下意识地想“它的源码里是不是和我一样先做self-attention、再加残差连接、过LayerNorm”你会主动打开PyTorch源码确认一下你的理解。甚至当PyTorch出了一个新模块你会自己先按照论文实现一版再和官方实现对比差异。这个习惯一旦建立你的学习速度会有质的飞跃。再比如你遇到一个微调任务时你会理解为什么调大学习率会让数据规模小的任务立即过拟合因为你从底层就知道学习率过大会让权重更新的步长直接跨过最优区域。5.2 工程素养的底层迁移数据管线、评估体系、实验管理AI工程里最耗时间的往往不是“模型代码”本身而是环绕在模型周身的工程问题。而from-scratch这个过程恰恰能顺便锻炼这些底层素养数据管线意识。在你的MNIST子集实验里你必然会处理数据下载、格式转换、归一化、批次切分。这些步骤放大十倍、百倍就是工业级数据管线的雏形。评估意识。你不会只看训练集loss。你会自然地做训练/验证集划分看验证集指标。这套“训练集-验证集-测试集”的心智框架直接迁移到真实项目就是完整的评估体系设计。实验管理习惯。手写实验时你很自然会记录“今天learning rate调到0.01loss从3.0降到2.6明天调到0.001loss降到3.5”——这就是最朴素的实验日志也是wandb这类管理工具的底层逻辑。我见过太多人上来就用高级工具结果连“我这个改动到底是好是坏”都说不清楚。从零开始的笨方法恰恰帮你把“实验-评估-记录”这个最底层的循环建立起来。5.3 后续继续深入的方向训练、部署、以及工程化扩展当这条路径走到阶段尾声你的知识地图已经初具雏形。接下来往哪个方向走取决于你的目标如果想做模型训练与优化研究混合精度训练、ZeRO分布式训练、梯度累积、学习率调度器。这些概念你在手写训练循环时会碰过一次现在去读它们的技术博客没有理解障碍。如果想做部署与服务研究模型量化INT8、INT4、权限验证、推理优化KV Cache已提过、流式输出。有了底层认知选型就不再是盲目的。如果想做LLM应用研究RAG检索增强生成、Agent编排、工具调用、长上下文优化。那些高级接口的本质依然是你实现的文本生成循环——输入一串token输出下一个token循环往复。我个人之后的路径是从训练端逐步转向部署端因为我发现做训练时有一条条看不见的边界——显存上限、延迟要求、吞吐约束——只有亲手碰过部署你才会真正理解模型性能约束的方方面面。最后再分享一个私藏的小技巧完成教学版GPT之后你可以做一次实验把学习率从1e-3改成1e-1观察梯度爆炸的整个过程。你会发现Loss瞬间飙到几十输出的文本变成乱码。这个“故意弄坏”的体验比只看“梯度爆炸”这四个字要生动得多也比你丢失一个生产环境的训练任务才学会珍惜要便宜得多。AI工程这条路很长但要我说最值得花力气的恰恰就是开头这段“自己动手重造轮子”的路。慢但每一步都算数。
📌 标签:
工业官网
设计趋势
AI 建站
SEO
获取完整报告 →
RELATED ARTICLES
推荐阅读
2026/11/2 18:09:05
VS2019闪退问题排查:从软件到CPU微码的深度解析
2026/11/2 18:04:03
基于HER思想构建个人复盘系统:让失败成为可复用的经验数据
2026/11/2 18:04:03
LSTM-Adaboost混合模型在电力负荷预测中的应用
2026/11/2 19:19:50
双重形式化框架:自然语言与机器逻辑的桥梁
2026/11/2 19:19:50
面部关键点检测全链路:从CSV坐标到CNN回归与掩码MSE
2026/11/2 19:19:50
MeteorSeed:快速生成项目脚手架的前端开发工具
2026/11/2 19:19:50
Web性能监控:PerformanceObserver API实战指南
2026/11/2 19:19:50
轨迹约束智能体的课程设计与思维链压缩技术
2026/11/2 19:14:47
低代码IDE与生成式AI结合加速智能客服开发
2026/11/2 1:03:35
工业SPI隔离方案:K64主控+MAX14431从设计到排查
2026/11/2 1:03:35
SPI隔离器MAX14431与PIC18F8722实现工业级稳定通信的实战指南
2026/11/2 1:03:35
雷达信号调制技术解析:从LFM到相位连续调频波形设计
2026/11/2 2:42:45
面向复杂光照与角度的宠物面部识别鲁棒性增强策略
2026/11/2 2:42:47
DRV8818PWPR与R7FA8M1AHECBD工业步进驱动实战指南
2026/11/2 2:42:50
STM32与DRV8818双极步进电机驱动方案:从选型到调试全流程解析
2026/11/2 2:42:45
面向复杂光照与角度的宠物面部识别鲁棒性增强策略
2026/11/2 2:42:47
DRV8818PWPR与R7FA8M1AHECBD工业步进驱动实战指南
2026/11/2 2:42:50
STM32与DRV8818双极步进电机驱动方案:从选型到调试全流程解析