深度學習框架內存不夠解決思路

本文只是記錄下有關內存不夠的解決思路,寫得比較淺,如果有其他方法或者思考也希望大伙兒分享,在這裡只拋磚引玉:p

1. Caffe內存不夠的例子

在一台弱機上,跑caffe的時候內存不夠也是理所當然。比方用Caffe時做infer會出現如下報錯:

---------- Prediction for ./examples/images/cat.jpg ----------F0410 20:06:03.651886 14365 syncedmem.hpp:33] Check failed: *ptr host allocation of size 3763200 failed*** Check failure stack trace: *** @ 0x76b978a4 (unknown) @ 0x76b9772c (unknown) @ 0x76b9708c (unknown) @ 0x76b9a9a8 (unknown) @ 0x76eb066c caffe::SyncedMemory::mutable_cpu_data() @ 0x76d750c8 caffe::Blob<>::mutable_cpu_data() @ 0x76e3039c caffe::PoolingLayer<>::Forward_cpu() @ 0x76e762cc caffe::Net<>::ForwardFromTo() @ 0x76e764a4 caffe::Net<>::Forward() @ 0x14dd8 Classifier::Predict() @ 0x14f58 Classifier::Classify() @ 0x138e4 main @ 0x756db294 (unknown)Aborted

通過find -name syncedmem.hpp命令查到build目錄下的代碼。打開可以看到:

#ifdef USE_MKL *ptr = mkl_malloc(size ? size:1, 64);#else *ptr = malloc(size);#endif *use_cuda = false; CHECK(*ptr) << "host allocation of size " << size << " failed";}

2. 解決思路總結

在caffe的issue搜到如下問題:

  • syncedmem.hpp: Check failed: *ptr host allocation of size 158297088 failed · Issue #2474 · BVLC/caffe

    syncedmem.hpp: Check failed: *ptr host allocation of size 158297088 failed · Issue #2474 · BVLC/caffe

根據該鏈接,總結並想出如下幾個方案:

2.1 換成64 bit操作系統

換成64bit的操作系統解決。不同位數的操作系統對支持的內存大小不同。有如下兩種情況:

  1. 當前內存大於操作系統該位數支持的內存。這樣有些內存資源就用不上了。這時候換成64 bit的操作系統,或許就能解決內存不夠的問題;
  2. 當前內存小於操作系統該位數支持的內存。讓內存達到當前系統的最大支持內存,買更多內存條,或者用更大內存條替換現有的小內存條。

這樣,cover住了test或者train時候需要的內存,問題就得到了解決。

2.2 增加swap area

通過增加swap area解決。操作系統的交換分區(swap area)是作為內存不足(或內存較低)時,將部分不常用的內存交換出來的備用區域。如果說內存是汽油,內存條就相當於油箱,交換區域則相當於備用油箱。Ubuntu Linux安裝時可以在磁碟上划出一個分區用作內存交換區域。文件則介紹如何使用文件作為內存交換區域。這兩種方法在使用效果上沒有太大區別,但文件可以在分區之後創建,且調整大小更容易,所以這種方案更加靈活。

參考:如何在Linux上使用文件作為內存交換區(Swap Area) - Linux系統教程

如何在Linux上使用文件作為內存交換區(Swap Area)

1、Windows 下有兩個超大文件,分別是虛擬內存和休眠緩存文件。而linux下只用一個swap分區(文件)兼備這兩個功能,如果你內存夠大、不想要休眠,可以考慮不要這個分區(文件);

2、用不著那麼糾結什麼時候會用到swap,在Ubuntu下有個明確的比例:60%,即實際內存使用60%的時候開始使用swap。並且這個比例可以自己調節。

休眠時必須。其他,以防萬一,程序載入到內存,或者運行時申請內存,說不定就直接崩潰了。再大的內存都沒用。比率是不要參考的。大內存的話,隨便給點swap就夠。

參考:我就不明白了,為什麼還要swap分區? - 查看主題 ? Ubuntu中文論壇

我就不明白了,為什麼還要swap分區? - 查看主題 ? Ubuntu中文論壇

關於如何設置swap space(即swap area),有用gparted的,以及命令的,具體參考該鏈接:

  • How to increase swap space? - Ask Ubuntu

    How to increase swap space?

2.3 用等效的小模型替代大模型

比方能達到同樣或近似性能(準確率、實時性)下,用更小的模型替代大模型,或者用多個小卷積核替代大卷積核等等。

2.4 壓縮圖像文件

對圖像壓縮,比方H.264壓縮,縮小圖像文件的大小。說白了就是在可接受範圍內降低質量。比方用格式工廠或者在線的一些圖像壓縮軟體。

2.5 減少batch size

在train和test的時候可以減少batch size,因為默認情況下,優化的方法是隨機梯度下降(SGD,按理說SGD做每次參數更新是基於一個樣本,但實際上在很多框架中都是基於大於一個樣本的batch來實現的,嚴格來說不應該叫做SGD,而是mini-batch Gradient Descent),每次做參數更新的時候是基於這個batch的所有樣本做iteration的,所以調小這次載入到內存的數據就少(我想的,也有人提到了)。

但這也不能保證,如果是預測單張圖像還好說,因為不知道當前框架一次會載入多少圖像,是每個batch載入,還是整個訓練集或測試集完整載入。不過一般來說,調小batch size還是有作用的。

2.6 用內存利用率高的框架

社區里有人說用Keras替代caffe後,跑同樣的模型該問題得到解決。或使用MXNet等框架,某些框架底層做了數學或者工程上的特別優化。

2.7 加更大更多內存

在保證系統支持的情況下插更多更大的內存條。有人反應該問題可以解決,但當數據量再次增大也會出現同樣的問題。

2.8 特別的數據格式

某些框架(keras)在使用前需要將input的數據轉換為該框架的特別數據格式,如果能事先將數據轉換好,或許就不會因為沒有轉換而導致將全部未轉換的數據載入出現內存不夠的問題了。

當然,這個首先是要確認出現內存不夠的問題是在數據轉換階段產生的。

使用HDF5數據格式。HDF5格式的功能之一是能夠使用大型數據集直接從硬碟不需要載入所有數據到內存中。我想使用相同的數據集有不同的框架,目前hdf5大多是支持的格式。

以上,拋磚引玉嘍;p,希望有小夥伴提出更多更好的方案!


推薦閱讀:

機器學習筆記-支持向量機(SVM)(一)
<Reinforcement Learning for Relation Classification from Noisy Data>閱讀筆記
機器學習演算法面試小結
Siamese network 孿生神經網路--一個簡單神奇的結構
關於不平衡數據集以及代價敏感學習的探討

TAG:深度學習DeepLearning | 機器學習 | 神經網路 |