news 2026/3/4 20:21:00

转型AI运维工程师·Day 4:显存炸了?别急着换机器——深入性能调优

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
转型AI运维工程师·Day 4:显存炸了?别急着换机器——深入性能调优

心情:像个侦探,从愤怒中寻找逻辑任务:排查 CUDA Out Of Memory (OOM) 错误,清理僵尸进程,优化显存配置关键词:CUDA OOM, Zombie Process, Mixed Precision (AMP), Batch Size

早上 10:00,办公室的气氛有点紧张。 李博士黑着脸找我:“YY,你这批 P4d 机器是不是那是次品?还是 AWS 给我们的卡是阉割版的?”

我一愣:“怎么可能,AWS 的 SLA 可是 99.99%。”

李博士指着屏幕上的红色报错:RuntimeError: CUDA out of memory. Tried to allocate 512.00 MiB (GPU 0; 40.00 GiB total capacity; 35.80 GiB already allocated...)

“你看,”李博士说,“我的模型参数加上梯度,算下来最多占 28G。这张卡是 40G 的 A100。现在才跑了几步就报 OOM(内存溢出),而且我看nvidia-smi,显存一直被占得满满的,根本不释放。肯定是有内存泄漏或者硬件故障。”

作为 AWS SAP,我第一反应是看 CloudWatch。一切正常。 但我知道,要解决这个问题,我必须深入到GPU 内存模型内部。

第一步:拆穿nvidia-smi的谎言

我登录到报错的节点10.100.1.10。 输入nvidia-smi

  • Memory-Usage:39800MiB / 40536MiB(确实满了)

但我知道一个 AI 运维的冷知识:nvidia-smi显示的是“被占用的显存”,而不是“正在使用的显存”。PyTorch 为了速度,申请显存后不会立即还给操作系统,而是自己管理(Caching Allocator)。

我打开了一个 Python Shell,敲入了几行代码来“自证清白”:

import torch print(f"Allocated: {torch.cuda.memory_allocated() / 1024**3:.2f} GB") print(f"Reserved: {torch.cuda.memory_reserved() / 1024**3:.2f} GB")

结果显示:

  • Allocated(实际正在用的):22 GB

  • Reserved(PyTorch 占着坑没用的):38 GB

我对李博士说:“博士,机器没坏。是 PyTorch 占着茅坑不拉屎,这是它的缓存机制。真正导致 OOM 的是瞬间峰值。”

第二步:清理战场的“幽灵” —— 僵尸进程

虽然解释了原理,但李博士尝试重启训练,依然秒崩。 他很困惑:“我都关掉程序了,为什么显存还是满的?”

我立刻意识到这是分布式训练常见的坑:僵尸进程 (Zombie Processes)。 当torchrun启动的 32 个进程中,如果有一个崩了,其他进程有时候不会自动退出,而是变成了僵尸,死死抓着显存不放。

运维神技:一把梭清理我没有一个个去 kill,而是用了一个核武器命令:

# 查找所有占用 NVIDIA 显卡的进程 PID fuser -v /dev/nvidia* # 或者更暴力的清理(慎用,会杀掉这台机器上所有 AI 任务) sudo kill -9 $(lsof -t /dev/nvidia*)

执行完后,再运行nvidia-smiMemory-Usage:4MiB / 40536MiB。 世界清静了。显存全部释放。

第三步:解决真正的 OOM —— 运维不懂算法也要懂配置

清理完环境,李博士重跑代码。 跑了 10 分钟,又崩了。这次是真的显存不够用了。

李博士叹气:“看来 70B 的模型太大了,Batch Size 设成 1 都跑不动。YY,能不能再加几台机器?或者换 80G 显存的 H100?”

加机器?那可是翻倍的成本。 换 H100?现在全球缺货,根本排不到队。 作为运维,我必须帮老板省钱。我凭借这两天恶补的知识,提出了三个**“不花钱”的优化方案**:

1. 开启混合精度训练 (Mixed Precision / AMP)我问:“博士,你是不是用的默认 FP32(32位浮点数)?” 博士点点头。 我说:“现在的 A100 专门优化了FP16BF16。你代码里加一行torch.cuda.amp.autocast(),显存占用能砍一半,速度还能快一倍。精度损失微乎其微。”

2. 梯度累加 (Gradient Accumulation)我建议:“如果 Batch Size 设成 64 跑不动,咱们就设成 16。然后跑 4 次不更新权重,把梯度攒起来,第 4 次再一起更新。这样数学上等价于 Batch Size 64,但显存只需要 1/4。”

3. 激活重计算 (Activation Checkpointing)“用时间换空间。把中间计算结果扔掉,反向传播时再算一遍。”

李博士看着我,眼神变了:“YY,你以前不是搞 SAP 的吗?怎么连 Checkpointing 都懂?” 我笑了笑:“为了不让你找我加预算,我昨晚看了通宵文档。”

第四步:实战调优

