#最佳实践 显存占用 85% 算是榨干 通俗来说: - **GPU 的显存(VRAM)**,类似于电脑的内存(RAM),但它是显卡上的专用内存,专门给**GPU**使用。 - CPU 的内存(RAM)用于处理一般数据和代码执行。 - **GPU 显存**则用于专门存放 GPU 运算需要的数据,比如模型参数、数据输入、输出结果、梯度信息等。 --- ## 📌 为什么训练模型时显存经常不够用? 因为模型训练时需要把以下内容全部装进 GPU 显存中: - **模型本身的参数**:模型越大,占用显存越多。 - **输入的数据**(如token化后的文本数据)。 - **中间结果与梯度信息**(用于反向传播和更新参数的计算)。 - **优化器信息**(如 Adam 优化器会额外存储一部分数据)。 当你的任务特别大(比如大模型、大批次数据)或打开了额外的优化选项(如 Liger、FlashAttention 等),都会导致 GPU 显存需求大幅增加,可能会超出 GPU 提供的显存容量,引发显存不足。 --- ## 🚩 举个简单例子 |项目|占用的 GPU 显存(示例)| |---|---| |模型参数(Qwen 1.5B)|大约 3~5GB 左右| |数据输入 (Batch)|大约 2~4GB 左右| |梯度计算、中间结果|大约 4~8GB 左右| |优化器状态|大约 2~4GB 左右| |Liger 优化|额外的显存开销(1~3GB以上)| 当这些数据全部加载后,你的 GPU 显存(24GB)可能就不够用了。 --- ## 🚩 因此 - 如果出现显存不足,就应当适当关闭一些占用显存的优化(如`use_liger`)。 - 或者减小单次训练的数据量(如减小 batch size)。 现在关闭`use_liger`即可有效降低显存占用。 调整 `per_device_train_batch_size`(单GPU训练时每个GPU上训练的批次大小)的核心目的是: > 在充分利用GPU显存且避免显存溢出的前提下,**最大化批次大小以提升训练吞吐量**。 --- ## 🚩 如何确定最佳 `per_device_train_batch_size`? 可以通过以下具体方法进行判断: ### 🔹 方法一:逐步尝试法(最常用、最简单) 逐渐增加批次大小(如 2→4→8→16),观察训练时GPU显存占用情况: - 当显存稳定且利用率较高(80%~90%以上),且没有出现OOM(显存溢出)时,批次大小就是合适的。 - 若出现OOM错误,则往下降一个档次。 例如,推荐的步骤: ```bash --per_device_train_batch_size 2 (目前情况) ✅ --per_device_train_batch_size 4 (测试,如无OOM,继续尝试更大) --per_device_train_batch_size 8 (测试,如出现OOM,回退到4) ``` --- ### 🔹 方法二:显存计算经验法(快速估算) 可根据模型大小和序列长度进行粗略推算: 经验公式(以Qwen1.5B模型、4096序列长度、fp16为例): - fp16模式下,每个参数约占用2字节。 - 每个样本内存需求约估算为: - **参数内存**:1.5B × 2 bytes = 3GB(约等于模型参数存储) - **激活值内存**:显存占用主要由激活值决定,通常可达模型参数大小的数倍。 通常**Qwen类模型**经验估计激活内存为: `参数内存 × 序列长度 ÷ 1000` 左右。 - 举例: ```Java 参数内存 = 3GB 激活内存 ≈ 3GB × 4096 / 1000 ≈ 12.3GB 单个样本内存占用 ≈ 3GB (参数) + 12.3GB (激活) ≈ 15GB ``` - 你的GPU是96GB,可推算最多大概容纳: `96GB ÷ 15GB ≈ 6个样本` 考虑训练时还要预留一些缓存空间,保守建议: - **批次大小设置为4-6比较合适**。 --- ### 🔹 方法三:观察GPU状态动态监控法(推荐方式) 训练时,实时监控GPU显存状态: ```bash watch -n 1 nvidia-smi ``` 理想的显存利用率范围: - **显存使用率:85%~95%** 是最佳范围。 - 若低于70%,则表示显存利用不足,可以进一步增加批次大小。 - 若长期保持99%-100%,风险较大,可能随时OOM,应降低批次大小。 --- ## 🚩 综合推荐批次大小(针对你的配置) 你目前的配置: - GPU: H20-NVLink (96GB) 单卡 - 模型: Qwen2.5-1.5B (参数量适中) - 序列长度: 4096 - 精度模式: fp16(节省显存) 考虑以上因素: |现有批次大小|推荐批次大小|原因|预估显存占用率| |---|---|---|---| |2|**4~6**|较充分利用显存,效率更高|80% ~ 90% 左右| 你可以直接尝试: ```bash --per_device_train_batch_size 4 ``` - 如果训练顺利,显存利用合理 (~80%-90%),则可进一步尝试 `batch_size=6`。 - 如果4就OOM,则维持批次大小4即可。 --- ## 🚩 调整后预期效果 - 若批次大小从2调高至4,训练速度预计提升近乎2倍(训练时间缩短约一半)。 - 若能调高至6,则速度提升更多。 举例: |批次大小|每秒迭代次数|总耗时 (训练约68530步)| |---|---|---| |2(当前)|1.2 it/s|~15小时| |4(预计)|2.4 it/s左右|~7.5小时(缩短一半)| |6(预计)|3.6 it/s左右|~5小时内(大幅提速)| --- ## 🚩 总结(最佳实践) - 首先尝试 `per_device_train_batch_size=4`: - 观察显存占用率,若有余量再适当提高。 - 通过`nvidia-smi`监控显存,确保稳定运行且高效。 这种方式简单可靠,是确定最佳批次大小的最推荐方式。