1. 从零搭建AI工程能力一个后端老兵的实战复盘这两年“AI工程”这个词被聊得太多但真正动手从零搭一套能跑通、能上线、能维护的AI系统和看几篇科普文章完全是两码事。我做了十多年后端两年前开始把主要精力转到AI工程方向踩过的坑比写过的代码还多。这个项目标题“ai-engineering-from-scratch”我第一眼看到就很有共鸣——它说的不是教你调个API、跑个demo而是从最底层开始把AI工程当作一门正经的工程学科来对待。说白了AI工程的核心不是训练模型而是把模型能力变成可靠的产品功能。这中间涉及数据管道、特征管理、模型服务、推理优化、监控告警、成本控制等一整套工程体系。适合谁来参考如果你是有后端基础、想转AI方向的工程师或者已经在做AI产品但总觉得系统“脆得不行”的开发者这篇内容应该能帮你少走不少弯路。我会从整体设计思路讲到具体实操把每个关键决策背后的“为什么”说清楚最后再分享几个我踩过的坑和排查技巧。2. 整体架构设计与技术选型思路2.1 为什么不能“先跑起来再说”很多人做AI项目的习惯是先拿个开源模型跑通推理然后直接包个HTTP接口就上线。这种做法在demo阶段没问题但一旦流量上来、需求变复杂系统就会变成一团乱麻。我见过太多团队在模型版本管理上翻车——线上跑的是哪个版本的模型、用了哪份数据训练的、推理参数是什么没人说得清楚。所以从零搭建AI工程能力第一步不是选模型而是定架构。我的思路是分层解耦数据层、训练层、服务层、监控层各自独立层与层之间通过标准接口通信。这样做的好处是任何一层换技术栈都不会影响其他层。比如你一开始用PyTorch训练后来想换TensorFlow只要模型导出格式统一服务层完全不用动。具体分层如下数据层负责数据采集、清洗、标注、版本管理。核心工具是DVCData Version Control加对象存储保证每份数据可追溯。训练层负责模型训练、调参、评估。用MLflow做实验跟踪每个实验的代码、参数、指标、产物全部记录。服务层负责模型部署和推理。用FastAPI做接口Triton Inference Server做推理引擎支持多模型、多版本共存。监控层负责性能监控、数据漂移检测、告警。用Prometheus加Grafana做指标可视化Evidently做数据漂移分析。这套架构不是拍脑袋想的是我在实际项目中反复调整后的结果。早期我也试过把所有逻辑塞在一个Flask应用里结果模型更新要重启服务数据漂移了没人知道线上出问题排查全靠猜。分层之后每个环节的职责清晰了排查问题也快了很多。2.2 模型服务选型为什么最终选了Triton模型服务这块我试过三种方案Flask直接加载模型、TorchServe、Triton Inference Server。最后稳定用Triton原因有几个。Flask方案最简单但问题也最明显Python GIL限制并发、没有动态批处理、模型热更新麻烦。TorchServe是PyTorch官方出的功能比Flask强但只支持PyTorch而且配置起来比较重。Triton的优势在于支持多框架PyTorch、TensorFlow、ONNX、TensorRT都行、自带动态批处理、支持模型版本管理和热更新、性能优化做得很到位。举个例子动态批处理这个功能在实际生产中太重要了。假设你的模型单次推理耗时50ms如果不做批处理每秒最多处理20个请求。但Triton可以把多个请求攒成一个批次一起推理比如攒到8个一起跑虽然单次耗时可能变成80ms但吞吐量变成了100请求/秒提升了5倍。这个账算下来GPU利用率上去了成本就下来了。注意Triton的配置文件config.pbtxt是核心里面要定义输入输出维度、批处理策略、实例数量等参数。第一次配的时候容易漏掉dynamic_batching字段导致批处理不生效。2.3 数据版本管理DVC加对象存储的组合拳数据版本管理是AI工程里最容易被忽视的环节。代码有Git管模型有MLflow管但数据呢很多人就是本地存一份改了就覆盖最后根本不知道线上模型用的是哪版数据。我的做法是用DVC做数据版本控制底层存储用S3兼容的对象存储。DVC的原理很简单数据文件本身不进GitGit里只存一个指向数据文件的元数据文件.dvc文件实际数据存在对象存储里。每次数据更新DVC会生成新的哈希值这样就能精确追溯到每个模型版本对应的数据版本。具体操作流程# 初始化DVC dvc init # 添加数据目录 dvc add data/training_set # 推送到远程存储 dvc remote add -d myremote s3://my-bucket/dvc-store dvc push这样每次训练前先dvc pull拉取指定版本的数据训练完把模型和对应的数据版本哈希一起记录到MLflow里。后面排查问题时就能精确复现当时的训练环境。3. 核心模块实操与关键细节3.1 数据管道搭建从原始数据到训练样本数据管道是AI工程的地基。我见过太多项目在数据环节出问题训练时用的数据分布和线上推理时的数据分布不一致导致模型效果大打折扣。这个问题的根源在于数据管道没有做好训练-推理一致性。我的做法是把数据预处理逻辑封装成独立的模块训练和推理共用同一套代码。比如特征工程里的归一化、分箱、缺失值填充这些逻辑在训练时用在推理时也要用而且参数必须一致。如果训练时用均值归一化推理时也要用同一个均值不能重新计算。具体实现上我用Python的pydantic定义数据schema用pandas做批量处理用numpy做数值计算。关键是要把预处理逻辑写成纯函数输入原始数据输出特征向量不依赖任何全局状态。from pydantic import BaseModel import numpy as np class RawInput(BaseModel): user_id: int item_id: int timestamp: float context: dict class FeatureProcessor: def __init__(self, norm_mean, norm_std): self.norm_mean norm_mean self.norm_std norm_std def process(self, raw: RawInput) - np.ndarray: # 特征提取逻辑 features [ raw.user_id % 1000, raw.item_id % 500, (raw.timestamp % 86400) / 86400, ] # 归一化 features (np.array(features) - self.norm_mean) / self.norm_std return features这个FeatureProcessor类在训练时和推理时都实例化参数从配置文件加载保证一致性。实操心得数据管道的每个环节都要加数据质量检查。比如检查特征值是否在合理范围内、是否有大量缺失、分布是否发生偏移。我一般用great_expectations做这件事虽然配置起来有点繁琐但能提前发现很多问题。3.2 模型训练与实验管理MLflow的实战配置模型训练不是跑个model.fit()就完事了。你需要记录每次实验的超参数、指标、产物否则调参就是碰运气。MLflow是我用过最顺手的实验管理工具轻量、易集成、UI也够用。配置MLflow的关键是统一跟踪服务器。不要每个人在本地跑一个MLflow那样实验记录散落在各处没法对比。正确做法是搭一个中心化的MLflow Tracking Server后端存储用PostgreSQL产物存储用S3。# 启动MLflow Tracking Server mlflow server \ --backend-store-uri postgresql://user:passlocalhost:5432/mlflow \ --default-artifact-root s3://my-bucket/mlflow-artifacts \ --host 0.0.0.0 \ --port 5000然后在训练脚本里集成import mlflow import mlflow.pytorch mlflow.set_tracking_uri(http://mlflow-server:5000) mlflow.set_experiment(recommendation-model) with mlflow.start_run(): # 记录超参数 mlflow.log_params({ learning_rate: 0.001, batch_size: 64, epochs: 10 }) # 训练模型 model train_model(params) # 记录指标 mlflow.log_metrics({ accuracy: 0.92, f1_score: 0.89 }) # 保存模型 mlflow.pytorch.log_model(model, model)这样每次实验都有完整记录后面对比不同超参数的效果就方便多了。3.3 模型部署与推理优化Triton配置详解模型训练完只是第一步部署上线才是真正的考验。Triton的配置核心是config.pbtxt文件这个文件定义了模型的输入输出、批处理策略、实例数量等关键参数。一个典型的PyTorch模型配置name: recommendation_model platform: pytorch_libtorch max_batch_size: 32 input [ { name: input__0 data_type: TYPE_FP32 dims: [128] } ] output [ { name: output__0 data_type: TYPE_FP32 dims: [64] } ] dynamic_batching { preferred_batch_size: [8, 16, 32] max_queue_delay_microseconds: 10000 } instance_group [ { count: 2 kind: KIND_GPU } ]这里有几个关键参数需要解释max_batch_size最大批处理大小。设太大显存扛不住设太小吞吐上不去。一般从32开始试根据显存占用调整。preferred_batch_size优先批处理大小。Triton会尽量攒到这个大小再推理。max_queue_delay_microseconds最大排队延迟。设太大延迟高设太小批处理攒不起来。10000微秒10ms是个比较平衡的值。instance_group实例数量。GPU上一般设1-2个太多会争抢显存。注意Triton的模型仓库目录结构有严格要求必须是模型名/版本号/模型文件的格式。比如recommendation_model/1/model.pt。版本号必须是数字Triton会自动加载最新版本。3.4 监控体系搭建Prometheus加Grafana实战AI系统的监控比普通后端系统复杂因为除了常规的QPS、延迟、错误率还要监控模型层面的指标预测分布、特征漂移、模型置信度等。我的监控体系分三层第一层基础设施监控。用Prometheus采集GPU利用率、显存占用、CPU、内存、网络IO。这些指标用Node Exporter和DCGM Exporter采集。第二层服务层监控。在FastAPI里埋点记录每个请求的延迟、状态码、请求量。用prometheus_client库暴露指标。from prometheus_client import Histogram, Counter import time REQUEST_LATENCY Histogram( model_request_latency_seconds, Model request latency, [model_name, version] ) REQUEST_COUNT Counter( model_request_total, Total model requests, [model_name, status] ) app.post(/predict) async def predict(request: PredictRequest): start time.time() try: result model.predict(request.data) REQUEST_COUNT.labels(model_namerec, statussuccess).inc() return result except Exception as e: REQUEST_COUNT.labels(model_namerec, statuserror).inc() raise finally: REQUEST_LATENCY.labels(model_namerec, version1).observe(time.time() - start)第三层模型层监控。这块用Evidently做数据漂移检测定期对比线上推理数据和训练数据的分布。如果漂移超过阈值就触发告警。from evidently.report import Report from evidently.metric_preset import DataDriftPreset report Report(metrics[DataDriftPreset()]) report.run(reference_datatrain_data, current_dataonline_data) report.save_html(drift_report.html)Grafana面板把这三层指标整合在一起出问题时能快速定位是基础设施问题、服务问题还是模型问题。4. 常见问题与排查技巧实录4.1 模型推理延迟突然飙升怎么排查这是最常见的问题之一。我的排查思路是从外到内逐层排除先看服务层指标QPS有没有突增如果有可能是流量上涨导致排队。如果没有继续往下查。看GPU指标GPU利用率是不是满了显存是不是快爆了如果GPU利用率100%说明计算资源不够需要加实例或优化模型。看批处理指标Triton的批处理大小是不是变小了如果请求间隔变大批处理攒不起来单次推理延迟就会上升。看模型输入输入数据的维度是不是变了有时候上游系统改了数据格式导致模型输入变大推理时间自然增加。我遇到过最诡异的一次是GPU利用率不高、QPS也不高但延迟就是高。最后发现是Triton的max_queue_delay_microseconds设太大了请求一直在排队等批处理。把这个值从50000调到10000延迟立刻降下来了。4.2 模型效果线上不如线下怎么办这个问题太常见了原因通常有三个第一训练-推理不一致。训练时用的特征处理逻辑和推理时不一样。比如训练时对缺失值填了0推理时填了-1。这种问题最隐蔽因为代码看起来都对但结果就是不对。解决办法是强制训练和推理共用同一套特征处理代码。第二数据漂移。线上数据分布和训练数据分布不一致。比如训练数据是夏季的用户行为上线时已经是冬季了用户行为模式变了。解决办法是定期用Evidently做漂移检测发现漂移就重新训练。第三评估指标和业务指标不一致。线下用AUC评估线上看点击率两者可能不一致。解决办法是线下评估时就用业务指标或者至少把业务指标作为辅助评估。实操心得我习惯在模型上线前做一次影子测试就是把线上流量复制一份给新模型但不影响实际结果只记录新模型的预测。跑一周后对比新旧模型的效果确认没问题再切换。这个做法虽然麻烦但能避免很多线上事故。4.3 模型版本管理混乱怎么破模型版本管理混乱的典型表现是线上跑的是哪个版本没人知道回滚时找不到旧版本多个模型版本同时在线导致结果不一致。我的解决方案是三件事模型仓库规范化Triton的模型仓库按模型名/版本号/组织版本号用递增整数。每次部署新模型版本号加1旧版本保留。配置中心化管理用一个配置文件记录当前线上使用的模型版本服务启动时从配置中心读取。这样切换版本只需要改配置不需要改代码。回滚自动化写一个脚本一键切换到指定版本。回滚时间从原来的半小时缩短到1分钟。#!/bin/bash # rollback.sh MODEL_NAME$1 VERSION$2 # 更新配置 curl -X POST http://config-center/api/model/version \ -d {\model\: \$MODEL_NAME\, \version\: \$VERSION\} # 通知Triton重新加载 curl -X POST http://triton:8000/v2/repository/models/$MODEL_NAME/load4.4 常见问题速查表问题现象可能原因排查方法解决方案推理延迟高GPU资源不足查看GPU利用率增加实例或优化模型推理延迟高批处理攒不起来查看批处理大小调整max_queue_delay模型效果差训练-推理不一致对比特征处理逻辑统一特征处理代码模型效果差数据漂移运行漂移检测重新训练模型服务崩溃显存溢出查看显存占用减小batch_size版本混乱配置未中心化检查配置文件引入配置中心监控缺失指标未埋点检查Prometheus配置补充埋点代码5. 成本控制与性能优化的实战经验5.1 GPU成本控制的几个关键手段AI工程绕不开成本问题尤其是GPU成本。我总结了几条实战经验第一用竞价实例做训练。训练任务对中断不敏感用竞价实例能省60%以上的成本。配合checkpoint机制实例被回收后能从最近的checkpoint恢复。第二推理用自动扩缩容。流量有高峰低谷没必要一直开着最大实例数。用Kubernetes的HPAHorizontal Pod Autoscaler根据QPS自动调整实例数。第三模型量化。把FP32模型量化成FP16或INT8推理速度能提升2-4倍显存占用减少一半。Triton支持TensorRT量化配置一下就能用。第四请求合并。如果多个请求可以合并成一个批次推理就尽量合并。Triton的动态批处理已经做了这件事但应用层也可以做一层合并比如把多个用户的推荐请求合并成一个批量请求。5.2 性能优化的优先级排序性能优化不能盲目做要有优先级。我的排序是先解决瓶颈用Profiler找到最耗时的环节优先优化。如果80%的时间花在数据预处理上优化模型推理就是白费力气。再优化批处理批处理是性价比最高的优化手段调整参数就能见效。然后做量化量化能显著提升速度但可能损失一点精度需要评估。最后考虑模型裁剪剪枝、蒸馏这些手段效果明显但工作量大放在最后做。实操心得优化前一定要建立基线。记录优化前的QPS、延迟、GPU利用率优化后再对比。没有基线的优化就是瞎猜。6. 从零搭建的完整流程清单如果你现在要从零开始搭建AI工程能力我建议按这个顺序来搭数据管道先把数据采集、清洗、版本管理跑通。数据是地基地基不稳后面全白搭。建实验管理搭MLflow把训练实验管起来。不要等到实验多了再补那时候已经乱了。做模型服务用Triton部署第一个模型跑通推理接口。先跑通再优化。加监控告警Prometheus加Grafana把基础设施和服务层指标监控起来。补模型监控加Evidently做数据漂移检测定期跑报告。做成本优化量化、自动扩缩容、竞价实例一步步来。建回滚机制一键回滚脚本确保出问题能快速恢复。这个顺序不是绝对的但大方向是这样。每一步都有坑但踩过之后系统就稳了。最后分享一个我个人的小技巧每次上线新模型前先跑一遍全链路压测。从数据管道到推理服务完整跑一遍看看每个环节的延迟和吞吐。这个习惯帮我提前发现了好几次配置错误避免了不少线上事故。AI工程这件事说到底就是把不确定性管起来让模型的效果可预期、可复现、可回滚。做到这三点系统就算入门了。
企业数字化 ERP 产品动态
相关推荐
数字货币量化交易:信号处理与多时间框架策略 1. 策略概述与设计思路在数字货币交易领域,高频波动与趋势转换的快速切换一直是量化策略开发的核心挑战。传统趋势跟踪策略往往在震荡行情中频繁止损,而反转策略又容易错过大级别趋势。经过多年实盘验证,我发现结合信号处理技术与多时间框架分… · 2026/11/4 15:23:13
Univer 表格渲染引擎:Canvas 架构与插件化实战 1. 从"univer"这个标题说起:一个被低估的前端表格渲染引擎第一次看到"univer"这个词,很多人会以为是某个新出的编程语言或者云服务品牌。实际上,它是一个开源的在线电子表格与文档协作引擎,核心定位是"把… · 2026/11/4 15:23:13
解决Maven依赖无法识别的缓存问题 1. 问题现象与初步排查 在Java开发中,尤其是使用Maven构建的Spring Boot项目中,我们经常会遇到这样一种情况:明明已经在pom.xml文件中正确添加了依赖,IDE(如IntelliJ IDEA)也能正常下载jar包到本地仓库&… · 2026/11/4 15:23:13
实测Shotgun规格驱动开发:支付系统从3-4周缩短到5天上线,研发时间减少80%的秘诀 【免费下载链接】shotgun Spec Driven Development 🤠 Write codebase-aware specs for AI coding agents so they dont derail. 项目地址: https://gitcode.com/gh_mirrors/shotgun3/shotgun 点击查看 免费下载 为什么 AI 编码代理会"跑偏"&… · 2026/11/4 16:08:58
Trae Agent 错误恢复:任务中断后,如何把丢掉的进度找回来 Trae Agent 错误恢复:任务中断后,如何把丢掉的进度找回来 【免费下载链接】trae-agent Trae Agent is an LLM-based agent for general purpose software engineering tasks. 项目地址: https://gitcode.com/gh_mirrors/tr/trae-agent
让 Trae Ag… · 2026/11/4 16:07:57
signature_pad 签名图片压缩避坑全解 signature_pad 签名图片压缩避坑全解 【免费下载链接】signature_pad HTML5 canvas based smooth signature drawing 项目地址: https://gitcode.com/gh_mirrors/si/signature_pad
上线第一个月,订单系统里用户提交的签名图片平均 200KB,CDN 带宽… · 2026/11/4 16:07:57
X-Policy-Lab:面向机器人策略评估与部署的统一标准与开放生态系统【集成 42 个机器人策略】 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/4 16:07:57
Linux 进程、线程与进程通信核心知识笔记 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/4 16:07:57
前端路在何方?看比特鹰如何培养AI时代的全栈工程师 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/4 16:07:57
双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/4 3:16:49
STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/4 6:59:29
DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/4 7:02:38
AI辅助技术栈评估:提升研发决策效率60% 1. 项目背景与核心价值技术决策一直是研发团队面临的重大挑战。随着技术生态的快速演进,技术栈的选择、维护和迭代变得愈发复杂。我们团队在过去两年里,先后经历了三次重大技术栈迁移,每次都需要投入大量人力进行技术评估和风险分析。直到去年… · 2026/11/4 0:00:17
从生成Token到直接决策:Jev如何重塑AI Agent工程实践 1. 从"生成文字"到"拍板决策":Jev 到底在解决什么问题大多数人第一次接触大模型,脑子里建立的模型是"输入问题、输出文字"。你问它今天天气怎么样,它给你一段描述;你让它写个周报,它给你… · 2026/11/4 0:00:17
32G统一内存跑大模型:内存账、TPS实测与端云分流 想在一台 32G 统一内存的小主机上把大模型跑成"日常可用",这件事我前后折腾了小半年。标题里说的这台 Mac mini M6,是我们这次讨论的目标平台,具体到手规格以实物为准;但下面这套推算方法和实测思路,对任何统… · 2026/11/4 0:00:17
双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/4 3:16:49
STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/4 6:59:29
DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/4 7:02:38