运维同事离职后,我用这套方案自己扛下了整个 AI 平台
接手一个 AI 平台的运维工作,通常是两种情景:要么是公司业务处在快速上升期,新增的算力、模型服务、训练任务已经多到一个人忙不过来;要么就是像标题写的那样——运维同事离职了,交接文档只有几行命令,剩下的全靠自己摸索。我遇到的情况是后一种,而且更棘手一些:平台不是传统的 Web 服务,而是包含了 GPU 资源池、模型推理服务、定时训练任务、对象存储、向量数据库在内的一整套 AI 基础设施。刚开始那两周,我基本是每天被告警叫醒,白天处理线上问题,晚上补文档、写脚本,整个人都是绷着的。
后来我冷静下来,把之前零零散散落在各个群聊、备忘录、Shell history 里的信息重新做了梳理,再结合自己平时积累的 Linux 运维功底和一点自动化经验,分阶段搭建出了一套“半自动化 + 强监控 + 极简排障”的运维方案。这套方案不依赖额外的人手,也不要求你懂多深的 Kubernetes 或机器学习算法,核心就是把日常重复操作全部脚本化、把故障发现时间压到最短、把排查路径固化下来。现在我一个人能扛住整个平台,靠的已经不是“盯”和“救火”,而是这套从监控、日志、备份到自愈的闭环体系。
这篇文章就把我落地的全过程整理出来,包括整体设计思路、核心监控与告警方案、AI 平台特有的 GPU 与训练任务运维技巧、日志与备份策略,以及我实际踩过的一些坑和排查方法。如果你也是一个人在面对一个不算小、但也不算超大规模的 AI 平台,这篇文章应该能给你提供一套可以直接抄作业的参考。
1. 整体设计与思路拆解
在动手写脚本、装监控之前,我先干了一件事:梳理现状。AI 平台和传统 Web 运维最大的区别在于,它不只是“保证服务不宕机”,还要关注资源利用率、任务状态、模型版本、数据链路这些维度。如果一上来就铺监控、上容器编排,反而会让你淹没在告警和配置里。
1.1 先用一张表摸清家底
我建议你接手任何一个平台后的第一件事,就是画一张“资产清单”。不一定非要上 CMDB 系统,Excel 或者 Markdown 表格就够用。关键是把这几类信息列清楚:
- 物理资源:有多少台服务器、每台的 CPU/内存/GPU 型号与数量、磁盘容量与挂载点、所在机柜或云可用区。
- 基础组件:操作系统版本、Docker/Kubernetes 版本、GPU 驱动版本、CUDA 版本、Python 版本。
- 业务组件:模型推理服务(比如 vLLM、Triton、TensorRT-LLM)、训练框架(PyTorch、TensorFlow)、调度平台(KubeFlow、Volcano、Slurm)、对象存储(MinIO、Ceph、OSS)、向量数据库(Milvus、pgvector、Chroma)。
- 数据链路:训练数据从哪来、模型产物存到哪、推理服务读哪个模型路径、日志打到哪个收集器。
- 关键联系人:虽然运维同事离职了,但云厂商的售后、机房托管的技术支持、开源社区的维护者,这些是你在紧急时刻能求助的人。
我一开始觉得这些信息都在脑子里,没必要写下来。但真正出了一次 GPU 驱动导致的故障后,我才发现:一个人在这种高压场景下,记忆是不可靠的。把这份清单维护好,是后面所有自动化和监控建设的地基。
1.2 先解决“看得见”,再解决“不用看”
很多运维同学接手新平台时容易犯一个错误:太急着做自动化,甚至想一步到位搞出“全自动运维”。但 AI 平台的复杂度决定了,你不可能一开始就信任脚本能处理所有异常。我的思路是分三步走:
- 第一步,先做全面可观测。让所有关键指标都有监控,所有关键服务都有日志,所有异常都能通过告警通知到我。这个阶段的目标是“出了问题我能第一时间知道,并且能快速定位”。
- 第二步,再做半自动修复。把高频、风险低的故障处理流程脚本化,比如自动重启挂掉的推理服务、自动清理磁盘空间、自动恢复失败的数据备份。脚本先以“手动触发”方式运行,跑熟之后再接入告警 webhook 实现自动触发。
- 第三步,最后做容量规划与自愈。在积累了足够多的运行数据后,再根据 GPU 利用率、任务排队时长、磁盘增长趋势做容量预测,并设计故障转移和自愈策略。
这样做的逻辑很简单:自动化是锦上添花,而不是雪中送炭。你连手动排查都要花一个小时的问题,做成自动化脚本也只是把一个小时的排查过程固化成了逻辑,不会让你的平台变稳定。先把监控和日志做扎实,才是对小团队最友好的路径。
1.3 技术选型:少即是多
AI 平台运维涉及的工具链非常多——Prometheus、Grafana、Loki、ELK、JumpServer、Ansible、KubeFlow……如果都铺开,学习成本和维护成本会非常高。我当时的选型原则是:能合并的合并,能轻量的轻量,优先选社区活跃、资料多的项目。
我最终保留了这几套:
- Prometheus + Grafana:监控指标采集与可视化,搭配 Alertmanager 做告警。
- Loki + Promtail:日志聚合。相比 ELK,Loki 的部署和维护成本低很多,对 AI 平台这种“日志量大但不需要全文索引”的场景足够用。
- Ansible:配置管理和批量操作。主要用于初始化新机器、下发配置文件、批量更新。
- Shell + Python 脚本:负责日常的备份、清理、自愈类操作,直接把 crontab 当作定时调度器。
这里面最核心的是 Prometheus + Grafana 这套组合,因为 AI 平台的监控对象非常特殊——GPU 利用率、显存占用、推理延迟、训练任务状态,这些指标是传统 CPU 监控覆盖不到的。后面我会单独用一节讲这块的配置。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 核心细节解析与实操要点
这一节是全文的干货核心。AI 平台运维和传统运维最大的不同,在于你需要理解“算力”和“任务”这两个维度。下面我按几个关键模块拆开讲,每个模块都附上具体的配置与操作要点。
2.1 GPU 监控:别只盯着利用率
很多刚接触 GPU 服务器运维的同学,最常看的指标是 nvidia-smi 输出里的 GPU-Util。但实际跑过模型训练和推理后你会发现,这个指标有时候会误导你——它表示的是“在采样周期内 GPU 上 kernel 执行的时间占比”,而不是“GPU 资源的真实饱和程度”。对于推理服务,GPU-Util 可能很低(比如 20%),但显存占用很高,这并不代表服务有问题;对于训练任务,GPU-Util 可能会周期性波动,这也不一定代表“瓶颈在 GPU”。
我在自建监控时,最终保留的 GPU 关键指标是这几项:
- 显存使用率(Memory Used / Total):这个指标比 GPU-Util 更稳定,也更容易判断是否接近 OOM 风险。
- GPU 温度与功耗(Temperature、Power Draw):温度过高直接导致降频,性能会明显下滑;功耗则能反映 GPU 是否真正在“满载工作”。
- GPU 卡故障状态(比如
nvidia-smi -q中设备是否显示Healthy):这个需要轮询采集,因为 GPU 卡偶发掉卡(比如NVML_ERROR_DRIVER_NOT_LOADED)并不会直接体现在利用率指标上。
Prometheus 有成熟的 nvidia_gpu_exporter 或者通过 DCGM Exporter 来采集这些指标。我在生产环境用的是 DCGM Exporter,因为它由 NVIDIA 官方维护,指标更全,包括温度、功耗、显存、PCIe 吞吐、NVLink 状态等。部署方式是 Kubernetes DaemonSet,每个 GPU 节点跑一个 Pod,指标通过 dcgm_ 前缀暴露给 Prometheus。
Grafana 上的展示面板,我会把每个节点单独一行,横向按 GPU 卡切分,方便一眼定位是哪台机器、哪张卡出问题。告警规则我最初设置的是“显存使用率 > 90% 持续 10 分钟”触发 Warning,因为大部分 AI 任务显存占用是启动后马上拉满并保持稳定的,如果持续高位说明有任务堆积或资源泄漏。后来加了“温度 > 85℃”的告警,用来发现机房空调故障或散热问题。
2.2 业务监控:推理服务和训练任务
除了 GPU 资源,AI 平台里最需要盯的是两类业务:在线推理服务和离线训练任务。
推理服务(比如基于 vLLM 或 Triton 部署)的监控重点在延迟、吞吐、错误率。vLLM 本身会暴露一些 metrics 接口,比如 avg_prompt_throughput_toks_per_s、avg_generation_throughput_toks_per_s、request_success 等,可以直接接入 Prometheus。我在 Grafana 里建了两个关键面板:一个是“首 Token 延迟”和“生成 Token 速度”,用来判断用户体验;另一个是“排队请求数”(Waiting Queue Size),如果这个值持续上升,说明后端推理能力已经打满,需要扩容或优化。
训练任务的监控更复杂一些,因为训练任务通常是被调度系统(KubeFlow、Volcano 或裸机脚本)拉起的,任务的状态变化(Pending、Running、Failed、Succeeded)需要单独采集。我的做法是通过一个 Python 脚本定时调用训练平台的 API,把任务状态、当前 epoch、loss、GPU 使用情况写入 Prometheus 的 PushGateway,然后配一条告警:任务失败或卡住(比如超过 2 小时无日志更新)时直接通知。
这里有个很关键的经验:AI 平台的“任务失败”往往不会带来明显的系统指标异常。 可能 CPU、内存、GPU 都正常,但训练因为一个 NaN loss 或者 Python 依赖 Bug 就退出了。所以单靠监控系统远远不够,必须配合日志和告警的联动,这也是我下面要讲的。
2.3 日志采集:Loki 比 ELK 更省心
传统运维里我们常讲“日志是排障的第一手材料”。到了 AI 平台,日志的重要性还要再加一层:模型的训练日志里包含 loss、accuracy 这些直接反映训练健康度的信息,而推理服务的日志里包含每次请求的输入输出、耗时、报错。在交接文档不完备的情况下,日志几乎是唯一能帮你还原线上问题的证据。
我选择 Loki 而不是 ELK,主要原因是 Loki 的部署和维护成本低得多——它不建索引,只存压缩后的日志块,靠标签做过滤查询。对于“我就想知道训练任务 3 小时前在某个 Worker 上输出了什么报错”这种场景,Loki 完全够用,而且资源占用比 ELK 小一个量级。
架构上我用了 Promtail 作为日志采集器。Promtail 以 DaemonSet 方式部署在每个节点上,指定收集路径,比如 /var/log/containers/*.log,这是 Kubernetes 里容器日志的软链目录。然后按照 Pod 的标签(比如 app=inference、job=training)自动附加标签,这样在 Grafana 里就能通过“标签过滤 + 时间范围”快速定位目标日志。
这套方案我还单独配了一个“日志中的错误关键字告警”:用 Loki 的 label_values(log, 'job') 查错误率,或者直接用 Promtail 的 pipeline_stages 正则匹配提取 error 级别日志。一旦某个服务在 5 分钟内出现超过 10 条 ERROR 日志,就告警出来。这个规则帮我抓到了好几个“指标看起来正常但实际有问题”的故障。
2.4 备份策略:模型和数据一个都不能丢
AI 平台里最“贵”的资产往往不是服务器,而是训练好的模型权重和标注好的数据集。模型文件动辄几十 GB 到上百 GB,存储成本高,备份起来也慢。很多运维会忽略这块,因为从传统运维视角看“磁盘没满、任务在跑”就够了。但我必须强调:没有备份的模型都是“薛定谔的模型”——你永远不知道它什么时候会消失。
我的备份策略分两个层级:
- 增量备份:对模型训练过程中产生的 checkpoint,通过 CronJob 每 4 小时做一次增量备份到对象存储(我是用 MinIO 配合
s3cmd同步工具实现)。增量备份的成本很低,只需要同步变更过的文件。 - 全量备份:对最终的模型产物、重要数据集、向量数据库的索引,每周做一次全量备份。向量数据库这块我特别说明下,Milvus 这类系统如果直接拷贝文件,可能会因为一致性原因导致备份不可用。正确做法是用它自带的备份工具(比如
milvus-backup),或者通过 API 做数据导出。
备份的验证同样重要。我每个月会随机挑一个备份,在测试环境恢复一次,确认文件完整可加载。这个习惯救了我一次——某个版本的数据集因为同步脚本一个 bug 导致部分文件损坏,如果不是我提前恢复了备份,等真正需要回滚的时候才发现备份坏了,那就真的被动了。
3. 实操过程与核心环节实现
这一节我把从零搭建这套运维体系的完整过程写出来,包含我实际执行的命令、配置文件和踩过的坑。你可以把它当作一份可直接照做的参考。
3.1 Linux 环境初始化与工具部署
AI 平台底层的服务器操作系统大部分是 CentOS 7/Ubuntu 20.04 这些常见发行版,但也有不少内部机器是“能跑就行”的状态——内核版本低、时区不对、文件描述符限制不够、常用命令缺失。接手后我做的第一件事就是刷新全局环境。
我写了一个 Ansible Playbook,一次性完成这些初始化操作:
- 统一时区:
timedatectl set-timezone Asia/Shanghai - 调整文件描述符限制:在
/etc/security/limits.conf里把nofile提到 65535,这一步对训练任务特别重要,因为高并发读写数据时很容易把默认 1024 的上限打满。 - 优化内核参数:把
net.ipv4.ip_forward打开,vm.swappiness设置为 10,vm.overcommit_memory设置为 2(防止某些训练任务一次性申请太多内存导致系统 OOM,反而拖垮其他服务)。 - 安装常用运维命令:
lsof、tcpdump、iftop、htop、sysstat、nload、python3-pip这些是排障必备,很多精简版系统镜像里都没带。
这个阶段有个细节要注意:GPU 驱动和 CUDA 版本最好不要用 Ansible 统一自动装,因为不同卡型、不同 Docker 镜像对驱动版本的要求可能不同。我在这个环节只做了“检测脚本”——启动时检查 nvidia-smi 是否可用、驱动版本是否满足最低要求、nvcc -V 是否正常输出。有了检测脚本,即使之后有新增机器或驱动更新,也能快速暴露问题。
3.2 Prometheus + Grafana + Alertmanager 搭建实录
我在 Kubernetes 集群内用 Helm 方式安装 Prometheus 生态。直接说一下关键配置:
- 部署 Prometheus Operator:它会自动发现 Kubernetes 里的 ServiceMonitor 和 PodMonitor,省去了手动维护 target 列表的麻烦。
- DCGM Exporter 安装:通过 Helm Chart
dcgm-exporter部署,默认会创建一个 PodMonitor,Prometheus 自动采集。 - Loki 安装:用 Helm 安装 Loki 到
loki命名空间,存储用本地磁盘,开启singleBinary模式就够,不需要上微服务模式。 - Grafana:安装后配置 Prometheus 和 Loki 两个数据源,再导入官方仪表盘(比如
DCGM Exporter Dashboard、Kubernetes Cluster、Node Exporter Full),然后基于这些模板做微调。
告警规则我是直接用 PrometheusRule 资源定义的。这里贴几个我后来验证过比较有效的规则核心要点:
dcgm_gpu_utilization == 0且dcgm_gpu_memory_used > 0持续 30 分钟:说明可能有任务卡死但显存没释放,需要人工介入。- 推理服务的请求成功率 < 99% 持续 5 分钟:直接通知到个人微信(通过 webhook 转发)。
- 节点可用内存 < 10% 持续 10 分钟:需要关注是否有内存泄漏。
Alertmanager 的通知渠道,我建议不要只发邮件——真正出事的时候没人会盯收件箱。我是接到了钉钉和飞书的机器人 webhook,再通过群机器人推送到手机 App。告警文案里一定要带“机器 IP + 指标当前值 + 查看 Grafana 面板的链接”,这样在手机端就能快速判断是否需要立刻起床处理。
3.3 自愈脚本:让 Crontab 帮你打工
监控和告警解决的是“发现”问题,但 AI 平台还有一类高频问题适合做成自愈脚本,比如:
- 推理服务 Pod 被 OOMKilled:这是 Kubernetes 里最常见的现象之一。
OOMKilled并不等于崩溃,如果后端配置了自动重启,重启后服务会恢复,但你仍然会收到 Pod 反复重启的告警。我的自愈脚本会自动检查 CrashLoopBackOff 的 Pod,如果重启次数超过 3 次,就自动拉取最近日志并发送到群里,然后执行kubectl rollout restart强制拉起(解决偶发性的资源竞争)。 - 磁盘空间告急:AI 平台对磁盘消耗非常大,尤其是训练过程产生的临时日志、缓存、容器镜像。我的脚本每 10 分钟检查一次节点的
/和/data使用率,超过 80% 就自动清理:先删掉过期 7 天的临时文件,再清理docker system prune -f(只删悬空镜像和停止的容器,不会动正在运行的容器),如果还超过 90%,就把/var/log下 gzip 过的日志文件删除。 - 训练任务卡死检测:通过 Prometheus 里的自定义指标(训练任务心跳),如果任务超过 1 小时没有上报心跳,脚本自动 kill 掉这个任务并通过 API 重新提交。
写自愈脚本的时候有个原则:先在手动模式跑一个月。 不要一上来就接告警自动触发。我是先让脚本每天定时运行,把“准备做什么”打印在日志里,但不实际执行。确认规则稳健、不会误伤正常服务后,再逐步放开为自动执行。这一步虽然慢,但能帮你避免“自动化脚本把自己的业务搞挂了”这种更尴尬的故障。
3.4 高效排障:Linux 命令的“实战姿态”
AI 平台排障和传统 Linux 排障有很多相通的地方,但也会遇到一些新的“为什么”。下面是我最常用的一些命令组合和判断思路:
- 先看负载:
uptime看 load average;如果 load 高但 CPU 不高,先怀疑磁盘 I/O 瓶颈,用iostat -x 1查看%util和await。 - 看进程:
htop按 CPU/内存排序,找哪个 python 进程在吃资源;如果出现多个同名进程,可以ps -ef | grep python看 PID 和启动参数。 - 看显存:
nvidia-smi前几行是显卡状态,后面是进程占用。如果显存没释放,用fuser -v /dev/nvidia*或kill -9杀掉残留进程。 - 看网络:推理服务的延迟突然升高,先排除网络问题,
ping网关和 8.8.8.8 看丢包率,再mtr看链路中的哪一跳有问题。 - 看日志:最快的是
journalctl -u <service-name> --since "10 minutes ago" --no-pager,如果服务在 Kubernetes 里,用kubectl logs <pod> --tail=200。
这里提一个挺常见的坑:很多 AI 框架是用 Python 写的,信号处理不太完善,kill -9 杀掉的 python 进程如果持有共享内存或显存,残留资源可能导致下一个任务启动失败。所以排障时,杀完进程后最好用 nvidia-smi 和 ipcs 检查一下资源释放情况。
4. 常见问题与排查技巧实录
最后这部分,我整理一下接手 AI 平台运维这段时期遇到的高频问题。每个问题都附上排查步骤和我的解决思路,可以直接存下来当速查表用。
4.1 GPU 卡“消失”了怎么办
现象:nvidia-smi 报错 No devices were found,或只识别出部分 GPU 卡。
排查链路:
lspci | grep -i nvidia看系统层面是否还有这张卡。如果 PCI 设备都看不到,大概率是硬件故障或拔卡了。- 如果能识别但 nvidia-smi 找不到,先用
dmesg | grep -i nvidia查内核日志,重点看有没有NVRM: failed to initialize或Xid报错。 - 尝试
sudo modprobe -r nvidia_drm nvidia_modeset nvidia && sudo modprobe nvidia重新加载驱动。 - 重启服务器。如果重启后恢复,可能是驱动和硬件的一过性冲突;如果频繁出现,建议联系厂家换卡。
这种问题没法靠自愈脚本解决,只能靠监控及时发现(DCGM Exporter 指标会归零),然后走硬件流程。
4.2 显存 OOM 但进程还在跑
现象:nvidia-smi 显示显存已满,但对应的 Python 进程还活着,不报错也不退出。
原因:PyTorch 等框架遇到 CUDA OOM 时通常会抛异常退出,但某些场景(比如 NCCL 通信卡住、DDP 同步等待)不会直接退出,导致显存一直被占用。
解决思路:
- 先查看进程对应的训练日志,判断是不是等待某个远端 worker 的同步。
- 用
py-spy dump --pid <pid>查看 Python 进程的当前调用栈,确认卡在什么函数上。 - 如果确认是死锁,直接 kill 掉进程,然后用脚本清理显存残留,再重新提交训练任务。
4.3 Kubernetes Pod 频繁重启
现象:推理服务 Pod 状态反复 CrashLoopBackOff,服务间歇性不可用。
排查步骤:
kubectl describe pod <pod>看 Events 里的 Last State 和 Reason,最常见的两个是OOMKilled和Error。kubectl logs <pod> --previous看上一次容器启动时的日志,这是关键,kubectl logs只能看到当前容器。- 如果是 OOMKilled,调整 deployment 的
resources.limits.memory或优化推理服务的 batch size。 - 如果是代码报错(比如 import 失败、模型加载失败),先把基础镜像修复,再滚动更新。
这个问题的坑在于,有些时候 Pod 重启是“偶发”的,重启后一切正常,但过了几小时又挂。这种情况下我会先给服务加一个 livenessProbe 的配置,让它检测到“模型加载完成”后再对外提供服务,避免“容器起来了但实际还没准备好”导致的假死。
4.4 告警风暴:如何防止被“狼来了”拖垮
AI 平台告警策略最大的敌人不是没告警,而是告警太多,导致真正严重的告警被淹没。
我的解决经验是:
- 告警分级:P0(必须立刻处理)只保留“核心推理服务不可用”“GPU 节点宕机”“数据备份失败”这几条;P1(当天处理)是资源使用率超阈值、训练任务失败;P2(本周关注)是磁盘增长趋势、GPU 利用率偏低等。
- 告警收敛:Alertmanager 里配置
group_wait: 30s、group_interval: 5m、repeat_interval: 4h,避免同一问题反复轰炸。 - 告警去重:用 Prometheus 的
sum(rate(...)) by (alertname)先把同类型告警合并,再投递。 - 定期复盘:每周五我会把本周的告警历史拉出来,看一下哪些告警是重复的、哪些是可以靠脚本自动修复的、哪些规则导致误报,然后不断调优规则。
写在最后:这半年我最大的收获
这一整套方案跑下来,我最深刻的体会是:AI 平台运维本质上不是“修 CPU、看内存、管网络”这三板斧,它更多是“理解算力、理解数据、理解任务生命周期”的一门综合工作。一个人扛平台确实累,但如果能把重复的事情自动化、把突发的故障流程化、把长期的趋势监控化,你的负担会小很多。
最后再分享一个小技巧:如果你刚接手一个 AI 平台,先从“把所有的监控补全”开始,而不是急着写自动化脚本。因为监控是发现问题的手电筒,自动化只是帮你快速处理问题的工具。没有手电筒,你连问题在哪都不知道,工具越多反而越乱。
我现在已经养成了一个习惯,每个月抽半天时间,把平台一个月以来的运行数据(资源利用率、任务成功率、告警数量)拉出来看一遍,然后花时间优化一个最影响效率的环节。这套方法让我的平台越跑越稳,也希望它能帮到正在独自面对 AI 平台的你。
