日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

如何处理GPU训练显存不足[memory isnapos;t enough][alloc failed][out of memory]

發布時間:2023/12/8 编程问答 71 豆豆
生活随笔 收集整理的這篇文章主要介紹了 如何处理GPU训练显存不足[memory isnapos;t enough][alloc failed][out of memory] 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

【現象描述】

GPU上網絡運行過程中出現OOM(顯存不足),報錯日志中有如下信息:

cudaMalloc failed, ret[2], out of memory

或者:

memory isn't enough and alloc failed

【原因分析】

網絡訓練過錯中出現顯存不足的原因很多,后續遇到我會持續補充,當前遇到的一些原因如下:

1.卡被占用,導致可用顯存變小了。

2.網絡訓練batchsize過大。

3.輸入數據的shape是變化的(輸入數據動態shape)。

4.輸出結果的tensor保存起來了。

5.網絡中的算子里出現顯存泄漏(算子里每次launch都申請顯存,并且不釋放)。

【排查步驟和解決方法】

步驟1:執行前使用命令nvidia-smi查看卡的使用狀態,是否有被占用以及被占用的大小,剩下可用顯存有多大。

步驟2:排查訓練的batchsize是否過大,可以逐步縮小batch,如果覺得batch不夠大,還是出現OOM,則排除這個原因。

步驟3:確認輸入數據是否是動態shape,當前動態shape還不支持輸入shape可變,因為針對這種場景,每次step訓練都會編譯新圖,導致顯存不斷申請最后OOM,可以通過圖的個數是不是不斷増長來判斷。(context.set_context(save_graphs=True),然后觀察*_validate*.ir這一類ir是不是一直在增多)

步驟4:輸出tensor里會掛接device上的地址,方便print時同步device數據輸出,在tensor析構的時候會釋放device地址,因此如果每次step訓練都把輸出tensor保存起來的話,導致tensor不會析構,隨著訓練step的增加則會OOM。

案例代碼:

losses=[] for i in range(steps):loss = train_network()losses.append(loss)

該案例代碼將圖的執行結果loss放到全局losses中存儲,因此每次循環都會保存loss的device地址,隨著訓練次數的增加可能會導致OOM。如果有存儲圖輸出結果的訴求,可以轉化成asnumpy后保存,改成loss = train_network().asnumpy(),loss經過asnumpy后拷貝device到host后會釋放掉device的地址。

步驟5:前面步驟確認都沒有問題的話,則有可能是算子實現bug,這塊需要對算子實現有一定的基礎了解,可以排查下是否有新增算子,算子里是否有申請顯存的操作導致顯存泄漏。

案例代碼:

bool Launch(const std::vector<AddressPtr> &inputs, const std::vector<AddressPtr> &workspace,const std::vector<AddressPtr> &outputs, void *stream_ptr) override {T *input = GetDeviceAddress<T>(inputs, 0);S *indices = GetDeviceAddress<S>(inputs, 1);T *updates = GetDeviceAddress<T>(inputs, 2);T *output = GetDeviceAddress<T>(outputs, 0);const size_t indices_len = sizeof(S) * out_strides_.size();void *indices_stride_work =?device::gpu::GPUMemoryAllocator::GetInstance().AllocTensorMem(indices_len);if (indices_stride_work == nullptr) {MS_LOG(EXCEPTION) << "Failed to alloc indices_stride_work, size: " << indices_len;}

每次launch都調用內存池接口AllocTensorMem申請內存,導致隨著訓練step增加出現OOM,可以搜索代碼查看算子的Launch中是否有調用AllocTensorMem函數。

步驟6:前面的幾種可能原因都排查沒有問題的話,需要MindSpore開發人員詳細分析了,context.set_context(save_graphs=True)同時export GLOG_v=1保存執行日志,將保存的圖和日志打包發給開發人員排查確認。

【建議與總結】

1.輸出tensor一般不建議保存起來,如果需要保存,可以保存asnumpy后的對象,tensor經過asnumpy后拷貝device到host后會釋放掉device的地址。

2.算子實現邏輯不應該出現申請顯存的邏輯,一般都可以通過workspace來實現臨時device地址存儲的目的。上面的案例修改方案參考:https://gitee.com/mindspore/mindspore/pulls/25633

總結

以上是生活随笔為你收集整理的如何处理GPU训练显存不足[memory isnapos;t enough][alloc failed][out of memory]的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。