李博士采纳了建议,开启了BF16(Brain Floating Point 16,A100 的绝活) 和梯度累加

再次启动torchrun。 这一次,我盯着nvidia-smi

  • 显存占用稳定在32GB / 40GB

  • GPU 利用率稳定在98%

  • 风扇狂转,热浪滚滚,但模型开始稳定产出 Loss 值了。

没有 OOM,没有报错。 原本需要加倍机器才能跑的任务,通过运维层面的参数建议,在现有硬件上跑通了。

下午 6:00:复盘 —— 运维的新价值

下班前,我在 Wiki 里更新了《AI 故障排查手册》,加了一条粗体字:

遇到 OOM 不要急着重启或加机器。先查僵尸进程,再查精度配置。

这一天,我意识到 AI 运维不仅仅是管服务器。 在传统运维里,我们管不到 Java 代码里的 Heap Size。 但在 AI 运维里,硬件和代码是强耦合的。不懂显存特性的运维,只能沦为无情的“重启机器工”;懂一点模型优化的运维,能帮公司省下几百万。

今日总结:

  1. nvidia-smi是会骗人的:必须要懂 PyTorch 的显存缓存机制。

  2. 僵尸进程是显存杀手:fuserlsof是清理显卡的必备工具。

  3. 性能优化 = 成本优化:通过 AMP 和梯度累加,用软件技巧解决了硬件瓶颈。


📎 附件:YY 的 AI 运维学习笔记(Day 4 - 性能调优篇)

文档说明:

Day 4 被李博士怼了之后,我深刻意识到:不懂算法原理的运维不是好运维。为了不背锅,我调研了以下 7 个核心概念。

适用人群:懂 AWS 和 Linux,但看到 PyTorch 报错就头大的运维兄弟。


1. 关于 AWS 资源:A100 和 H100 真的那么难搞吗?
  • 现状:是的,极其难搞,且极其贵

    • A100 (P4d 实例):这是上一代机皇。目前在 AWS 属于“紧俏物资”。如果你是新账号,配额几乎 100% 是 0。必须签大额承诺消费(EDP)或者找客户经理特批。价格约$32.77/小时

    • H100 (P5 实例):这是当今的显卡皇帝。比 A100 快 3-6 倍。在 AWS 上,这玩意儿几乎不对普通公众开放,通常只给战略级大客户。价格约$98.32/小时

  • 运维启示:正因为硬件稀缺且昂贵,所以我们才要拼命做“软件优化”(Day 4 做的那些事),而不是一遇到慢就加机器。

2. PyTorch 到底是个什么鬼?是那个 Web 界面吗?
  • 误区:

    • Jupyter(那个 Web 界面) =IDE / 编辑器(类似于 VSCode / Eclipse)。

    • PyTorch=库 / 框架(类似于 Spring Boot / React)。

  • 正解:

    PyTorch 是一组 Python 的代码库(Library)。

    李博士写的代码里第一行import torch,就是在加载这个库。它负责指挥显卡进行矩阵运算。

    它不是一个常驻后台的服务(像 Nginx 或 MySQL 那样),它更像是一个脚本,跑完就退出了。

3. 什么是“混合精度 (AMP)”和autocast
  • 通俗解释:

    • FP32 (单精度):传统的计算方式。存一个数字(比如权重)要占32 bit显存。就像用原本的 4K 画质看电影,极其清晰但文件很大。

    • FP16 / BF16 (半精度):存一个数字只占16 bit。显存占用直接砍半。就像用 1080P 看电影,虽然模糊了一点点,但为了流畅度(速度)和存储空间,完全可以接受。

  • torch.cuda.amp.autocast():

    这是 PyTorch 的一个开关。开启后,它会自动判断:

    • 哪几步运算需要高精度(FP32),就用 FP32。

    • 哪几步运算可以用低精度(FP16),就自动切成 FP16。

      这就是Mixed Precision (混合精度)

  • 运维价值:一行代码,显存省一半,速度快一倍。这是性价比最高的优化手段。

4. 什么是 Batch Size?什么又是梯度累加?

这两个概念是解决 OOM(显存溢出)的核心。

  • Batch Size (BS):

    • 定义:GPU 一口能吃掉多少条数据。

    • 比喻:就像搬砖。

      • BS = 64:用一辆大卡车,一次拉 64 块砖。效率高,但卡车(显存)可能装不下,会爆胎(OOM)。

      • BS = 1:用一个小推车,一次拉 1 块砖。卡车肯定装得下,但要在路上跑 64 趟,效率极低

  • 梯度累加 (Gradient Accumulation):

    • 场景:显存太小,装不下大卡车(BS=64),但我又想达到 BS=64 的训练效果(因为 BS 太小会导致模型学不准)。

    • 做法:

      用小推车(BS=16),连拉 4 趟

      但是!前 3 趟拉完后,不卸货(不更新模型权重),把砖头先堆在工地上(累加梯度)。

      等到第 4 趟拉完,凑够了 64 块,再一次性砌墙(更新权重)。

    • 公式:$16 (\text{Micro Batch}) \times 4 (\text{Accumulation Steps}) = 64 (\text{Global Batch Size})$

  • 运维价值:用时间换空间。虽然慢了一点点,但在有限的显存下跑通了大模型。

