從TensorFlow被kill到增加Swap分區

背景

最近,Gemfield在使用TensorFlow訓練模型時,tensorflow程序會突然被kill,而且console的輸出日誌就顯示killed這一個單詞,連一點其它的上下文提示都沒有。其實,這就是TensorFlow所需的內存資源不夠了。

簡介

一般來說,有2種資源的不足會導致TensorFlow退出:

  1. 一種是TensorFlow對於顯存不足的反應,TensorFlow程序運行起來後,會列印一堆申請顯存的log(這是由log_device_placement=True的session參數決定的),然後逐漸的,顯存分配殆盡,TensorFlow打出Out of memory的錯誤然後就退出了。
  2. 一種是TensorFlow對於內存不足的反應,確切說,是Linux內核對TensorFlow程序佔用太多內存的反應。Linux內核一旦因為內存資源不足而生氣的時候,會使用OOM killer將佔用內存最多的進程殺掉。這種情況下,TensorFlow的python程序根本就來不及顯示相關的內存日誌,直接在呼喊出killed這一個簡短有力的詞語後,就game over了。如果不提前掌握這個背景的話,你可真是會手足無措啊。這種情況下,你可以使用dmesg命令查看到Linux內核相關的OOM日誌,就像下面這樣:

[206009.173075] Out of memory: Kill process 17718 (python) score 848 or sacrifice child[206009.173197] Killed process 17718 (python) total-vm:56701592kB, anon-rss:14454984kB, file-rss:149476kB, shmem-rss:534528kB[206009.734100] oom_reaper: reaped process 17718 (python), now anon-rss:0kB, file-rss:158000kB, shmem-rss:534528kB[207045.699687] perf: interrupt took too long (8044 > 7760), lowering kernel.perf_event_max_sample_rate to 24750[207320.694565] perf: interrupt took too long (10109 > 10055), lowering kernel.perf_event_max_sample_rate to 19750[208618.112358] docker0: port 5(vethb5fe09b) entered blocking state[208618.112361] docker0: port 5(vethb5fe09b) entered disabled state[208618.112475] device vethb5fe09b entered promiscuous mode[208618.112621] IPv6: ADDRCONF(NETDEV_UP): vethb5fe09b: link is not ready......

解決方案

既然我們確定了是內存不足導致的問題(dmesg也能明確的顯示出kernel把佔了近10個GB的python進程給kill了),那我們的解決方案就有2個:

第一個是加大內存,將我的x99平台的內存從16GB增加到64GB;這個方案先放棄了,因為內存條漲價太猛,我買不起了;

第二個是增加swap分區,當然性能會降低,但不需要額外增加成本。所以Gemfield今天的選擇就是第二個方案。

1,先禁止掉swap功能:

gemfield@gemfield-ThinkPad:~$ sudo swapoff /swapfile

這個命令執行之後,如果你用free命令查看的話會發現swap分區的大小變為了0。

2,增加 /swapfile的大小:

gemfield@gemfield-ThinkPad:~$ sudo dd if=/dev/zero of=/swapfile bs=1M count=30720 oflag=append conv=notrunc

這個命令會在現有的/swapfile後面追加30GB,加上之前的2GB的swap分區,現在共有32個GB的swap分區了。如果按照固態硬碟128GB有300多塊錢來算的話,這個命令花了七八十塊錢呢。

3,設置這個文件為swap分區的掛載點:

gemfield@gemfield-ThinkPad:~$ sudo mkswap /swapfile

4,再次啟用swap

gemfield@gemfield-ThinkPad:~$ sudo swapon /swapfile

慶祝

慶祝個毛,這個內存問題剛解決完,顯存不夠的問題又來了,這次可真的是tensorflow自己輸出的log。我只好把batch size設置為1繼續苟且下去了。

推薦閱讀:

一篇不一樣的docker原理解析
docker內部的資源限制
在Ubuntu 16.04環境下安裝Docker-CE(附視頻教程)
生產環境中使用Docker Swarm的一些建議
Docker 重要更新: 原生支持多階段構建(multi-stage build)

TAG:TensorFlow | Docker | 深度學習DeepLearning |