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

如何在运行的Jupyter Notebook中释放TensorFlow 2.17.0占用的NVIDIA GPU内存?

如何在运行的Jupyter Notebook中释放TensorFlow 2.17.0占用的NVIDIA GPU内存?

我完全懂你这种反复重启kernel的痛苦——加载数据花半天,调参没几次就爆显存,太折腾了!结合你的场景(GCE Debian机器、Conda kernel、Jupyter里反复跑模型调参),给你几个实用的解决方案,不用重启kernel也能释放GPU内存:


1. 每次训练前彻底清理旧模型与会话资源

你之前可能只跑了tf.keras.backend.clear_session()和gc.collect(),但漏了手动删除模型相关的变量!TensorFlow有时候会因为这些变量被引用,导致显存里的资源“赖着不走”。每次运行训练细胞前,先执行这段代码:

import tensorflow as tf
import gc

# 清除Keras的全局会话
tf.keras.backend.clear_session()

# 手动删除之前的模型、训练历史变量(如果存在)
if 'model' in locals():
    del model
if 'history' in locals():
    del history

# 强制触发Python垃圾回收
gc.collect()

为什么有用:手动删除model和history后,切断了Python对TensorFlow显存资源的引用,再配合clear_session清除Keras的内部状态,垃圾回收器就能真正把显存里的旧模型资源回收掉。


2. 启用TensorFlow动态显存分配(必试!)

默认情况下TensorFlow会一次性占满GPU的大部分显存,启用内存增长模式后,它会根据训练需要动态分配显存,不用的资源也会及时释放,从根源减少显存累积。

把这段代码放在第一个加载数据的细胞最开头(必须在import TensorFlow或任何模型操作之前执行):

import tensorflow as tf

# 检测可用GPU
gpus = tf.config.list_physical_devices('GPU')
if gpus:
    try:
        # 为每个GPU启用动态显存分配
        for gpu in gpus:
            tf.config.experimental.set_memory_growth(gpu, True)
        logical_gpus = tf.config.list_logical_devices('GPU')
        print(f"{len(gpus)} 个物理GPU,{len(logical_gpus)} 个逻辑GPU")
    except RuntimeError as e:
        # 内存增长模式必须在GPU初始化前设置,所以要放在最开头
        print(e)

为什么有用:这样TensorFlow不会一开始就把显存占满,每次训练结束后会主动释放不用的显存空间,多次调参的显存占用就不会越积越多。


3. 把训练逻辑封装成函数(进阶优化)

把模型定义和训练过程都放进函数里,利用Python的局部变量生命周期自动回收资源。这样每次训练结束后,函数内部的模型变量会被自动销毁,TensorFlow很难再持有显存引用:

def train_model(img_size, categories, train_data, val_data, lr=0.0001, epochs=20, batch_size=32):
    import tensorflow as tf
    from tensorflow.keras import Sequential
    from tensorflow.keras.layers import Dense, Dropout, Flatten, Input
    from tensorflow.keras.optimizers import Adam

    train_images, train_labels = train_data
    validate_images, validate_labels = val_data

    # 在函数内部定义模型(局部变量)
    model = Sequential([
        Input(shape=(img_size, img_size, 3)),
        Flatten(),
        Dense(256, activation='relu'),
        Dropout(0.4),
        Dense(128, activation='relu'),
        Dense(64, activation='relu'),
        Dense(len(categories), activation='softmax')
    ])
    model.compile(optimizer=Adam(learning_rate=lr), 
                  loss='sparse_categorical_crossentropy', 
                  metrics=['accuracy'])

    # 执行训练
    history = model.fit(train_images, 
                        train_labels, 
                        epochs=epochs,
                        batch_size=batch_size,
                        validation_data=(validate_images, validate_labels)) 
    return history

每次调参时,先执行清理步骤,再调用函数:

# 先清理旧资源
tf.keras.backend.clear_session()
if 'model' in locals(): del model
if 'history' in locals(): del history
gc.collect()

# 传入新的超参数开始训练
history = train_model(img_size, categories, (train_images, train_labels), 
                      (validate_images, validate_labels), lr=0.00005, epochs=15)

4. 尝试使用cuda_malloc_async显存分配器

错误提示里提到的TF_GPU_ALLOCATOR=cuda_malloc_async确实能缓解显存碎片问题,但要注意设置时机:必须在任何TensorFlow操作之前设置环境变量。

把这段代码放在第一个细胞的最最开头(甚至在import TensorFlow之前):

import os
os.environ['TF_GPU_ALLOCATOR'] = 'cuda_malloc_async'

# 之后再import TensorFlow和加载数据
import tensorflow as tf
# ... 加载数据的代码 ...

注意:如果已经import过TensorFlow再设置这个环境变量,是不会生效的,所以必须第一次运行第一个细胞时就执行这段。


总结最省心的组合方案

  1. 第一个细胞开头启用动态显存增长模式;
  2. 每次运行训练细胞前,执行清理旧变量+clear_session+gc.collect;
  3. 配合把训练逻辑封装成函数,基本能彻底解决显存累积的问题,不用再重启kernel啦!

备注:内容来源于stack exchange,提问作者Ennio

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.14 09:09:32