You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何计算TensorFlow中训练单样本CNN所需的GPU内存

GPU显存不足排查:CNN训练内存计算遗漏点分析

我正尝试计算特定数据集上训练CNN所需的GPU内存(或通用计算方法),因为训练时出现显存不足,但无法定位原因。

实现的CNN模型

我用TensorFlow实现了如下CNN:

from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Conv2D, Dense, Flatten

model = Sequential()
model.add(Conv2D(16, (3,3), activation='relu', input_shape=(1491, 257,1)))
model.add(Conv2D(16, (3,3), activation='relu'))
model.add(Flatten())
model.add(Dense(128, activation='relu'))
model.add(Dense(1, activation='sigmoid'))

model.summary()

模型输出的summary信息:

Model: "sequential_1"
_________________________________________________________________
 Layer (type)                Output Shape              Param #   
=================================================================
 conv2d_2 (Conv2D)           (None, 1489, 255, 16)     160       
                                                                 
 conv2d_3 (Conv2D)           (None, 1487, 253, 16)     2320      
                                                                 
 flatten_1 (Flatten)         (None, 6019376)           0         
                                                                 
 dense_1 (Dense)             (None, 128)               770480256 
                                                                 
 dense_2 (Dense)             (None, 1)                 129       
                                                                 
=================================================================
Total params: 770482865 (2.87 GB)
Trainable params: 770482865 (2.87 GB)
Non-trainable params: 0 (0.00 Byte)

存储该模型需要2.87GB内存。

单样本训练内存计算

网络输入为1491x257x1张量,输入来自以下数据管道处理的wav文件:

data = data.map(preprocess)
data = data.cache()
data = data.shuffle(buffer_size=1000)
data = data.batch(1)
data = data.prefetch(1)

train = data.take(1)
test = data.skip(10).take(1)

preprocess函数会将每个wav文件转换为1491x257x1的频谱图(函数详情见文末)。

根据CNN内存消耗计算逻辑,单个数据元素前向传播所需内存为输入元素内存加上各层输出内存:

  • 单个输入元素内存:4*(1491*257*1) = 1,532,748字节(TensorFlow默认float32类型,占4字节)
  • 各层输出内存(Flatten仅重排数据,不计额外内存):4 * 输出维度

由此计算单样本前向传播所需内存:

4*(1491*257*1 + 1489*255*16 + 1487*253*16 + 128 + 1) Bytes

换算为GB:

4*(1491*257*1 + 1489*255*16 + 1487*253*16 + 128 + 1)/(1024**3) GB = 0.05 GB

单样本训练总GPU内存预估:模型内存+前向传播内存+反向传播内存(假设与前向一致),即2.87GB + 0.05GB + 0.05GB = 2.97GB。

数据集内存估算

我复现的是鸟类音频分类项目,原始文件占用0.4 GB内存。预处理后每个文件转为float32类型的1491x257x1频谱图:

  • 810个频谱图总内存:810 * 4 * (1491 * 257)/(1024 * 1024 * 1024) = 1.15GB
  • 数据管道设置了1000个元素的shuffle缓冲区,预估占用:1000 * 4 * (1491 * 257)/(1024 * 1024 * 1024) = 1.43GB

当前核算的最大内存占用为2.97GB + 0.40 GB + 1.43GB = 4.80GB,而我的GPU有9.29GB内存,剩余4.49GB,理论上单样本训练不应出现显存不足。我忽略了什么?


预处理函数详情

import tensorflow as tf 
import tensorflow_io as tfio

def preprocess(file_path, label): 
    wav = load_wav_16k_mono(file_path)
    wav = wav[:48000]
    zero_padding = tf.zeros([48000] - tf.shape(wav), dtype=tf.float32)
    wav = tf.concat([zero_padding, wav],0)
    spectrogram = tf.signal.stft(wav, frame_length=320, frame_step=32)
    spectrogram = tf.abs(spectrogram)
    spectrogram = tf.expand_dims(spectrogram, axis=2)
    return spectrogram, label

def load_wav_16k_mono(filename):
    # Load encoded wav file
    file_contents = tf.io.read_file(filename)
    # Decode wav (tensors by channels) 
    wav, sample_rate = tf.audio.decode_wav(file_contents, desired_channels=1)
    # Removes trailing axis
    wav = tf.squeeze(wav, axis=-1)
    sample_rate = tf.cast(sample_rate, dtype=tf.int64)
    # Goes from 44100Hz to 16000hz - amplitude of the audio signal
    wav = tfio.audio.resample(wav, rate_in=sample_rate, rate_out=16000)
    return wav

内容的提问来源于stack exchange,提问作者user1245262

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 18:55:20