ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

从零构建AI工程:完整路线图与实战复盘

从零构建AI工程:完整路线图与实战复盘 ai-engineering-from-scratch这个名字最早出现在我笔记里还是三年前。当时我在一家互联网公司做后端每天看着算法团队的PPT——训练损失下降模型效果提升——心里很清楚自己在AI面前就是个门外汉。真正促使我开始动手的是一次需求评审会产品经理问我这个AI功能大概多久能上线我答不上来因为我对整个训练链路毫无概念。于是我从零开始花了大约八个月时间走完整条路从补数学基础、写Python脚本到用numpy手写线性回归再到从零实现一个几十万参数的小型语言模型最后把它做成一个API服务部署上线。这篇文章就是那条路线图的完整复盘。我会把每一阶段的核心任务、关键选择、踩坑记录和时间规划都摊开来讲。不管你当前是完全没写过代码的转行者还是和我当年一样有编程背景但没接触过AI的后端工程师这条from scratch路线都能直接用。1. 为什么from scratch路线值得走1.1 AI工程不是调包而是一条完整链路我见过太多人一上来就装好 transformers 库跑通一个情感分析 demo然后觉得自己已经入行了。等真遇到实际项目就全懵了数据为什么这么脏模型线上效果为什么和线下差那么多显存爆了怎么办接口延迟太高怎么优化这些问题恰恰是 AI 工程的核心。AI 工程不只是一个算法问题它是一条从数据到模型的完整链路数据工程采集、清洗、标注、特征构造、数据版本管理。模型工程模型选型、架构设计、训练策略、超参调优。推理工程模型压缩、量化、部署、推理加速、弹性伸缩。评估工程离线评估、线上测试、效果监控、数据回流。任何一个环节掉链子整个系统都跑不稳。而from scratch的意义就是让你有机会亲手把这条链路上的每一个环节都走一遍而不是永远停留在别人做好了什么我拿过来用的层面。1.2 从零开始不是回到原始社会而是重建心智模型有人一听from scratch就害怕以为要把整个数学体系重学一遍甚至连深度学习框架都不能用一切从寄存器写起。这完全是误解。我理解的scratch有三层含义理论从零不跳过必要的算法原理。你要能解释梯度下降为什么能让 loss 持续下降而不是只会调用 optimizer.step()。实现从零核心算法和模型架构至少亲手实现一遍哪怕用 PyTorch 这种框架也要清楚每一层到底在算什么。不是为了造轮子是为了建立正确的直觉。经验从零不从现成模板和示例项目出发而是从需求出发自己设计数据流程和训练方案。一个很贴切的生活类比是学吉他。你可以照着网上的六线谱一首一首弹三个月能弹好几首歌但换一首新曲子还是不会。可如果你先花时间搞明白吉他为什么是六根弦、和弦是怎么构成的、变调夹的原理是什么——之后再学新曲子速度完全不一样。前者是会弹后者是懂音乐。AI 工程也是一样的。1.3 这条路适合谁先看看这几类人先说结论适合所有愿意慢下来打底子的人。如果你是完全没有编程经验的转行者我建议在起步阶段花一个周末玩一玩 Scratch 少儿编程工具别觉得幼稚。它的积木式逻辑——顺序、循环、条件判断——几乎把编程思维的骨架都摆在你眼前了。我见过好几个转行朋友就是靠 Scratch 建立了程序是由一条条指令组合而成的直觉再学 Python 完全不费劲。如果有 iPad从 Scratch Jr 这个更简化的幼儿版开始也行同样是先建立结构化思维。如果你有后端或前端经验编程基础已经有了直接从数学和机器学习开始就好。我这条路线里的实操对照可以帮你省掉大量试错。不适合谁呢不适合只想三天内调出一个大模型 demo、发个朋友圈交差的人。那种需求直接调用 API 就好真的不用读这篇文章。2. 核心路线全拆解四阶路线从零到可用2.1 第一阶编程与数学地基1-2个月这一阶段的目标不是成为数学专家而是建立两个能力能写代码完成数据处理能看懂算法公式里的核心符号。编程方面Python 是绝对主线。基础部分需要掌握变量与数据类型、列表/字典/集合、循环与条件、函数定义与调用、类与面向对象、文件读写以及常用的数据处理库。不要求精通但要求能独立写一个读取 CSV 文件并统计某字段分布的小脚本。数学方面很多人是被数学劝退的。这里给你一颗定心丸AI 工程日常用到最多的数学其实只有三个模块。线性代数矩阵乘法、矩阵形状变换、内积。深度学习里所有数据都是向量和矩阵理解批量处理其实就是矩阵运算是第一步。微积分导数与梯度。反向传播的核心就是链式法则你只需要理解梯度是损失函数在山坡上的指向就够了。概率统计常见概率分布、期望、条件概率、最大似然估计。语言模型生成一个词本质上就是从一个概率分布里做采样。实操建议不要单独啃数学课本。拿 numpy 手写一遍线性回归包括梯度下降你会发现自己在写代码的过程中把线性代数和微积分都补上了比背三百页公式效率高十倍。2.2 第二阶机器学习与深度学习原理2-3个月第一阶搞定后你已经能写代码、能看懂基本公式了接下来进入机器学习。机器学习的世界看起来模型很多线性回归、逻辑回归、决策树、随机森林、SVM、KMeans……但它们的骨架其实是一致的就是四个要素数据、模型、损失函数、优化算法。你给模型喂数据模型输出预测损失函数衡量预测和真实标签的差距优化算法最常见的是梯度下降调整模型参数让差距变小。所有模型万变不离其宗。这个阶段我强烈建议你手写关键算法而不是直接调库。比如用 numpy 实现逻辑回归在一个简单二分类数据集上完成训练和评估。用 numpy 实现一个两层神经网络手写反向传播理解每一行计算对应链式法则的哪一步。对每个算法都画一遍loss 随迭代次数变化的曲线亲眼看它降下来。深度学习本质上就是更多层 更大数据 更强算力的神经网络。要掌握的核心概念其实不多反向传播、自动微分框架、卷积与 Transformer 的基本思路。只要把两层神经网络的反向传播手写懂了再看 Transformer 的梯度流心理上完全不难只是计算图的复杂度高了而已。2.3 第三阶从零构建大语言模型3-4个月这是整条路线里最硬核、也最有成就感的一段。我的核心参考是《Build a Large Language Model from Scratch》这本书它几乎就是为from scratch路线量身定做的实战手册从准备训练数据开始手把手带你写 BPE 分词器、搭建 Transformer 架构、实现预训练循环、做指令微调最后还能把模型打包成一个可交互的对话应用。如果你想做 AI 工程落地而不是纯算法研究第三阶可以这样拆第一数据准备。找一个小规模文本语料比如一部公版英文小说或若干篇文章合集。先做一个字符级或子词级分词器。数据决定了模型的上限这一步绝对不能省。第二模型架构。从零搭建一个 mini 版 GPTembedding 层把 token 变成向量多头自注意力让每个 token看到上下文前馈网络做非线性变换每一层再接残差连接和 LayerNorm。这些模块加起来也就一两百行代码但每一行都有明确的数学含义。第三训练。先在小的语料上把语言建模这个目标跑通——预测下一个 token。然后再做指令微调让模型学会回答指令问题。想更进一步可以了解 RLHF但小模型阶段不是必需的。第四进阶方向。当前的热词是 build a reasoning model from scratch也就是从零构建推理模型。大模型在数学推理、逻辑推理上的能力是工程落地的关键瓶颈在小模型范围内尝试推理能力的构建是一个性价比极高的方向。2.4 第四阶工程化落地与部署1-2个月模型训练出来只是第一步真正体现工程二字的是落地。从工程视角看你要把训练好的模型包装成线上服务。最简单的方案是用 FastAPI 包一个 HTTP 接口让外部系统能发起推理请求。之后再逐步补全用 Docker 做容器化部署、通过批处理和流式处理优化吞吐、用量化把模型从 FP16 压到 INT8 甚至 INT4 以降低显存占用、用 vLLM 之类的推理框架提升并发能力。同时必须建立评估与监控体系。离线评估要关注准确率、召回率、困惑度等指标线上要监控推理延迟、请求量、错误率并且设计数据回流机制——线上用户输入经过脱敏后进入下一次训练集形成数据-模型-反馈-再训练的闭环。这里送大家一个经验工程化升级要一步一个脚印不要一开始就上全家桶。先把一个最简单的接口跑通哪怕直接用 requests 发请求调模型也行然后在保证可用的前提下逐项加东西。工程的首要原则永远是先能跑再跑得快最后跑得稳。3. 实操记录从零训练一个小型GPT模型3.1 项目定位与硬件准备理论路线看完了下面用一个小项目展示从零开始具体意味着什么。我的练习项目是这样定位的用一小段真实文本大约两万多个 token 的规模训练一个参数量只有几十万的小型 GPT 模型。训练完成后它能生成一些语法通顺、但内容不太有逻辑的短句。可当你亲眼看到模型学会了生成语言那种成就感足够支撑你继续学下去。这个项目的硬件门槛极低。如果只用 CPU 也能跑只是慢一些我用的是一张 4GB 显存的旧显卡完全够用。这也说明from scratch路线并不烧钱真正贵的是你的时间和耐心。3.2 数据准备分词与数据集构建第一步是准备语料。我把一本公版英文小说下载下来去掉目录、标题等噪声只保留正文清洗后大概两万多 token。接下来是分词。最简方案是字符级分词把每个字符当成一个 token。优点是简单直观缺点是序列太长、训练效率低。更实用的是子词级分词最常见的算法是 BPE从单字符统计开始迭代地把高频共现的字符对合并成新 token直到达到目标词表大小。下面给出 BPE 训练流程的示意代码生产级实现建议直接参考 tiktoken 一类的成熟库# 简单的BPE训练流程示意 # 输入文本列表目标词表大小 # 1. 统计每个字符的频率得到初始词表 # 2. 循环 # a. 统计所有相邻token对的共现频率 # b. 找到频率最高的一对合并为一个新token # c. 更新词表 # 3. 重复直到达到目标词表大小有了分词器后还要把语料切成长度为 block_size 的样本构造训练集。每个样本里前 n 个 token对应第 n1 个 token语言模型的学习任务就是这么定义的。3.3 模型架构手写Transformer核心组件这是整个项目最核心的部分。我建议把它拆成四个子模块逐一实现。第一个是 Token Embedding 层。每个 token 对应一个固定维度的向量Embedding 矩阵的形状是 [vocab_size, n_embd]随机初始化后交给模型在训练中自己学习。第二个是位置编码。Transformer 本身没有顺序感所以要给模型提供 token 的前后关系。简单有效的做法是给每个位置也学一个向量加到 token 的 embedding 上。第三个是多头自注意力它是 Transformer 的心跳。核心思想是对序列里的每个 token通过查询Q、键K、值V三个向量计算我应该多关注序列里哪些位置。import torch import torch.nn as nn import torch.nn.functional as F class Head(nn.Module): def __init__(self, head_size, n_embd, block_size, dropout0.1): super().__init__() self.key nn.Linear(n_embd, head_size, biasFalse) self.query nn.Linear(n_embd, head_size, biasFalse) self.value nn.Linear(n_embd, head_size, biasFalse) self.dropout nn.Dropout(dropout) # 因果掩码矩阵保证每个token只能看到自己及之前的token self.register_buffer(tril, torch.tril(torch.ones(block_size, block_size))) def forward(self, x): B, T, C x.shape k self.key(x) # (B, T, head_size) q self.query(x) # (B, T, head_size) # 计算注意力分数缩放因子取 head_size 的平方根 wei q k.transpose(-2, -1) * (k.shape[-1] ** -0.5) # (B, T, T) wei wei.masked_fill(self.tril[:T, :T] 0, float(-inf)) wei F.softmax(wei, dim-1) wei self.dropout(wei) v self.value(x) # (B, T, head_size) out wei v # (B, T, head_size) return out第四个是前馈网络加残差与层归一化。注意力机制让 token 之间交换信息但每个 token 自身的思考需要前馈网络完成一个两层的 MLP激活函数常用 ReLU 或 GELU。残差连接保证深层网络的梯度顺畅回流LayerNorm 让每一层的数值分布保持稳定。把这四个模块组合起来就是标准的 Transformer Block。多个 Block 叠加再接一个输出头把最后一层 hidden state 映射到词表大小的 logits一个可训练的 GPT 模型就完成了。3.4 训练循环与推理生成训练的本质是让模型的输出 logits 与目标 token 的交叉熵损失最小。优化器选 AdamW它对新手很友好不太需要精细调学习率。for step in range(max_steps): x, y get_batch() # x是输入序列y是右移一位的下一个token logits model(x) loss F.cross_entropy(logits.view(-1, logits.size(-1)), y.view(-1)) optimizer.zero_grad() loss.backward() optimizer.step() if step % 500 0: print(fstep {step}, loss {loss.item():.4f})推理生成时核心是自回归把当前序列输入模型预测下一个 token再把这个 token 接回序列尾部继续预测下下个直到达到目标长度。为了让生成结果更丰富一般不直接取概率最高的 token而是按概率采样用 temperature 控制随机程度。def generate(model, idx, max_new_tokens, context_length, temperature1.0): for _ in range(max_new_tokens): idx_cond idx[:, -context_length:] logits model(idx_cond) logits logits[:, -1, :] / temperature probs F.softmax(logits, dim-1) idx_next torch.multinomial(probs, num_samples1) idx torch.cat((idx, idx_next), dim1) return idx训练几万步之后这个几十万参数的小模型就能生成出像模像样的短句。你会亲眼看到 loss 从 5.5 左右一路降到 1.5 附近的完整过程这比看任何教程都更能建立对语言模型的直觉。3.5 跑通之后的几点心得跑完这个小项目有几个体会非常深刻。一是模型的本质是压缩。模型学会的其实是训练数据里的统计规律数据里有什么模型才会什么。这让我养成了先看数据、先分析数据分布的习惯。二是超参数的影响非常直观。学习率设到 3e-3 以上loss 很容易发散发散设到 1e-4 以下收敛慢得让人着急。从零调一遍之后你对学习率为什么是工程调优第一参数会有肌肉记忆。三是用 TensorBoard 之类的工具记录 loss 曲线非常必要。如果没有曲线你根本分不清模型是在正常训练还是在原地打转。4. 常见问题与排查技巧实录4.1 学习阶段最容易踩的五个坑先讲学习阶段。第一个坑是数学恐惧症。很多人在线性代数上耗了一个月觉得矩阵乘法都没整明白不配学 AI。我的建议先接受我不需要知道每件事的完整证明只要能用直觉理解矩阵乘法是批量计算的一种形式就可以继续走。用到什么数学补什么数学你会发现自己比想象中学得快。第二个坑是跳跃式学习。跳过机器学习直接学 Transformer跳过原理直接用大模型 API短时间看是快了两步长期看是把自己卡在永远只会调用、不会创造的天花板下。第三个坑是只抄不看。很多人 clone 别人的实现跑通之后沾沾自喜。跑通 demo 大概只占整个学习的 10%剩下 90% 在于你能不能不看代码自己重新实现一遍能不能回答这里为什么用 LayerNorm 而不是 BatchNorm第四个坑是完美主义。想把所有细节都理解透了再动手写代码结果是三个月过去笔记一堆命令行一行没敲。先跑起来再逐步理解是自学者最该有的节奏。第五个坑是资料贪多。今天收藏这个课程明天买那本书资源库越攒越大动手时间越来越少。挑一两个核心资源跟到底比囤一百个文件夹有用得多。4.2 训练与部署中的高频问题速查训练过程中问题几乎是一路踩过来的。这里把最高频的问题整理成一张速查表现象可能原因排查方法loss 下降很慢或不动学习率太小、数据未预处理、样本太少画数据分布检查噪声尝试把学习率调大 5-10 倍观察loss 突然变成 NaN学习率过大、数值溢出、数据里有 NaN调小学习率检查预处理是否产生除零加梯度裁剪训练集 loss 低但验证集高过拟合增加数据、加 dropout、早停、减小模型规模生成文本全是重复词模型太小、训练不充分、temperature 太低延长训练调高 temperature尝试 top-k/top-p 采样显存不足batch size 太大、序列太长减小 batch size 或 block_size用梯度累积在线服务延迟高模型参数量大、未量化、并发处理弱用 INT8/INT4 量化批量处理请求考虑 vLLM 等推理框架排查思路的核心是控制变量。一次只改一个参数并且记录每次实验的超参和结果。很多新手一上来同时改学习率、batch size、模型层数出了问题根本没法定位。我自己的做法是每次实验只动一个旋钮用表格记录像做物理实验一样。另外一个常被忽略的坑是随机种子。同样的代码跑两次结果不一样是正常的——如果你不设置种子PyTorch 的随机初始化每次都会不同。复现实验时一定要固定 seed同时记录依赖库的版本号。4.3 资源清单与时间规划最后给出一份亲测有效的资源清单。书籍《Build a Large Language Model from Scratch》是从零构建大模型的最佳实践参考配合《深度学习》花书作为原理查漏补缺。课程吴恩达的机器学习公开课虽然是十多年前的老课但概念清晰度至今无人能比。工具PyTorch 官方教程里的 60 分钟入门篇HuggingFace 文档用于工程化阶段参考。启蒙完全零基础的话先用 Scratch 少儿编程工具花一个周末建立编程思维再回头学 Python。时间规划上第一阶 1-2 个月第二阶 2-3 个月第三阶 3-4 个月第四阶 1-2 个月总时长大约 7-10 个月。如果全职学习可以压缩到 4-6 个月如果每天只有两小时业余时间按 10 个月规划更现实。这里再强调一句不要在一个知识点上死磕超过三天。遇到实在绕不过去的先跳过等整条链路通了之后回头再看很多难点会豁然开朗。个人经验这类从零开始的项目最难的不是技术本身而是在没有外部压力时保持稳定的输出节奏。我自己的办法是每周强迫自己产出一个可以看到的东西代码也好、笔记也好、训练曲线截图也好。这些东西既是进度记录也是下一周继续下去的动力。哪怕某周只写了一个几十行的脚本也远好过一周什么都没动。最后再分享一个小技巧在电脑桌面放一个专门的文件夹按日期命名每次实验比如2026-03-15-lr-3e-4-block8。三个月后回头翻这个文件夹你看到的是一份活生生的成长地图。这种可视化的进步感比任何学习计划表都管用。
返回列表