1. 为什么AI工程成了比“会调模型”更值钱的技能
这两年有个现象很有意思:会训练模型的人渐渐不那么稀缺了,稀缺的是能把模型真正用起来、跑起来、扛住线上流量的人。打开招聘网站,AI应用开发工程师、AI工程化岗位的需求量肉眼可见地在涨,薪资也在往上走。这背后的逻辑其实不复杂——企业不缺demo,缺的是能落地的产品。把一个模型从Notebook里搬到生产环境,中间隔着数据清洗、推理优化、服务封装、部署运维一整套链路,这条路走通的人,才是市场真正抢着要的。
我见过太多“模型跑得通、服务起不来”的团队。模型精度刷到90%以上,结果一上线上QPS一高就崩,或者接口延迟动不动三四秒,业务方直接劝退。问题出在哪?出在很多人没把“AI工程”当作一个完整的学科来对待,只盯着模型本身,忽略了模型之外的工程环节。
这套技能图谱,我想按实际工作流的顺序来梳理,从环境准备、模型选型,到代码构建、服务封装,再到部署上线和后期迭代,每个环节讲清楚要掌握什么、为什么需要、有哪些坑。目标读者是正准备入行AI应用开发的工程师,或者已经在做算法、想往工程方向延伸的朋友。这篇文章不做那种“一键跑通”的教程,而是帮你建立起一套完整的工程思维框架。
2. 构建AI应用的前置条件:环境、数据和模型选型
2.1 环境准备——本地依赖和镜像构建的坑
先说环境。大部分AI应用开发的第一步,就是把本地依赖装好。这个环节看起来简单,实际上翻车率极高。PyTorch、CUDA、cuDNN、Python版本之间互相打架,是每个AI工程师的日常噩梦。我建议从一开始就养成两个习惯:第一,所有项目都用虚拟环境隔离依赖,conda和venv都行,别嫌麻烦;第二,把依赖版本锁死,requirements.txt里精确到小版本号,别用>=这种模糊写法。
顺便说一句,深度学习版本的CUDA和PyTorch之间的匹配关系,一定要去官网查对照表,不要想当然。我以前遇到过CUDA 11.8配了编译期默认的PyTorch,结果跑起来直接报undefined symbol错误,查了半天才发现是CUDA runtime版本不匹配。
等本地验证通过,下一步就是容器化。Dockerfile构建镜像这事儿,看着简单,里面全是细节。我见过好几个项目,镜像体积动不动就上GB,构建一次等十分钟。优化思路无非几条:
- 选择合适的基础镜像,
python:3.10-slim比python:3.10体积小一大截,GPU环境用nvidia/cuda官方镜像对应的runtime版本,别用devel版本,除非你要编译自定义算子; - 把依赖安装和代码拷贝分成两个层,
COPY requirements.txt先执行RUN pip install,再COPY代码,这样代码改动不会触发依赖重装,利用Docker的层缓存能省大量构建时间; - 多阶段构建,编译阶段用完整镜像,运行阶段只拷产物。
2.2 数据准备和构建知识库——从RAG到GraphRAG
AI应用和传统软件最大的区别在于,AI的效果上限是数据决定的。本地部署大模型时,如果要用私有知识库,最常见的技术方案就是RAG(检索增强生成)。
RAG的核心流程不复杂:把文档切块、向量化、存入向量数据库,用户提问时检索相关内容拼进Prompt,再送给大模型生成答案。但这里面有大量工程细节。切块大小怎么定?我实测下来,中文场景512到1024个字符左右比较合适,太长检索精度下降,太短上下文碎片化。Embedding模型怎么选?BGE系列、M3E这些都是中文场景下比较稳的选择,别张口就用OpenAI的embedding,国内业务数据和合规都会出问题。
真正进阶一点的做法,是用知识图谱替代或补充向量检索。构建知识图谱的流程是:实体识别、关系抽取、属性提取,然后存入图数据库(Neo4j是社区里最常用的)。这个方案的优点是能回答多跳问题,比如“A公司的供应商里,哪些同时和B公司有合作”,这种问题靠向量检索基本答不了。缺点也很明显——构建和维护成本高,实体识别的准确率直接影响下游效果。农业、医疗、法律这类专业领域,聪明的做法是“向量检索为主,图谱辅助”,兼顾效果和成本。
2.3 模型选型——本地部署还是调用API
这是每个AI应用项目都要做的第一个决策。我见过不少团队,一上来就追求大参数模型,结果部署成本爆炸,推理延迟高到没法用。选模型这事,得基于具体场景倒推。
如果是To C的聊天助手,对延迟要求高,QPS波动大,本地部署一个7B、13B的模型,用vLLM或TensorRT-LLM做推理加速,单卡A10就够扛了;如果是企业内部的知识问答,数据不能出内网,那就必须本地部署,这时候推理框架的选择就很关键;如果业务刚起步、调用量不确定,直接用API先跑通业务闭环,再根据用量考虑要不要私有化部署,这才是合理节奏。
现在本地部署大模型的主流工具,Ollama算是最省心的一个。一条命令就能把模型拉起来,OpenAI兼容的接口格式,配合FastAPI写业务逻辑非常顺滑。但Ollama更适合开发调试和小规模部署,真到生产环境,vLLM的吞吐量和并发控制能力还是更可靠。我看过一份压测数据,同样一张A100上,vLLM的吞吐量能做到Ollama的3到5倍,这个差距在线上就是实打实的成本差距。
3. AI应用开发的核心:从模型到服务的最后一公里
3.1 用FastAPI和SQLAlchemy构建高性能后端
模型本身不产生价值,被调用才产生价值。把模型包成服务,FastAPI是当前AI工程领域事实上的标准选择。为什么是FastAPI而不是Flask或Django?三个理由:
第一,异步原生支持。大模型推理本身就是IO密集型的,同步框架会阻塞worker线程,FastAPI的async/await机制能让你在等待模型推理时同时处理其他请求,资源利用率不是一个量级。
第二,自动生成OpenAPI文档。前后端联调时,Swagger UI直接可点可测,省掉大量沟通成本。
第三,Pydantic的数据校验。请求参数在入口就做了类型校验,非法输入根本进不到业务逻辑层,这在模型服务这种对输入格式敏感的场景里简直救命。
SQLAlchemy在AI应用里的角色,是管理业务数据的ORM框架。用户信息、调用记录、任务状态这些结构化数据,用SQLAlchemy定义模型、做迁移,比手写SQL要规范和高效得多。我个人习惯是SQLAlchemy 2.0的Declarative风格,配合Alembic做数据库迁移,表结构变更可控可回滚。
3.2 构建和测试的基本功——别让构建拖垮迭代速度
很多AI项目翻车不是翻在模型效果,而是翻在工程基建。这里说的“构建”不仅仅是代码编译,包括代码的构建、测试、集成,也就是CI/CD流水线。我接触过的AI团队里,极少有把CI/CD做扎实的,最典型的表现是“本地能跑就万事大吉”。
以Java Web项目为例,Maven或Gradle是标配构建工具,但很多AI项目是Python写的,那就需要用Poetry或uv来管理依赖和构建。Poetry的lock文件能保证开发、测试、生产环境依赖完全一致,这一点对AI项目的可复现性至关重要。
测试这一环,AI应用比传统应用多了一个维度:不光要测代码逻辑,还要测模型效果。代码层面,pytest是基础,接口测试用TestClient模拟请求,验证状态码、响应格式和延迟指标;模型层面,要有独立的评测集,每次迭代都要回归跑一遍,防止模型效果回退。我在实际开发中会加一个“冒烟测试”环节——部署前用固定的测试用例集做一次快速验证,通过才允许上线,这套机制帮我拦截了至少五次线上事故。
3.3 把模型服务封装成可复用的工程组件
模型封装这事儿,新手和熟手的差距巨大。新手通常把模型加载、预处理、推理、后处理全写在一个函数里,看着方便,改起来痛苦。我推荐的模式是分层封装:
- 模型层:只负责权重加载和
forward调用,不关心输入是什么格式; - 服务层:负责请求解析、参数校验、调用模型层;
- 业务层:负责Prompt组装、后处理逻辑、调用外部工具。
这三层之间用接口隔离,每一层都能单独测试和替换。比如业务层要改Prompt模板,根本不需要动模型层的代码;模型要从A换成B,只要接口兼容,服务层和业务层完全不用改。
这里还涉及一个很多人忽略的点——模型的“工程化”不是把模型文件存下来就行。做AI应用开发,你迟早要面对“模型版本管理”的问题。模型文件动辄几个GB,塞进Git不现实,我的方案是把模型元信息(版本号、训练数据描述、精度指标、关联代码commit)记在数据库或配置文件中,模型文件本身走对象存储或专门的模型仓库(如MLflow)。
4. 部署:AI应用上线的关键一环
4.1 推理服务部署——从本地到生产环境
部署是整个AI工程链路里最考验综合能力的一环。前面说的本地能跑、测试通过,都不代表能部署上线。生产环境要面对的是并发、延迟、资源和稳定性四个维度的问题。
部署方式上,我推荐先把服务容器化,然后用Docker Compose在单机上编排,等规模上去了再引入Kubernetes。很多人一上来就上K8s,结果复杂度直接压垮团队。我见过一个团队,三个人维护一个K8s集群,光踩坑就踩了一个月,最后又退回Docker Compose。合理的演进路线是先单机、再集群,别一步到位。
GPU资源的分配是另一个大坑。一块GPU共享给多个服务用,NVIDIA MPS或MIG都是方案,但性能和隔离性的取舍需要实际测试。最稳妥的做法是一个服务独占一块GPU,等业务量级确实上来再考虑共享。
4.2 用vLLM或Ollama承载本地模型推理
本地部署大模型这两年最大的进展,就是推理框架的成熟。Ollama把部署门槛降到了极低,几行命令就能跑起一个对话模型,对开发者友好到无脑。但生产环境我强烈建议用vLLM做推理引擎。原因有三个:
- PagedAttention——显存管理机制,能显著提高GPU利用率,同样一张卡能跑的并发请求数翻倍;
- Continuous Batching——动态拼批,推理吞吐量远高于静态批处理;
- OpenAI协议兼容——前端和业务代码可以直接复用,无缝切换。
部署DeepSeek这类重量级模型时,这些特性的差距会被放大得非常明显。DeepSeek-V3这种671B参数的MoE模型,没有vLLM级别的推理框架,想在消费级硬件上跑起来几乎不可能。硬件上A100、H100这种旗舰卡当然好,但实际部署中更常见的是A10、A30这一档的中端卡,这时候推理框架的选择比显卡本身更影响性能表现。
4.3 部署到GitHub Pages或服务器——经典方案复盘
部署这个主题,想多说两种典型场景。第一种是个人项目或文档站,目标平台是GitHub Pages,静态托管、免费、省心。配合Hexo或VuePress这类静态站点生成器,写Markdown、执行构建、推送代码,GitHub Actions自动触发部署,整套流程不到半小时就能配好。第二种是正式业务,目标平台是自己的服务器或云主机,Nginx做反向代理和负载均衡,HTTPS证书用certbot一键签发,数据库单独容器,应用容器通过内部网络访问数据库,这是目前中小型AI应用最稳的架构。
两种场景的部署细节差异很大,但核心原则是共通的:部署流程必须可重复、自动化、可回滚。手动在服务器上敲命令部署,一次两次可以,时间长了必然出问题。哪怕用最基础的脚本把部署步骤固化下来,也比手工强一百倍。
5. 实际项目中的踩坑实录与排查方法
5.1 常见部署问题速查表
按我自己在这些项目里踩过的坑,整理了一份排查速查表,覆盖面比较广,希望对大家有帮助。
| 症状 | 可能原因 | 排查思路与解法 |
|---|---|---|
| 服务启动报“CUDA out of memory” | 模型加载时显存占用过高,或推理框架显存管理不当 | 先确认模型精度(FP16/BF16),用nvidia-smi监控显存占用,考虑开启vLLM的--gpu-memory-utilization参数限制显存使用 |
| 接口响应很慢(超过3秒) | 未使用推理加速框架、并发处理不当、模型本身太大 | 确认是否用了vLLM或TensorRT-LLM加速,检查GPU利用率是否跑满,必要时升级推理引擎或做模型量化 |
| 容器内GPU不可用 | Docker未配置GPU runtime | 安装NVIDIA Container Toolkit,启动容器时加--gpus all参数 |
| 模型效果和本地不一致 | 服务端和本地tokenizer版本不一致,或推理参数(temperature等)设置不同 | 逐个字段比对服务端和本地的推理参数,确保tokenizer文件一致 |
| 请求量一大就502 | 服务崩溃或worker进程数不足 | 看日志定位是否OOM或线程死锁,用Gunicorn/FastAPI的worker数量设置结合压测结果调优 |
| 数据库连接池耗尽 | SQLAlchemy连接池配置过小 | 调大pool_size和max_overflow参数,同时排查代码中是否有连接泄漏 |
5.2 推理性能优化的三个实操方向
部署之后,最常做的事就是性能调优。我梳理了三个性价比最高的方向。
第一是模型量化。把FP16降成INT8或INT4,显存占用直接减半甚至更多,推理速度也能明显提升。代价是精度损失,但这个损失在大多数业务场景下是可以接受的。我用过GPTQ和AWQ两大量化方案,AWQ在同样的压缩比下质量损失更小,AGI时代的工程经验基本一致。
第二是并发参调。很多人以为并发越高越好,实际上当并发请求太多时,推理系统会陷入资源争抢,反而拖慢单个请求的响应速度。vLLM的max-num-seqs参数和FastAPI的worker数量需要联动调整。我的调试方法是:用压测工具先打一轮单并发,找到P95延迟,再逐步增加并发,观察延迟变化曲线,找到拐点,把并发控制在拐点附近,既保证吞吐又不至于延迟失控。
第三是Prompt工程优化。这里的优化指的不是效果,而是输入token数量。Prompt越长,每次推理的prefill时间越长,成本越高。把历史对话做裁剪、把知识库检索结果做精简、把系统提示词压缩,都能直接降低推理延迟。有次我把一个系统的历史消息从保留20轮改成保留10轮,P95延迟直接降了35%,这个性价比比换显卡高多了。
5.3 线上问题排查的实战记录
最后分享一次真正的线上事故排查。
某次凌晨两点,告警电话把我叫醒——AI问答服务接口超时率飙到30%。第一反应是看GPU显存和利用率,都正常。再看日志,发现大量超时请求卡在数据库查询阶段。继续排查,数据库的连接池满了,大量连接处于idle in transaction状态,明显是事务没有正确提交导致连接泄漏。翻代码才发现,某个异常分支里,SQLAlchemy session没有做close操作,异常一抛,连接就泄漏了。那次之后,我把所有的数据库操作统一改为依赖注入方式管理session,并在入口处加了全局异常处理器兜底关闭连接。这套改动之后,类似问题再没出现过。
这次事故给我的教训就一句话:AI应用首先是应用,其次才是AI。模型再强,工程基建烂,照样线上崩。
6. 按这条路线,你该怎么一步步学习AI工程
既然聊到这里,我索性把AI应用开发的学习路线也整理出来,给想入门的朋友一条相对清晰的路径。
第一阶段(1-2周):打好后端基础。掌握Python或Java的核心语法,特别是异步编程、装饰器、类型注解这些AI服务开发高频用到的特性。然后用FastAPI写一个简单的CRUD接口,配合SQLAlchemy操作数据库,把HTTP协议和RESTful设计的基本功练扎实。
第二阶段(2-3周):熟悉大模型和AI应用的基本交互模式。了解Prompt Engineering的基本方法,能用LangChain或直接调用API实现一个基础的知识库问答应用。这个阶段的重点是理解RAG的流程和各类参数的作用,别急着上生产。
第三阶段(3-4周):掌握本地模型部署。用Ollama跑起一个开源模型,用FastAPI封装成HTTP服务,再和前端页面打通。然后过渡到vLLM,了解推理加速的底层原理,对比不同推理框架在吞吐量和延迟上的差异。
第四阶段(1-2个月):系统学习部署和运维。Docker容器化、Docker Compose编排、Nginx反向代理、HTTPS配置,这套组合拳要熟练掌握。然后了解Kubernetes的基本概念和常用操作,重点理解Pod、Service、Deployment这三个核心对象。
第五阶段(持续):深入一个垂直场景。农业、法律、医疗、金融,选一个你感兴趣的领域,做一套完整的知识库问答系统。这个过程中会逼着你处理真实场景的数据问题、业务逻辑和部署需求,这才是真正走向资深的路径。
这套路线的核心逻辑是:先跑通,再优化,再深入。很多人卡在第一步就没迈出去,总觉得要先把数学、算法、模型原理全搞明白才能动手,这是最大的误区。AI工程是工程学科,动手做比什么都重要。