5. 激活重计算 (Activation Checkpointing) 是干嘛的?
  • 问题:训练大模型就像爬山,爬山过程中为了能原路返回(反向传播),你需要把沿途的所有风景(中间计算结果/激活值)都拍下来存到手机(显存)里。结果还没到山顶,手机内存满了。

  • 解决:激活重计算

    我不存照片了。当我需要回看半山腰的风景时,我重新再爬一次那一段路,现场算出来。

  • 运维价值:极端省显存(甚至能省 70%),代价是计算量增加(会慢 20%-30%)。这是最后的救命稻草。

6. 为什么是“再次启动torchrun”,而不是“启动 PyTorch”?
  • 区别:

    • PyTorch是代码库,你不能直接运行它。你运行的是Python 脚本(比如python train.py)。

    • torchrun是 PyTorch 官方提供的一个启动器工具 (Launcher Utility)

  • 为什么要用它:

    在单机单卡时,用python train.py没问题。

    但在多机多卡(Day 2 搭建的集群)环境下,你需要告诉程序:

    • 一共有几个节点?(--nnodes)

    • 我是谁?(--node_rank)

    • 老大的 IP 是多少?(--master_addr)

    • 每个节点几张卡?(--nproc_per_node)

    手动配这些环境变量会死人的。torchrun帮你自动处理好这些脏活累活,拉起分布式的 PyTorch 进程。

7. 总结:AMP 和 梯度累加
  • AMP (自动混合精度):

    • 核心:压缩数据。

    • 效果:显存减半,速度变快。

    • 副作用:极小(基本无损)。

    • 优先级:最高,必开。

  • 梯度累加 (Gradient Accumulation):

    • 核心:拆分任务。

    • 效果:显存占用大幅降低,模拟大 Batch Size。

    • 副作用:训练总时长略微增加。

    • 优先级:中等,遇到 OOM 时开启。


[图示:显存优化三板斧]

  1. AMP:把 32 位的胖子变成 16 位的瘦子。

  2. 梯度累加:把一大口饭分四口吃。

  3. 激活重计算:忘掉中间过程,用到时再算一遍。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/3/3 6:02:43

基于计算机视觉的答题卡识别及判分系统

项目简介基于计算机视觉的答题卡识别及判分系统实现了以下功能:采用Python开发语言、实现简单答题卡识别系统,其基本功能包括: 1,对答题卡进行图像处理; 2,识别答题卡的选择题选项; 3&#xff0…

作者头像 李华
网站建设 2026/3/4 17:39:38

int * 代替外部计数结构体实现SharedPtr

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 一、核心矛盾点二、错误实现演示与问题分析错误代码片段测试场景与崩溃后果核心问题总结 三、正确方案的本质:用指针共享堆上的计数简化优化&#xff1a…

作者头像 李华
网站建设 2026/3/2 20:40:52

Libvio.link爬虫技术解析

文章目录Libvio.link爬虫技术解析一、网站结构与核心特征1.1 页面类型与数据分布1.2 技术特征分析二、反爬机制深度剖析2.1 基础反爬措施(部分存在)2.2 反爬强度评估三、爬虫核心技术实现方案3.1 基础爬取:静态内容获取3.2 动态内容处理方案方…

作者头像 李华
网站建设 2026/3/2 23:36:18

重启MySQL或者MariaDB服务

文章目录1. 编辑 MariaDB 配置文件2. 在配置文件中添加或修改相关设置3. 保存并重启 MariaDB 服务4. 验证二进制日志是否已启用总结原因根据您的输出, log_bin 显示为 OFF,这意味着二进制日志功能目前没有启用。您尝试使用 SET GLOBAL log_binon; 来启…

作者头像 李华
网站建设 2026/2/26 23:44:18

基于STM32的仓库温湿度数据获取系统

基于STM32的仓库温湿度数据获取系统 第一章 绪论 传统仓库温湿度管理依赖人工手持仪器巡检,存在数据采集频率低、人工成本高、数据易遗漏篡改、无法实时掌握全域温湿度状态等问题,尤其在大型仓储场景中,易因局部温湿度超标导致货物霉变、失效…

作者头像 李华
网站建设 2026/2/7 16:06:11

基于STM32的仓库环境监测系统的设计与实现

基于STM32的仓库环境监测系统的设计与实现 第一章 绪论 传统仓库环境监测多依赖人工巡检,存在数据实时性差、监测维度单一、异常预警滞后等问题,易因温湿度超标、有害气体泄漏、火灾隐患等导致货物损毁,难以满足现代化仓储的精细化管理需求…

作者头像 李华