BERT推理显存爆满?7个实用技巧教你快速优化!显存优化的最佳实践指南
如果只使用BERT进行推理得到词向量,但显存仍然爆满,以下几个建议可以帮助缓解显存问题:
-
分批处理(Batching):
即使是在推理阶段,也可以将输入数据分成较小的批次(batch),这样每次推理只处理较少的数据,从而减少显存占用。具体来说可以减小 batch size,逐步降低直到显存能够容纳。 -
减少输入序列长度:
BERT 的显存占用与输入序列的长度直接相关。可以尝试裁剪输入文本,使得序列长度减少。特别是对很长的文本,可以设置合理的最大长度(如128或256),从而减少计算需求。 -
使用梯度检查点(Gradient Checkpointing):
虽然主要用于训练,但在推理时可以通过减少内存开销来节省显存。可以通过调整模型以支持这种技术,减少中间计算结果的缓存。 -
半精度推理(FP16):
如果你的硬件支持,可以使用半精度浮点数(FP16)进行推理。许多深度学习框架(如 PyTorch)支持将模型加载为半精度,从而减少显存需求。这在大多数推理场景下对精度影响不大。 -
冻结部分层:
如果只需要较浅层的词向量,可以考虑冻结模型的某些层,只对前几层进行推理。例如,如果只需要基础的词向量特征,可以考虑只使用 BERT 的前几层,而不是整个模型。 -
使用更小的模型:
如果推理性能和速度比模型大小更重要,使用更小版本的 BERT,例如DistilBERT或ALBERT,可以大幅减少显存占用,同时还能保持不错的性能。 -
迁移到更大显存的设备:
如果硬件允许,尝试迁移到具有更多显存的GPU。对于BERT这样的模型,如果输入数据量大且显存瓶颈严重,可能需要考虑硬件升级。
如果这些方法还无法解决问题,可以分享你具体的代码片段,我可以帮你进一步优化和调整。
在运行代码时,显存逐步增加的情况,可能是因为在 for 循环中处理句子时,每次的计算结果并未及时释放,导致显存占用累积。这里有几个常见的问题及优化建议,可以帮助你减少显存占用,并防止显存泄露。
1. 确保不保留计算图:
在推理过程中,如果没有进行反向传播,则不需要保留计算图。因此,你可以在获取模型输出后使用 torch.no_grad(),以确保不会存储反向传播所需的中间计算结果,这样可以大幅减少显存占用。
优化代码如下:
def get_entity_encodings(sentence):model.eval() # 设置模型为评估模式with torch.no_grad(): # 不需要计算梯度... return e1_encoding, e2_encoding, tokens
这里通过 torch.no_grad() 关闭了梯度计算,不会为推理计算生成反向传播的计算图。
2. 释放显存(CUDA 清理):
在每次处理句子后,可以调用 torch.cuda.empty_cache() 来手动清理 CUDA 中未使用的显存,防止显存逐步累积。它不会影响当前运行的代码,但可以帮助释放不再需要的显存。
在循环中可以定期清理显存:
for idx, (sentence, label) in enumerate(tqdm(zip(train_sentence, train_sentence_label), total=len(train_sentence), desc="Processing sentences")):try:....# 定期释放 CUDA 显存if idx % 100 == 0:torch.cuda.empty_cache()except ValueError as e:print(f"跳过句子 {idx}: {e}")
3. Batching(批处理):
虽然你现在是在逐句处理,但可以考虑使用批处理来一次处理多个句子,减少模型前向传播的次数,这样能更有效地使用显存并加快处理速度。批处理的实现方式如下:
- 使用
DataLoader进行批次处理,调整batch_size以找到适合显存的大小。
from torch.utils.data import DataLoaderdataset = TensorDataset(inputs, sentence_labels, sentence_indices)
dataloader = DataLoader(dataset, batch_size=16, shuffle=True) # 调整 batch_size 以适应显存for batch in tqdm(dataloader, desc="Processing batches"):batch_inputs, batch_labels, batch_indices = batch# 批处理后的推理操作
4. 减少中间结果的存储:
目前的代码中,你存储了每一对实体编码。如果数据量较大,可以考虑在需要时才使用中间结果,而不是一直保存所有数据。例如,将这些中间结果保存到磁盘,或仅保存你确实需要的部分。
5. 使用更小的模型:
如果显存依然不够,可以尝试使用更小的模型,如 distilBERT 或 TinyBERT,它们的显存占用比 BERT-base 要小很多,且推理速度更快。
通过这些优化策略,你可以大幅减少推理过程中的显存占用,并防止显存泄漏导致的崩溃。
从图表中可以看出,尽管你使用了 torch.no_grad() 和 torch.cuda.empty_cache(),显存的占用仍然在逐步增加。这表明某些部分可能存在显存的积累,没有被正确释放。
可能的原因与解决方法:
-
BERT 模型输出的累积:
即使使用了torch.no_grad(),model(**inputs)仍然会返回last_hidden_state,这些可能会在每次循环时被保留在 GPU 中。因为你将e1_encodings和e2_encodings保存在列表中,而这些编码仍然在 GPU 中。解决方法:
- 在将
e1_enc和e2_enc保存到列表之前,将它们转移到 CPU。
修改如下:
e1_encodings.append(e1_enc.cpu()) e2_encodings.append(e2_enc.cpu()) - 在将
-
inputs和outputs没有被释放:
尽管torch.no_grad()防止了计算图的构建,但inputs和outputs仍然保留在 GPU 内存中,尤其是在循环内,这些 Tensor 没有被及时释放。解决方法:
- 在每次处理完后,手动删除不再使用的 Tensor,并调用
torch.cuda.empty_cache()来释放内存。
修改如下:
e1_enc, e2_enc, tokens = get_entity_encodings(sentence) e1_encodings.append(e1_enc.cpu()) # 将编码转移到 CPU e2_encodings.append(e2_enc.cpu()) # 将编码转移到 CPU sentence_labels.append(label) sentence_indices.append(idx)# 删除临时变量并释放显存 del e1_enc, e2_enc, tokens, inputs, outputs torch.cuda.empty_cache() - 在每次处理完后,手动删除不再使用的 Tensor,并调用
-
BERT 模型的缓慢累积:
有时模型的内部可能会缓存一些中间状态,特别是当有特殊处理时(例如特殊标记的调整)。解决方法:
- 考虑在每个批次的迭代过程中重新加载模型,以确保没有多余的缓存累积。比如,可以在每次处理一定数量的句子后,重新加载模型并继续处理。
-
定期监控内存并进行清理:
你可以通过手动监控 GPU 内存,检查是否有部分 Tensor 没有及时被释放。如果发现某些部分内存占用异常,可以通过分析相应的代码段来定位问题。
总结:
在每次迭代后,手动将结果转移到 CPU,并释放不再使用的 Tensor,同时调用 torch.cuda.empty_cache() 可以有效减小显存的逐步增长。你可以先尝试这些修改,观察是否有帮助。如果问题仍然存在,我们可以进一步分析可能的内存泄漏点。
相关文章:
BERT推理显存爆满?7个实用技巧教你快速优化!显存优化的最佳实践指南
如果只使用BERT进行推理得到词向量,但显存仍然爆满,以下几个建议可以帮助缓解显存问题: 分批处理(Batching): 即使是在推理阶段,也可以将输入数据分成较小的批次(batch)&…...
JS实现树形结构数据中特定节点及其子节点显示属性设置的技巧(可用于树形节点过滤筛选)
大家好,今天我要分享的是如何在树形结构的数据中,根据特定条件设置节点及其所有子节点的显示属性。在实际项目中,这种需求非常常见,特别是在需要动态展示和隐藏节点的情况下。下面我将通过一个具体的示例来讲解实现过程。 需求分析…...
第二证券:金价涨了!创一历史之最!
当地时间周四,金融商场进一步消化美联储大幅降息50个基点的利率抉择,认为这是为了完结美国经济“软着陆”的一次防备式降息,而非紧急应对阑珊风险的降息,加之当天公布的上星期初度申请赋闲救助人数低于预期,投资者对美…...
maxwell 输出消息到 kafka
文章目录 1、kafka-producer2、运行一个Docker容器,该容器内运行的是Zendesk的Maxwell工具,一个用于实时捕获MySQL数据库变更并将其发布到Kafka或其他消息系统的应用3、进入kafka容器内部4、tingshu_album 数据库中 新增数据5、tingshu_album 数据库中 更…...
青柠视频云——视频丢包(卡顿、花屏、绿屏)排查
一、问题说明 近期有客户反馈,接入平台的设备经常出来卡顿、花屏、录屏的情况,出现这样的场景很是尴尬。 客户是私有化部署在公网环境,于是我们联系客户,对问题进行追踪排查。 二、场景复现 我们现场情况确认的过程中,…...
单片机原理及应用
引言 单片机(Microcontroller Unit, MCU)作为现代电子技术的核心之一,广泛应用于工业自动化、消费电子、医疗设备、汽车电子、航空航天等多个领域。它集成了CPU(中央处理器)、存储器、输入输出接口及定时/计数器等功能…...
sql中拼接操作
SQL中的拼接操作 常用listagg聚合函数用法 也可用 XMLAGG代替上述操作 常用listagg聚合函数 LISTAGG(column, [separator]) WITHIN GROUP (ORDER BY order_by_clause)column:你想要连接起来的列。 [separator]:可选参数,用于指定列值之间的分…...
基于C语言+SQL Server2008实现(控制台)图书管理系统
第1章 概述 1.1项目背景 随着科技的发展,尤其是计算机技术的迅猛发展,图书馆管理的问题从以往的人工管理,到现在的电脑化,系统化,是对图书馆管理方法的质的飞跃,这些技术不仅让图书馆管理变得更加方便、快…...
Msf之Python分离免杀
Msf之Python分离免杀 ——XyLin. 成果展示: VT查杀率:8/73 (virustotal.com) 火绒和360可以过掉,但Windows Defender点开就寄掉了 提示:我用360测的时候,免杀过了,但360同时也申报了,估计要不了多久就寄…...
electron-updater实现electron全量版本更新
在 Electron 应用中使用 electron-updater 来实现自动更新功能时,通常你会在一个专门的模块或文件中管理更新逻辑。如果你想要使用 ES6 的 import 语法来引入 electron-updater,你需要确保你的项目已经配置好了支持 ES6 模块的构建工具(如 We…...
Mysql梳理6——order by排序
目录 6 order by排序 6.1 排序数据 6.2 单列排序 6.3 多行排列 6 order by排序 6.1 排序数据 使用ORDER BY字句排序 ASC(ascend):升序DESC(descend):降序 ORDER BY子句在SELECT语句的结尾 6.2 单列排序 如果没有使用排序操作,默认…...
Java设计模式—面向对象设计原则(三) -----> 依赖倒转原则DIP(完整详解,附有代码+案例)
文章目录 3.3 依赖倒转原则(DIP)3.3.1概述3.3.2 案例 3.3 依赖倒转原则(DIP) 依赖倒转原则:Dependency Inversion Principle,DIP 3.3.1概述 高层模块不应该依赖低层模块,两者都应该依赖其抽象;抽象不应该依赖细节,细…...
Linux操作系统 进程(3)
接上文 Linux进程优先级之后,我们了解到僵尸进程与孤儿进程的形成原因,既然是因为父进程没有接收子进程的退出状态导致的,那么我们该如何去获取子进程的退出状态呢?那本篇文章将围绕这个问题来解释进程。 环境 : vsco…...
QQ频道机器人零基础开发详解(基于QQ官方机器人文档)[第五期]
QQ频道机器人零基础开发详解(基于QQ官方机器人文档)[第五期] 第五期介绍:频道模块之接口授权管理和发言管理 目录 QQ频道机器人零基础开发详解(基于QQ官方机器人文档)[第五期]第五期介绍:频道模块之接口授权管理和发言管理获取机器人在频道可用权限列表…...
代码签名证书快速申请指南
申请代码签名证书是确保软件或应用程序在分发和安装过程中不被篡改的重要步骤。以下是详细的快速申请指南: 一、选择证书品牌和服务商 选择知名证书品牌:首先,选择一个国际知名的代码签名证书品牌,如GlobalSign、Digicert、Comod…...
安卓 uniapp跨端开发
HBuilder X 4.24 本地插件方式使用原生插件 例如 MT-TTS 地址PS: 播放 speek({text: ‘test’}) 应为 播放 speak({text: ‘test’})MT-TTS下载下来之后,将 nativeplugins 文件夹拷贝到 uniapp 项目根目录中manifest.json ---- App原生插件配置 运行 语音引擎测试文字转语音播…...
【高阶用法】uniapp的i18n多语言模块修复与增强(Typescript)
痛点 在i18n多语言模块使用过程中,发现下面几个问题,需要解决 1)uni-best框架下,$t功能函数无法实时的切换语言,可能跟使用有关 2)uni-best建议的translate方式在vue块外使用太繁琐,希望不用…...
SQL Server Data Tools (SSDT)入门教程
SSDT (SQL Server Data Tools) 是微软提供的一款用于开发、设计和管理SQL Server数据库的工具。它集成在Visual Studio中,允许开发人员和数据库管理员在统一的环境中进行数据库开发与管理。以下是关于SSDT的详细介绍: 1. 什么是SSDT? SQL S…...
窗户检测系统源码分享
窗户检测检测系统源码分享 [一条龙教学YOLOV8标注好的数据集一键训练_70全套改进创新点发刊_Web前端展示] 1.研究背景与意义 项目参考AAAI Association for the Advancement of Artificial Intelligence 项目来源AACV Association for the Advancement of Computer Vision …...
2.计算机网络基础
2. 计算机网络基础 (1) 计算机网络的定义 计算机网络是指将地理位置不同、具有独立功能的多个计算机系统通过通信线路和设备连接起来,以功能完善的网络软件实现网络中资源共享的系统。最简单的定义是:计算机网络是一些互相连接的、自治的计算机系统的集合。最庞大的计算机网…...
STM32F4基本定时器使用和原理详解
STM32F4基本定时器使用和原理详解 前言如何确定定时器挂载在哪条时钟线上配置及使用方法参数配置PrescalerCounter ModeCounter Periodauto-reload preloadTrigger Event Selection 中断配置生成的代码及使用方法初始化代码基本定时器触发DCA或者ADC的代码讲解中断代码定时启动…...
将对透视变换后的图像使用Otsu进行阈值化,来分离黑色和白色像素。这句话中的Otsu是什么意思?
Otsu 是一种自动阈值化方法,用于将图像分割为前景和背景。它通过最小化图像的类内方差或等价地最大化类间方差来选择最佳阈值。这种方法特别适用于图像的二值化处理,能够自动确定一个阈值,将图像中的像素分为黑色和白色两类。 Otsu 方法的原…...
OkHttp 中实现断点续传 demo
在 OkHttp 中实现断点续传主要通过以下步骤完成,核心是利用 HTTP 协议的 Range 请求头指定下载范围: 实现原理 Range 请求头:向服务器请求文件的特定字节范围(如 Range: bytes1024-) 本地文件记录:保存已…...
Python爬虫(二):爬虫完整流程
爬虫完整流程详解(7大核心步骤实战技巧) 一、爬虫完整工作流程 以下是爬虫开发的完整流程,我将结合具体技术点和实战经验展开说明: 1. 目标分析与前期准备 网站技术分析: 使用浏览器开发者工具(F12&…...
【生成模型】视频生成论文调研
工作清单 上游应用方向:控制、速度、时长、高动态、多主体驱动 类型工作基础模型WAN / WAN-VACE / HunyuanVideo控制条件轨迹控制ATI~镜头控制ReCamMaster~多主体驱动Phantom~音频驱动Let Them Talk: Audio-Driven Multi-Person Conversational Video Generation速…...
QT3D学习笔记——圆台、圆锥
类名作用Qt3DWindow3D渲染窗口容器QEntity场景中的实体(对象或容器)QCamera控制观察视角QPointLight点光源QConeMesh圆锥几何网格QTransform控制实体的位置/旋转/缩放QPhongMaterialPhong光照材质(定义颜色、反光等)QFirstPersonC…...
MyBatis中关于缓存的理解
MyBatis缓存 MyBatis系统当中默认定义两级缓存:一级缓存、二级缓存 默认情况下,只有一级缓存开启(sqlSession级别的缓存)二级缓存需要手动开启配置,需要局域namespace级别的缓存 一级缓存(本地缓存&#…...
Python竞赛环境搭建全攻略
Python环境搭建竞赛技术文章大纲 竞赛背景与意义 竞赛的目的与价值Python在竞赛中的应用场景环境搭建对竞赛效率的影响 竞赛环境需求分析 常见竞赛类型(算法、数据分析、机器学习等)不同竞赛对Python版本及库的要求硬件与操作系统的兼容性问题 Pyth…...
上位机开发过程中的设计模式体会(1):工厂方法模式、单例模式和生成器模式
简介 在我的 QT/C 开发工作中,合理运用设计模式极大地提高了代码的可维护性和可扩展性。本文将分享我在实际项目中应用的三种创造型模式:工厂方法模式、单例模式和生成器模式。 1. 工厂模式 (Factory Pattern) 应用场景 在我的 QT 项目中曾经有一个需…...
0x-3-Oracle 23 ai-sqlcl 25.1 集成安装-配置和优化
是不是受够了安装了oracle database之后sqlplus的简陋,无法删除无法上下翻页的苦恼。 可以安装readline和rlwrap插件的话,配置.bahs_profile后也能解决上下翻页这些,但是很多生产环境无法安装rpm包。 oracle提供了sqlcl免费许可,…...
