ARTICLE DETAIL

资讯详情

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

AI工程从零到一:为什么调用API只是起点

AI工程从零到一:为什么调用API只是起点 为什么说“pip install 一下”和 AI 工程之间隔着一整条护城河两年前我在团队里接过一个需求——用 AI 对合同做关键条款审核。那会儿最流行的做法是调大模型 API把几十页合同扔进去让模型抽取出付款条件、违约责任、续约条款。我花了两周搞定 demo效果惊艳老板当场拍板“下个月上线”。然后噩梦开始了长合同截断导致漏条款、特殊排版表格乱掉、模型输出格式不稳定、并发一高延迟就飙到十几秒最后还得自己写规则引擎去校验模型输出。那两周让我彻底想明白了一件事会调用别人训练好的模型叫 AI 应用开发能把一个 AI 系统从数据到训练到部署到监控完整地搭起来、优化起来、稳定地跑在生产环境里才叫 AI 工程。“AI engineering from scratch”这个主题想说的就是这件事。它不教你三分钟调用一个 API也不教你硬啃几个月数学论文。它是一条把底层原理、工程实践、工具链选择、踩坑经验串起来的完整路径——适合两类人一是写了几年业务代码、想转 AI 方向的开发者二是已经在用现成模型做应用、但总觉得自己在“拼积木”、想补上底层功底的工程师。下面这些东西都是我自己从零搭项目时一步一步踩出来的不是课程大纲是实际操作过、验证过、也翻过车之后留下的经验。1. 先搞清楚“能跑”和“工程化”之间隔了多远的距离我在各种社区里见过太多类似的讨论有人发帖说“我用 LangChain 接了个 GPT-4 做客服机器人这个算 AI 工程师吗”底下评论吵成一片。这个问题本身就有问题——因为“用 LangChain 接 GPT-4”这件事的难度和一个真正在生产环境里稳定运行的 AI 客服系统之间差距是全方位的。1.1 AI 应用开发与 AI 工程的核心差异用做饭来类比可能更直观。AI 应用开发是照着菜谱做菜——菜谱告诉你放多少盐、炒几分钟你照着做菜能上桌但这不叫你会做菜。AI 工程是你要开一家餐厅——你得懂食材供应链数据从哪来、怎么清洗、懂后厨设备GPU 怎么配、推理引擎怎么选、懂菜品标准化模型输出怎么让它在 100 万次请求里都稳定、懂成本控制推理成本怎么从每千次 5 块钱降到 1 块钱、懂食客反馈bad case 怎么收集、怎么反哺模型。拿我做的合同审核项目举例。demo 阶段我只需要把 PDF 转成文本按固定 prompt 问模型几个问题解析返回的 JSON。这个链路任何会写 Python 的人两周都能跑通。但到了生产阶段问题变成了这样合同 PDF 有扫描件、有表格嵌套、有页眉页脚干扰文本抽取直接决定模型效果的上限。这一步的工程量大得惊人OCR 选型、版面分析、表格还原每一个都是独立的技术栈。用户对“审核结果”的信任要求极高模型的输出不能直接扔给用户看得过一层校验条款抽取是否完整、金额数字和原合同是否一致、日期格式是否规范。这一层规则引擎的编写和维护工作量不比模型本身小。合同提交有高峰时段上午十点到十一点集中涌入。模型的推理速度跟不上就得做缓存、做并发控制、做动态 batch甚至要拆分模型服务做水平扩展。用户会对审核结果反馈“这里查错了”“这里漏了”这些反馈怎么回流、怎么变成新的训练数据、怎么评估新版本模型有没有改进——这又是一整套闭环。你看模型本身只是整个系统的一小部分。我后来统计了一下合同审核项目里真正花在模型训练和调优上的时间大概只占 20%。剩下的 80% 都在做数据、做推理优化、做校验逻辑、做监控告警。这就是 AI 工程和 AI 应用开发之间的真正区别前者把模型当系统的一个组件来对待后者把模型当全部。1.2 三种不同层级的“AI 工程师”顺着这个思路可以把市面上自称 AI 工程师的人分成三档。第一档调用者。会用现成 API会写 prompt会解析模型输出。说句不客气的话这一档的门槛已经低到几乎不存在了。连 prompt 工程本身都在被快速自动化。这类能力更像是“会用 Excel”撑不起“工程师”这三个字。第二档集成者。会用开源模型、会微调、会搭 RAG知道怎么把模型嵌进现有业务系统。这是目前需求量最大的一批人也是多数教程的目标受众。第三档建造者。能从数据收集、清洗、标注开始自己训练模型自己写推理优化自己搭评测体系自己设计 A/B 实验甚至能改模型结构。到了这一档你才算真正拥有 AI 工程能力。“From scratch”的终极目标是让你成为第三档的人。但路径不是一上来就啃 Transformer 论文——而是从一个端到端的小项目开始把每一环节都亲手做一遍然后逐层加深。我后面会细讲这条路径怎么走。2. 从零起步的能力地基数学、代码与数据三件套很多想转 AI 工程的朋友问我的第一个问题都是同一个“数学不好能学 AI 吗”我的回答是能但你不能永远不好。关键是你需要的那部分数学比很多人想象中窄得多。而且不是靠死啃课本是可以在做项目的过程中补起来的。2.1 到底需要多少数学以及它们真实的使用场景先给结论AI 工程常用的数学就三个板块——线性代数、概率统计、微积分里的梯度优化。注意是“工程中常用的”部分不是数学系课程的完整内容。下面用最具体的例子说明它们到底在哪一步发挥作用你就能理解谁值得好好学。线性代数最典型的应用场景是矩阵乘法。Transformer 的核心注意力机制做的就是 Query 矩阵和 Key 矩阵的乘法得到注意力分数再和 Value 矩阵加权求和——一个标准的矩阵乘加操作。你在 PyTorch 里写的torch.matmul(Q, K.T)背后就是线性代数。当你需要调试显存占用时你得理解一个形状为(batch_size, seq_len, hidden_size)的张量占用多少显存——这就是batch × seq × hidden × 数据类型字节数的乘法问题。不会这些你连 OOM 报错都排查不了。概率统计出现在哪里无处不在。训练集里正负样本比例是 9:1你训练的模型准确率 90%看起来很厉害其实它什么都没学会——它只需要永远预测“负样本”就能拿到这个准确率。这时候你需要的评估指标应该是精确率、召回率、F1 值而这些概念全来自统计。线上监控时你要判断模型延迟的 p95 从 800 毫秒涨到 1.2 秒是不是显著异常这需要一点基本的分布知识。甚至你做数据清洗时发现某个字段有 5% 的缺失率应该直接删掉还是填充这个决策背后也是统计思维。微积分里的梯度下降你不需要会手动求导但你要理解损失函数图上“梯度”是什么意思。训练不收敛的时候学习率调大调小凭感觉吗不是你得理解学习率在 loss 曲线上对应的行为——学习率太大参数更新步长太大loss 可能在最小值附近来回震荡学习率太小收敛慢得让人绝望。这些概念理解了你用wandb看训练曲线时才能看懂应该怎么办。我的建议是线性代数里矩阵乘法和张量形状要扎实概率统计里评估指标和分布要扎实微积分理解个直觉就行。这三件事可以边做项目边补不需要单独闭关三个月刷题。2.2 代码能力别以为“会 Python”就够了写业务代码的 Python 和写 AI 工程的 Python关注点差别非常大。业务代码关注逻辑正确、代码可读、接口清晰AI 工程更关注 CPU/GPU 负载均衡、内存和显存管理、数据 IO 是否成为瓶颈。我这里说三个真实的小例子。第一个是数据加载。大部分初学者写训练脚本时喜欢把所有数据一次性read()进内存然后for epoch in range(10)跑训练。数据量小没事数据量一上来——比如几十 GB 的语料——这种写法直接撑爆内存。标准的做法是用torch.utils.data.DatasetDataLoader设置合适的batch_size和num_workers让数据加载和 GPU 计算并行起来。这算入门基础但很多人一开始就是这么写的谁没爆过几次内存呢。第二个是显存管理。PyTorch 训练中常见的CUDA out of memory报错Debug 起来有一套方法论先检查模型本身占了多少显存再算一算单条数据经过网络各层后的中间张量大小然后调节batch_size到合适值。如果调小 batch 还是爆可能是模型里某个操作导致显存峰值异常——比如在很长的序列上用全局注意力或者做超大 batch 的矩阵乘法。这一套排查逻辑没有工程经验的人真的处理不来。第三个是 profiling。很多人觉得训练慢就加机器实际上很多时候瓶颈根本不在 GPU而是数据预处理卡在 CPU 上GPU 一直在空等。用torch.profiler跑一次你会发现每个操作的真实耗时分布很多问题一查一个准根本不值得“花钱上卡”。2.3 数据能力模型的天花板由数据决定这是我想最用力强调的一点。随便去问一个做了三年以上 AI 工程的老人他最重视的环节是什么大概率回答不是模型结构不是调参技巧而是“数据质量”。数据科学界有句老话叫“garbage in, garbage out”——垃圾进垃圾出。模型结构再先进喂进去的数据乱七八糟结果就是乱七八糟。“数据质量”具体包含哪些事我按轻重缓急给你排个序。第一是数据量。深度学习的“深度”是建立在大量数据之上的。几万条样本可能训练一个小模型做演示但真要一个能扛住真实场景的模型数据量往往需要几十万甚至上百万级。当然数据量不是唯一的因素但“从零训练”时它是最基础的。第二是数据覆盖面。单量多、但集中在少数几种模式上模型照样学不好。比如做多语种翻译100 万条语料里 99% 是英文模型对法语的翻译就会一塌糊涂。这在数学上就是“训练分布”和“推理分布”不匹配的问题。做小样本场景时选数据比造数据更重要。第三是数据噪声。真实业务拿到的数据一定是有错误的标注错误、重复样本、残缺字段、格式混杂。它们会直接把模型带偏。我在合同审核项目里亲眼看过因为训练数据里有一些“金额”字段格式不统一有的带逗号、有的带币种符号、有的是大写中文模型输出的金额格式也是五颜六色的后来我写了专门的清洗脚本把所有金额统一成“数字币种代码”才算解决。从工程角度讲数据是整个 AI 系统里最值得投入时间的部分。一个优秀的数据处理管线应该做到输入原始数据输出格式干净、覆盖充分、分布可控的训练集和测试集。这个过程中的清洗逻辑、过滤规则、抽样策略本身就是可以长期复用的工程资产。3. 亲自动手训练第一个模型从零到 loss 下降的完整过程理论讲再多都不如跑通一个端到端的项目来得实在。这节我带你做一个最经典的入门项目垃圾邮件分类。选择这个项目的原因有三个数据集好找、模型规模小一台普通电脑就能训练、评估指标直观。但我们的目的不是“会做一个垃圾邮件分类器”而是通过这个过程理解 AI 工程从头到尾的各个环节。3.1 项目设计与数据集准备项目目标是给定一封邮件的文本内容判断是正常邮件ham还是垃圾邮件spam。第一步是找数据。Hugging Face Datasets 上有现成的sms_spam数据集大概 5500 多条短信量不大但做入门足够。用下面的代码就能加载from datasets import load_dataset dataset load_dataset(sms_spam) print(dataset) # 输出会显示 train split包含 label 和 text 两个字段加载完数据先别急着训练。花一点时间做所谓的“数据探索”EDA这一步很多人跳过但我觉得这是最简单的提升技术品味的方式import pandas as pd df dataset[train].to_pandas() print(df[label].value_counts()) # 大概率会看到 spam 和 ham 的比例大约 1:4 左右这就是类别不均衡的开始 print(df[text].str.len().describe()) # 看看文本长度的分布决定后续最大序列长度怎么设这是第一个“工程决策”发生的时刻。我看到样本不平衡就知道后面评估模型时不能只看准确率——因为无脑预测“正常邮件”也能拿到 80% 的准确率。选择用什么指标是每个 AI 工程师的第一课。3.2 从零训练还是用预训练模型工程选型的核心权衡这里有个必须做的决策也是 AI 工程从零路径上最重要的一次选型是用 TF-IDF 机器学习分类器朴素贝叶斯、逻辑回归还是用预训练语言模型微调还是从零训练一个小型 Transformer我的建议是入门阶段先做 TF-IDF 逻辑回归这个方案足够优秀训练极快而且能帮你建立对“特征工程”的理解。做完这个之后再用预训练模型微调体验一下从“手工特征”到“自动特征”的跃迁。这个对比体验比看十篇论文都管用。TF-IDF 的做法非常简单把文本转成词频向量过滤掉停用词然后丢给逻辑回归分类器。你用scikit-learn几十行代码就能完成from sklearn.feature_extraction.text import TfidfVectorizer from sklearn.linear_model import LogisticRegression from sklearn.pipeline import Pipeline pipeline Pipeline([ (tfidf, TfidfVectorizer(stop_wordsenglish, max_features5000)), (clf, LogisticRegression()), ]) pipeline.fit(X_train, y_train)跑完这个你会惊奇地发现准确率轻松到 97% 以上。但注意这个准确率有欺骗性——因为数据集不大、任务本身简单你甚至不需要深度学习。这就是我强调“工程选型”的原因并不是所有任务都得用大模型能用低成本方案解决的任务用大模型反而是过度工程。3.3 用 PyTorch 从零训练一个小型神经网络的完整脚本接下来上点硬菜。我们用 PyTorch 从零搭一个朴素的小型神经网络——不加载任何预训练模型只用一个 Embedding 层 一个简单的分类头手动完成从词表构建到训练的全过程。这个过程能让你彻底搞懂“模型训练”这件事的内部结构。import torch import torch.nn as nn import torch.optim as optim from torch.utils.data import DataLoader, Dataset # 1. 构建词表 def build_vocab(texts, min_freq2): from collections import Counter counter Counter() for text in texts: counter.update(text.split()) vocab {pad: 0, unk: 1} for word, freq in counter.most_common(): if freq min_freq: vocab[word] len(vocab) return vocab # 2. 定义数据集 class SpamDataset(Dataset): def __init__(self, texts, labels, vocab, max_len64): self.texts texts self.labels labels self.vocab vocab self.max_len max_len def __len__(self): return len(self.texts) def __getitem__(self, idx): tokens self.texts[idx].split()[:self.max_len] ids [self.vocab.get(w, self.vocab[unk]) for w in tokens] ids ids [self.vocab[pad]] * (self.max_len - len(ids)) return torch.tensor(ids), torch.tensor(self.labels[idx]) # 3. 定义模型 class TinySpamClassifier(nn.Module): def __init__(self, vocab_size, embed_dim64, num_classes2): super().__init__() self.embedding nn.Embedding(vocab_size, embed_dim, padding_idx0) self.classifier nn.Sequential( nn.Linear(embed_dim, 32), nn.ReLU(), nn.Linear(32, num_classes), ) def forward(self, x): # x shape: (batch, seq_len) embedded self.embedding(x) # (batch, seq_len, embed_dim) pooled embedded.mean(dim1) # 很朴素的池化平均所有 token 的向量 logits self.classifier(pooled) # (batch, num_classes) return logits # 4. 训练循环 def train(): device torch.device(cuda if torch.cuda.is_available() else cpu) vocab build_vocab(X_train) train_dataset SpamDataset(X_train, y_train, vocab) train_loader DataLoader(train_dataset, batch_size32, shuffleTrue) model TinySpamClassifier(len(vocab)).to(device) optimizer optim.Adam(model.parameters(), lr1e-3) criterion nn.CrossEntropyLoss() for epoch in range(5): total_loss 0 for batch_ids, batch_labels in train_loader: batch_ids batch_ids.to(device) batch_labels batch_labels.to(device) optimizer.zero_grad() logits model(batch_ids) loss criterion(logits, batch_labels) loss.backward() optimizer.step() total_loss loss.item() print(fEpoch {epoch1}, Loss: {total_loss / len(train_loader):.4f})这段代码看着短但它几乎包含了训练一个模型所需的全部环节。我强烈建议你逐行读通它——理解embedding是什么、forward里数据形状的变化过程、loss.backward()做了什么。把这几十行代码吃透比刷十节深度学习课程打的基础都扎实。跑这个脚本时你会看到 loss 从最初的 0.69 左右因为二分类随机初始化逐轮下降。这就是“训练”的感觉。你会亲眼看到一条 loss 曲线下降、模型从完全随机到能分对垃圾邮件的全过程——这是调 API 永远体会不到的。这一课的本质不是“我会做垃圾邮件分类了”而是“我对一次完整训练的所有环节都有了掌控感”。3.4 评估阶段别让准确率骗了你训练完评估这一步是重中之重。用测试集来评估不能用在训练集上沾过的数据。还是上面说的类别不均衡下准确率会上天入地地欺骗你。正确做法是同时看混淆矩阵、精确率、召回率、F1from sklearn.metrics import confusion_matrix, precision_score, recall_score, f1_score y_pred pipeline.predict(X_test) cm confusion_matrix(y_test, y_pred) print(cm) # 行是真实标签列是预测标签 # [[TN, FP], # [FN, TP]] print(fPrecision: {precision_score(y_test, y_pred):.3f}) print(fRecall: {recall_score(y_test, y_pred):.3f}) print(fF1: {f1_score(y_test, y_pred):.3f})垃圾邮件场景里漏掉一封垃圾邮件召回率低的代价是用户被骚扰误杀一封正常邮件精确率低的代价是用户收不到重要邮件。两种错误的代价不一样你要根据业务去权衡你应该优先优化哪个指标。这个“根据业务选择指标”的思路是 AI 工程里一直贯穿始终的。4. 从“能跑”到“能用”推理性能优化的那些硬指标模型训练完成了得意洋洋地部署上线结果生产环境给你上强度了——单次推理 200 毫秒QPS 要求 50当前并发一上来就超时。这就是我合同审核项目真实经历到的上一课模型在离线评估里表现好和生产环境“能用”是两码事。你需要做推理优化。4.1 先分清延迟和吞吐这两个完全不同的优化方向推理性能优化第一件事是搞清你要优化哪个指标。延迟latency是指单个请求从发出到收到响应的总时间吞吐throughput是指系统每秒能处理的请求数量。这两个目标经常是互斥的。举个例子为了提升吞吐你可以把多个用户请求拼成一个 batch 送进 GPU 推理这叫“动态 batching”。单个请求可能因为要等 batch 凑满而多等几十毫秒延迟会变差但每个 GPU 计算单位内处理的请求数量大幅提升吞吐飙升。如果你做的是一个企业级客服系统用户等 1 秒和等 2 秒感受差别不大用动态 batching 把吞吐拉高是划算的如果你做的是自动驾驶的实时目标检测延迟每多 100 毫秒都可能出事那你就该牺牲吞吐保住这条延迟底线。我之前整理过一张优化手段对照表贴在这里优化手段主要收益成本/风险适用场景量化INT8/INT4显存减半、推理提速少量精度损失、需要校准数据大规模推理、GPU 资源紧张动态 Batching吞吐大幅提升单请求延迟可能上升高并发对话机器人、批量内容审核前缀缓存KV Cache相似前缀请求延迟大幅下降增加显存占用、需要命中率多轮对话、长文档问答模型蒸馏模型变小、推理变快训练成本高、质量可能下降对质量要求高、用大模型蒸馏小模型算子融合优化TensorRT 等延迟降低 20-50%部署复杂度增加、平台绑定对延迟敏感、固定硬件环境4.2 量化用一点点精度换一大截速度量化是目前推理优化里最常用也最立竿见影的技术。它的本质是把模型权重从 FP1616 位浮点数每个数字占 2 字节压缩到 INT88 位整数每个数字占 1 字节显存占用直接减半计算速度通常也会明显提升。但量化不是白拿的。INT8 的数值表达能力远不如 FP16直接把权重截断会导致模型输出质量下降。所以业界有一种叫做“校准”的流程用一批有代表性的数据跑一遍模型统计每一层激活值的分布范围然后把量化的缩放参数设到合适的值让精度损失最小。我的实测经验对大部分任务INT8 量化的质量损失在 1%-3% 之间对用户基本无感INT4 会损失更多一般用在对话模型这类对单 token 精度不敏感的生成任务上。有一个很实用的建议量化后的模型必须跑一遍评测集对比质量不能直接上生产。你可以在自己的垃圾邮件分类器上用torch.quantization试一把看看指标掉了多少。4.3 前缀缓存用空间换时间的买卖值不值前缀缓存是 RAG 应用里最容易被忽视的一环。想象一个场景用户打开一个 AI 合同审核问答页面发给后端的问题是“合同里关于违约金的条款是什么”“违约金上限是多少”“如果我提前解约怎么算”——这三个问题的前缀都是“你是合同审核助手请根据以下合同内容回答问题[合同全文]”。这一段系统提示词加合同全文可能有几千个 token。每次请求都要把这几千个 token 重新跑一遍 Transformer 的前向计算计算量巨大。前缀缓存KV Cache的思路是把相同前缀第一次计算得到的注意力中间结果KV 矩阵缓存下来后续请求直接复用这部分结果只需要计算用户新问题的部分。这招在一个知识库问答场景里能省下 60%-80% 的推理开销。但它的代价是显存——缓存掉的 KV 矩阵是很大的张量占用显存。命中率低了缓存放着吃灰你需要用实际请求数据分析哪些前缀是热门的、缓存设多大合适。这个“衡量缓存收益和代价”的思考方式就是工程思维本身。4.4 一个完整的推理优化实战流程上面这些手段不是一次性全上的。我把项目实践中的优化顺序整理给你这个顺序已经考虑了投入产出比和风险控制先量化到 INT8重跑评测集确认质量无损或可接受——这一步通常能拿到 40% 的提速。用 vLLM 这类支持动态 batching 和前缀缓存的开源推理引擎替换最朴素的部署方式。自己写推理服务不考虑 vLLM 简直是对 GPU 的不尊重——它能自动把并发请求拼 batch能把相同前缀缓存住一行配置都不用改。再上一个监控面板把延迟、吞吐、显存占用、GPU 利用率全部可视化。没有监控的优化是盲人摸象——你不知道瓶颈到底在哪优化就全凭感觉。最后才考虑模型蒸馏——这是成本最高的手段需要重跑训练所以放在最后确认前几步优化不够再做。这个过程里最重要的习惯是每做一步优化就跑一次评测集做对比。没有评测的优化是耍流氓。5. AI 工程落地的最后三公里评测、监控与持续迭代模型训练完、推理优化完、服务上线了很多团队松一口气觉得大事告成。他们忘了一个 AI 系统的生命周期从上线才真正开始。生产环境的数据分布会漂移、用户行为会变化、你的模型会逐渐“过时”。这时候如果没评测体系、没监控、没有迭代闭环就会变成“模型坏了也不知道知道坏了也不知道怎么坏”的被动局面。5.1 评测体系AI 工程的“自动化测试”你可能觉得传统软件工程里的自动化测试和 AI 没关系——模型是概率性的没法写断言。但实际上AI 工程不仅需要评测而且评测体系应该像传统软件工程里的自动化测试那样从一开始就建立、持续维护、作为每次版本迭代的“验收门禁”。做 LLM 应用的人都知道Prompt 刚改了一个词是不是所有场景的效果都变好了很多人靠人工抽几条数据看看得累死还不一定看得出来。正经做法是把一批固定的测试用例业内叫“golden set”固化下来。比如客服机器人项目里准备 200 条高频问题涵盖退款、物流、售后、投诉等场景每条问题标注期望的回答要点。每次改 prompt 或换模型版本都跑一遍这 200 条计算通过率。通过率下降说明改坏了通过率上升说明改好了。这就是把工程思维引入 AI 应用的典型方式。大语言模型的评测还可以做得更自动化。对“开放性”回答质量的评估可以让一个强大的模型比如 Claude、GPT-4当裁判——把模型输出和人类标注的参考答案一起发给裁判模型让它打分。这个做法叫 “LLM-as-a-Judge”。但要用好它有一些坑裁判模型对回答顺序有偏好、对详细程度有偏好、对自家模型的输出可能偏袒。解决方案是把正反顺序对调各评一次或用多个裁判模型取平均。这些都是实践中摸出来的经验。5.2 线上监控别等用户骂了才知道模型出问题评测集是线下防线线上防线靠监控。AI 服务的监控指标跟传统服务有相同之处也有独有的部分。我把线上监控指标按优先级整理了这么几个梯度第一梯度基础服务指标。服务存活、平均延迟、P95/P99 延迟、错误率、QPS。这些任何一个后端服务都需要。第二梯度模型专属指标。Token 吞吐量每秒生成多少 token、首 token 延迟用户感知的“转圈圈”时间、请求队列长度、GPU 显存利用率。这些帮助定位是“服务问题”还是“模型推理问题”。第三梯度业务效果指标。用户对回答点“赞”还是“踩”、对话是否被用户主动中断、转人工率有没有上升、搜索后是否换问题重问。这些指标和模型离线评测的结果可能天差地别它是模型真实的业务价值。实际上监控告警有一个很常见又很隐蔽的坑某天新版本模型发布后用户反馈变差但技术层面所有指标全部正常——延迟没变、错误率没变、服务稳定。为什么因为“回答质量变差”不会触发任何基础设施监控指标。这个问题的解法就是上面说的第三梯度业务效果指标。你在设计系统架构时就要为模型质量监控留好埋点。比如客服机器人在回复后加一个“这个回答有帮助吗”的点赞/点踩按钮再在主流程里把点击数据落库用这些数据绘制时间序列搭配告警。这样模型质量变差技术上才有感知的抓手。5.3 数据回流让 system 进化的数据闭环评测和监控发现 bad case 之后怎么办这就是数据回流机制的价值所在。一个成熟的 AI 系统数据流要循环起来生产日志用户输入、模型输出、用户反馈 - 筛选找出 bad case - 人工标注修正正确输出 - 补充到训练集/评测集 - 重新训练/微调 - 重新评测 - 新版本上线。这个闭环里每一步都需要工程支持。以客服机器人项目为例。用户问“我的包裹什么时候发货”模型回答“您的包裹已发货预计三天后到达。”结果用户回了一句“我问的是发货时间不是预计到达时间”——这是非常典型的 bad case因为模型答非所问。这类样本被筛选出来后人工修正为“您可以在订单详情页看到发货时间通常在下单后 24 小时内发货。”然后进入训练集。下一版模型再遇到类似问题时就能给出更准确的回答。这里有一个非常核心的工程原则人工标注的样本要同时进训练集和评测集但必须保证评测集里的样本不参与训练。如果评测集里混入了训练样本评测指标就会虚高相当于考试时偷看了答案。我和团队刚做数据闭环时踩过这个坑——评测集偶尔出现训练样本好长一段时间效果良好直到一次全面排查才发现。从那以后我们用一套基于样本哈希去重的逻辑每次训练都自动剔除与评测集重复的数据。这个数据闭环做完你手里的模型就不再是“训练一次用一辈子”的一次性产品它变成了一个有持续进化的生命体。这才是 AI 工程和传统软件开发最不一样的地方传统代码是写出来就定型的AI 系统是你得养着的。6. 我的“从零到一”路线图与最后的几句实在话很多人看完上面的内容会问同一个问题“我该按什么顺序学这些”如果我现在要从零开始重走一遍我的安排会是这样。我觉得先给你路线图再给你几句我吃过亏才总结出来的实在话。6.1 建议的 12 个月路线图这个路线图按阶段划分每阶段有明确目标和产出物不需要一次性把所有理论全学完而是每阶段通过项目着你往前走。阶段时间核心目标实践产出基础补全第 1-2 月Python 处理数据基本功、入门矩阵/概率统计独立写爬虫/数据处理脚本框架上手第 3-4 月吃透 PyTorch 张量操作和自动求导机制用 PyTorch 从零实现线性回归和 MLP第一个 NLP 项目第 5-6 月跑通分类任务全流程完成本文的垃圾邮件分类项目并写技术报告模型原理深入第 7-8 月理解 Transformer 结构内部机制用 PyTorch 从零实现简化版 Transformer工程化阶段第 9-10 月部署、优化、监控把上面的模型部署成 API做量化优化、加日志和监控综合项目第 11-12 月整合所有能力做一个 RAG 客服机器人数据 向量检索 LLM 评测 数据回流这个路线图的底层逻辑是每个阶段都要有“亲手实现”的环节。不是看视频不是读博客而是真的动手写代码、跑通、出结果。“看会”和“做会”之间的差距比你想象的大得多。6.2 那些没人教你的“工程经验”最后分享几条实在话都是我踩过坑之后才懂的。第一条数据质量永远比模型结构重要。同一个模型用干净的数据训练效果可能比用先进模型配脏数据还好。遇到模型效果不好先查数据再看模型这两个顺序不能反。第二条评测集要先于模型存在。在训练第一个模型之前最好先把评估方案设计好——用什么指标、多少测试样本、覆盖哪些边界情况。没有评测标准的训练就是在迷雾里开车。第三条不要一上来就上大模型。如果你用朴素贝叶斯和 TF-IDF 就能到 95% 准确率的任务硬上 BERT 或者 GPT 纯属给自己找麻烦。选型时要考虑成本、延迟、可维护性模型的复杂度只有和任务的复杂度匹配时才是工程上最优的。第四条记录实验记录一切。每改一个参数、每换一个模型、每调一次 prompt都应该有实验记录。我用的工具是wandb但哪怕你用一个 Excel 表格记录几个关键参数的组合和效果也比“全都靠记忆”强一百倍。你永远不知道哪次改动的组合会突然带来效果飞跃等你需要回溯时没有记录就只能拍大腿。从“调 API 就算做过 AI”到“能独立从零搭一个 AI 系统”这条路没有捷径。但只要你亲手写完一个项目把数据、训练、评估、部署、监控的每一个环节都摸过一遍你就会发现后面的路越走越宽。AI 工程能力的护城河不是知识本身而是那些花了无数次失败才换来的手感。希望这篇长文能帮你少踩几个我踩过的坑——如果看的过程中有哪个环节特别想聊按照文章里的步骤先动手做做完遇到的疑问才是有价值的疑问。
返回列表