ARTICLE DETAIL

资讯详情

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

AI原生基础设施实战:GPU算力调度与推理服务优化

AI原生基础设施实战:GPU算力调度与推理服务优化 今天正式加入 Dynamia 密瓜智能以后很长一段时间我都会泡在 AI 原生基础设施这条线上。熟悉我的朋友都知道过去几年我主要做分布式系统和云原生架构接过不少训练平台、推理服务的活但这次不是换个公司继续干老本行而是要把“基础设施”这个东西重新拆开站在 AI 的视角再组装一遍。这篇文章就当我的开工笔记把决定加入前后的思考、对 AI 原生基础设施的理解以及最近实操踩出来的经验一并写清楚。如果你也在做模型训练、推理服务或者正在帮团队搭 GPU 算力平台这篇文章应该能给你一些参考。哪怕你现在只是刚接触大模型只要搞明白“算力、存储、网络、调度、服务”这几件事怎么协作后面看任何 AI Infra 相关的方案都会轻松很多。1. 为什么我从“跑模型”转到“AI 原生基础设施”先说结论传统云原生基础设施解决的是“应用怎么跑得稳”AI 原生基础设施解决的是“模型怎么跑得快、跑得省、跑得起”。这俩看起来都是基础设施但底层逻辑完全不同。我过去搭过不少 Kubernetes 集群也帮团队做过微服务改造。那时候的核心关注点是容器的生命周期、配置管理、服务发现、弹性伸缩。一个典型场景是用户请求量涨了HPA 自动把 Pod 从 3 个扩到 10 个流量降了再缩回来。这套体系放在 Web 服务上非常成熟OpenTelemetry、Prometheus、Ingress Controller 一套组合拳打下来基本能覆盖 90% 的运维需求。但放到 AI 场景里这套逻辑立刻露馅Web 请求是无状态的模型推理请求是有状态的。一个模型加载到显存里可能要几十秒甚至几分钟Pod 副本数随便扩容没有任何问题但模型副本不能随便扩显存不够就是不够GPU 卡不插上去就不存在。Web 流量高峰可以排队推理请求排队需要额外管理。用户可等不了一个整 Batch 慢慢凑延迟敏感业务对 P99 的要求近乎苛刻。Web 资源可以按 CPU/内存配额切分GPU 资源的切分颗粒度又贵又粗显存、算力、带宽彼此还会互相影响。换句话说云原生基础设施是“以容器为中心”AI 原生基础设施是“以模型和 GPU 为中心”。倒不是说 K8s 在 AI 场景没用而是光靠 K8s 那一套远远不够你得在它上面重新设计一层面向模型、面向计算资源、面向数据流的逻辑。1.1 AI 原生基础设施到底和“云原生 GPU”差在哪很多团队以为在 K8s 里加上 GPU 节点就能做 AI 平台其实差距挺大的。我做了一张对照表能比较清楚地看到两者的差异维度云原生基础设施AI 原生基础设施调度对象容器 / PodGPU 资源、显存、模型副本弹性单位实例副本数批量推理任务、动态 Batch、显存配额故障恢复重启容器重新加载权重、检查点恢复、断点续训存储需求低延迟热数据 返回数据超大模型文件、Checkpoint、数据集多渠道读写网络瓶颈微服务调用梯度同步、KV Cache 传输、分布式推理成本敏感点实例单价 / 并发GPU 利用率、排队等待、混合任务调度这也解释了为什么现在大家开始反复提“AI 原生”而不是简单说“在 K8s 上跑 AI”。前者是从头按 AI 工作负载的形状来设计基础设施后者只是把 AI 工作负载硬塞进原有的基础设施。1.2 这个赛道解决什么问题加入 Dynamia 密瓜智能之前我和团队聊过几次最终真正说服我的不是 PPT是三个具体问题第一算力利用率太难看。很多公司的 GPU 集群平均利用率不到 30%。训练任务白天跑推理服务晚上高峰中间还有大量碎片时间。把训练和推理放在同一个池子里动态调度听上去简单做起来涉及 GPU 共享、显存隔离、抢占策略每一步都是硬骨头。第二大模型推理的延迟瓶颈。模型越来越大显存放不下得做量化、蒸馏、分布式推理。推理框架选型、动态 Batch 调参、前置网关怎么做直接影响用户体验和成本。第三数据流转效率。训练前期要读海量数据集训练过程中要高频写 Checkpoint训练完又要发布模型到推理集群。整个链条上如果存储和缓存设计不合理GPU 再快也在等数据时干烧电。这三个问题背后其实是同一个核心把 GPU 当成一种需要精细调度的稀缺资源而不是可以随便铺的普通服务器。这也是 Dynamia 密瓜智能想做透的事。2. 一套 AI 原生基础设施的“最小五件套”如果你也要从零搭一套 AI 原生基础设施我的建议是先别急着上各种高级组件而是把下面五层搞清楚。这五层是一个可运行的最小骨架之后所有平台能力都是在这五层之上逐步长出来的。2.1 算力层GPU 节点选型与配置算力层很容易被理解成“买卡就行”实际远不止。GPU 节点配置要同时考虑三件事GPU 型号、CPU/内存配比、互联拓扑。GPU 型号直接决定了你能跑多大的模型。以常见的单卡显存为例一张卡 80GB 和一张卡 24GB 能承载的模型规模差非常多。显存不够就得做模型并行或者切分这会引入额外的通信开销所以很多时候宁可选大显存卡。CPU/内存配比容易被忽略。数据预处理、Tokenize、动态 Batch、Python 运行时这些都会吃 CPU 和内存如果节点里 CPU 核数太少GPU 会经常空等数据。我见过一个实例数据管道没做好GPU 利用率只有 40%CPU 却 100% 跑满典型的一核有难、八核围观。互联拓扑更关键。多卡训练时卡与卡之间的通信带宽直接决定了训练效率。NVLink 和普通 PCIe 的带宽差距可能是数量级的。选机器的时候我建议问清楚卡间互联方式别光看卡数。至少要让同一台机器上的跨卡通信走高速互联跨机通信再另外规划 RDMA 或高性能网络。2.2 存储层模型仓库、数据集与检查点AI 场景的存储需求和普通业务完全不同。一个模型权重文件动辄几十 GBCheckpoint 可能要写几百 GB数据集又是大量小文件加少量超大文件混合。这时候很难用单一存储方案通吃。我的建议是分层处理训练数据用并行文件系统或者高性能对象存储核心指标是高吞吐和大并发能扛住成百上千个数据加载进程同时读。模型文件用对象存储 本地缓存。推理节点启动时先从对象存储拉权重但每次都拉一遍显然不现实所以节点上要有本地缓存层最好再配合模型预热机制。Checkpoint 写入用高带宽并行存储并且要有版本管理。训练崩了要能快速回滚到最近一次健康状态而不是从头再来。存储层最怕的是“看起来能存实际一压就垮”。很多团队一开始图省事用了常规文件存储结果并行训练一开存储带宽直接被打满训练速度反而被存储拖慢。这一块不能省。2.3 网络层分布式训练与推理的隐形命脉模型规模一大单卡、单机都装不下分布式是必然选择。分布式训练里最核心的通信模式是 AllReduce每一轮梯度同步都需要所有节点互相传数据这种通信对带宽和延迟极其敏感。普通以太网下几百张卡一起同步开销会迅速吃掉训练收益。所以 AI 原生基础设施的网络设计重点不是对外提供多少带宽而是内部东西向流量的延迟和吞吐。RDMA 技术已经是分布式训练场景的事实标准。当然不是说没有 RDMA 就跑不了分布式训练而是规模上来之后这是绕不开的性能分水岭。推理侧的网络压力也开始变大。现在很多团队做 Prefill 和 Decode 分离把 Prefill 阶段的中间结果通过高速网络传给 Decode 节点跨机传输的数据量比传统请求大很多网络设计必须提前考虑。2.4 调度与编排层谁来决定这块 GPU 给谁用我在加入前最看重的就是这一层。没有调度所有 GPU 资源就是一堆散落的算力谈不上平台。调度层首先要感知 GPU 资源。节点上有几张卡、多少显存空闲、是否已经跑着任务都要能实时掌握。不能只看节点剩余 CPU 和内存因为两个节点即使 CPU 相同GPU 型号不同能跑的任务也完全不同。其次要支持多级调度策略。训练任务通常跑得久、资源需求大推理任务需要快速响应、延迟敏感。这两种任务混在同一个集群里需要一个能区分优先级、能抢占、能排队的调度器。比如高峰期的交互式推理请求应该优先离线批量训练可以排后。最后还要处理 GPU 共享和显存隔离。一张卡上跑多个推理任务可以大幅提升利用率但显存配额的硬隔离必须到位否则一个任务超显存会把同卡上的其他任务一起打挂。2.5 接入层模型服务与推理网关模型训练得再好最终要通过服务暴露出去才有价值。接入层是用户第一眼看到的东西也是延迟和成本控制的关键战场。我比较推荐的模式是“模型服务引擎 推理网关”两层。模型服务引擎负责真正加载模型、执行推理常见的有 vLLM、Triton 这类框架它们内部已经做了 PagedAttention、动态 Batch 等优化。推理网关则负责请求路由、鉴权、限流、排队、超时管理相当于模型世界的 API Gateway。两层分离的好处是引擎可以专注性能优化网关可以专注接入逻辑。以后模型版本迭代比如从 7B 换到 13B只需要在网关层调整路由规则不需要改动整体接入链路。另外推理网关还承担流控职责防止突发流量把模型服务打爆。3. 落地过程中的关键设计我偏向的四个选择有了最小五件套的骨架接下来就是更细的设计选择。这些选择没有绝对的对错更多是结合业务形态做取舍。我这里把自己认为值得参考的四个决策点写出来。3.1 训练和推理共用集群而不是物理隔离很多团队习惯把训练集群和推理集群分开管理简单但资源利用率很低。白天推理业务少的时候GPU 闲置着晚上训练任务跑完算力又空着。分开部署两边都在浪费。我偏好的做法是训练推理共用同一个资源池但用调度策略区分优先级。交互式推理请求优先级最高可以抢占低优先级离线训练任务离线训练任务则把资源利用的空窗填满。这个设计对调度器的要求高但收益也很直接同样的 GPU 总量月产出至少多出两成。3.2 GPU 共享用显存硬隔离不用裸跑裸占一张 80GB 的卡如果只跑一个大模型内存利用率太难看。我很看好 GPU 共享的方向但实现方式必须讲究。硬件层面的 MIG 或者虚拟化方案能做到比较强的隔离一张卡切几个实例互不干扰。软件层面的时间切片能提升利用率但隔离性弱一个任务的异常容易殃及同卡邻居。我的习惯是在生产环境用硬件级隔离或容器级显存限制宁可单卡利用率低一点也要保证故障隔离和安全边界。测试环境可以放开时间切片怎么压都行。3.3 推理请求先排队再动态 Batch动态 Batch 能大幅提升推理吞吐。原理很简单把短时间内的多个请求攒在一起凑成一个 Batch 喂给模型利用 GPU 的并行计算能力同时处理多个请求代价是第一个请求会稍微多等一会。这里的关键参数是 Batch 窗口。窗口太短攒不住请求Batch 效果不明显窗口太长延迟飙升用户体验崩掉。我一般会从 20ms 起步调观察 P99 延迟和吞吐曲线找到剪刀差最小的点。另一个调整方向是优先聚合同类请求让同一个 Batch 内部模型保持一致避免不同模型来回切换导致缓存失效。3.4 模型发布要可回滚版本要可追溯模型上线之后不是万事大吉。线上效果变差、数据分布漂移、推理结果异常都需要快速回滚到之前的版本。所以模型仓库里的每个模型都要有版本号、训练日志、评估指标发布时要走灰度流程。灰度推理是我比较强调的环节。先切 5% 流量到新模型观察反馈确认没问题再逐步放量。一旦异常指标出现网关层要能立刻切回旧版本。这个流程依赖模型网关的路由能力所以 2.5 里我特意强调网关的重要性。4. 从零跑通一个 AI 推理服务的实操记录理论说了不少上点实操。最近我在 Dynamia 密瓜智能的测试环境里搭了一套最小推理服务从裸机到能调通接口大致花了一个下午。把过程写下来给你一个可以照着做的模板。4.1 环境准备驱动、容器运行时、GPU 识别正常步骤是先装 GPU 驱动再装容器运行时最后让 K8s 识别到 GPU 资源。如果只是单机验证可以用 Docker 直接跑但生产环境建议还是走 K8s。这里重点检查一件事容器里能不能看到 GPU。很多坑都出在驱动版本和容器运行时版本不匹配上。验证命令很简单跑一个带 GPU 的测试容器执行nvidia-smi能看到卡信息基本就通了。注意驱动装完别忘了重启节点。很多人漏了这一步结果nvidia-smi在宿主机上正常容器里怎么都看不到卡。4.2 部署模型服务引擎我这次用的是 vLLM 来加载模型。先拉一个精简模型做起验证配置核心参数时给两点建议max-model-len不要设置太大。很多人喜欢把上下文窗口开满实测下来显存占用会明显上升如果业务很少用到超长输入设一个合理的值更经济。gpu-memory-utilization一般设 0.85 到 0.9。别设到 0.95 以上显存接近满载时碎片化问题会直接影响并发能力和稳定性。模型服务引擎的启动命令大概长这样python -m vllm.entrypoints.openai.api_server \ --model /data/models/qwen2-7b-instruct \ --served-model-name qwen2-7b \ --max-model-len 8192 \ --gpu-memory-utilization 0.9 \ --port 8000启动成功后可以用一个最简单的请求验证curl http://127.0.0.1:8000/v1/chat/completions \ -H Content-Type: application/json \ -d { model: qwen2-7b, messages: [{role: user, content: 你好}] }能正常返回说明模型服务引擎已经通了。4.3 加一层网关做路由和限流单机验证没问题接生产还需要在前面加网关。网关要处理的事情包括请求路由到正确的模型服务、接口鉴权、Token 限流、排队超时等。这层我用的是比较通用的方案Kong 或者 APISIX 都可以。关键是配置路由规则把/v1/chat/completions的请求转发到 vLLM 的 8000 端口并给每个调用方配好 QPS 上限。网关层我额外加了两个参数连接超时和读超时。模型推理比较慢超时设太短会误杀正常请求设太长又会让异常请求长期占据连接。我会把默认读超时设成 120 秒因为长文本生成的耗时确实可能到分钟级。最大排队数。超出排队上限直接返回 429 错误避免雪崩效应。这样做之后调用方拿到的是一套稳定的 API后端模型是哪个、要不要扩容调用方完全不用关心。4.4 压测与指标观察服务起来之后一定要压测别直接上生产。我用的压测工具是简单的 locust 脚本构造一批并发请求同时盯四个指标QPS、TTFT首 Token 延迟、Token 生成速率、GPU 利用率。第一轮压测我通常会把并发从 1 逐步加到 50观察延迟曲线。如果 QPS 不再线性增长说明系统进入瓶颈区再压下去只会让延迟剧增。这个瓶颈点的数据就是后续做容量评估和成本预估的依据。压测结果出来后我会回到 3.3 提到的动态 Batch 参数重新调 Batch 窗口和并发限制。实测下来调优后 QPS 翻倍是很常见的事。5. 最近踩过的三个真实坑再来点更接地气的。下面的问题都是我在实操中真实遇到过的网上资料不太会这么集中地写我整理出来给同行参考。5.1 GPU 显存泄漏服务越跑越慢现象模型服务刚启动时延迟很好跑两三天后延迟逐渐变高最后 OOM 崩溃。排查过程先看进程内存和显存占用发现显存使用率持续走高。再用 Nvidia 的调试工具抓 CUDA 缓存状态确认是部分请求结束后没有正确释放显存。常见诱因是自定义模型逻辑里创建了 CUDA 张量但没有显式清理或者某些库版本存在内存碎片问题。结论显存泄漏问题很难完全避免但可以通过定期滚动重启来止血更治本的做法是升级推理框架版本并确保模型代码里的临时张量都走with torch.cuda.device这类规范写法。注意上线前压测不要只压 10 分钟至少要压几个小时甚至几天才能暴露出泄漏问题。很多人就是栽在短压测看起来一切正常。5.2 高峰时段请求排队过深P99 延迟爆炸现象业务高峰期 P99 延迟从 300ms 飙到 5 秒甚至出现调用超时。排查过程检查网关日志发现高峰期排队数非常大模型服务的 Batch 窗口又过长导致大量请求堆在等待队列里。再往下查真实原因是模型副本数不够GPU 资源上限到了加排队只是把问题从“超时”变成长尾。结论合理的做法是高峰期自动扩容模型副本并设置最大排队深度拒绝掉一些可接受的流量。不能只顾着保护后端无限制地堆积请求这样会把所有用户的体验都拖差。5.3 多租户任务互相干扰一个任务写爆共享目录现象同一个训练集群里两个团队跑任务其中一个疯狂写临时文件把共享存储打满导致另一个团队的 Checkpoint 写不进去。排查过程查存储看是单个大文件占空间还是一堆小文件占 inode。这次更隐蔽单个文件不大但数量几百万个把共享目录的 inode 打满了。结论租户隔离不只是算力隔离存储配额和文件数限制也要做。我后来给每个租户单独目录设置容量配额和文件数配额并对临时文件做自动清理策略问题才彻底解决。症状可能原因解决办法显存持续上涨最终 OOM推理框架显存泄漏未释放缓存升级框架版本规范临时张量清理定期滚动重启P99 延迟飙升队列堆积过深模型副本不足扩容副本设置最大排队数和超时策略共享目录空间或 inode 打满租户任务写临时文件无节制配置容量配额、文件数配额、自动清理请求偶发返回 500 或超时模型加载中压测后冷启动问题增加模型预热机制用就绪探针控制流量多卡训练速度上不去卡间通信走普通 PCIe带宽不足改高速互联优化数据并行和梯度同步策略6. 我对接下来的方向判断加入 Dynamia 密瓜智能之后我把未来一段时间的工作重点分成三个阶段。第一个阶段是把现有集群的利用率打上去通过细粒度的调度和副本管理先把空闲 GPU 盘活。第二个阶段是把推理服务标准化给业务方提供一致的接入体验内部模型怎么部署、怎么灰度、怎么回滚都做成标准流程。第三个阶段是更长期的事情做训练推理一体化的资源编排让一个资源池能同时支撑训练和推理的复杂混合负载。这三个阶段里我对第三个阶段最感兴趣。很多人觉得训练和推理是两个系统训练平台管分布式任务推理平台管在线服务。但它们的底层资源明明是同一批 GPU。如果能把检查点恢复、模型预热、动态扩容这些能力整合到一个系统里AI 团队从开发到上线再到迭代的效率会提升一个大的台阶。老实说这个方向没人敢说完全做透了。卡与卡之间的调度、显存与算力的隔离、存储与网络的配合每一个环节都有大量优化空间。正因为如此这件事才值得认真做。这几个月我自己最大的体会是AI 原生基础设施不是买一堆卡然后写个 Kubernetes 部署文件那么简单它更像把算力当成一门生意来精细化运营。每一块 GPU 的利用率、每一次推理的延迟、每一个任务的排队时间最后都会变成实实在在的成本和用户体验。这个项目后续我能延展的东西还很多后面有新的进展或者踩到新坑再回来写文章继续跟大家聊。
返回列表