如何与深度学习服务器优雅的交互?(长期更新)
0. 故事序言
如果有人問小夕:"小夕,要是人工智能的就業崗位一夜之間消失了,你會去轉行做什么呢?"
答曰:"當然是去做Linux運維啊23333"
小夕有一臺自己負責的GPU服務器,她可讓小夕操碎了心吶,真是好不容易把這嬌氣的小公舉拉扯大了。下面就向各位服務器寶寶的爸爸媽媽們傳授一下育女經驗,讓她早日成長為一個省心的深度學習服務器。
下面小夕將依次介紹:
1. 操作系統建議
如果你主要用tensorflow來作為你的深度學習框架,那么小夕還是建議安裝16.04服務器版。注意是服務器版!為什么呢?因為有很多顯卡的高版本驅動與桌面版的圖形界面不兼容,導致容易出現循環登陸問題,要解決循環登陸問題也是極其的麻煩,小夕曾經在所里配的筆記本上搗鼓過一周多,重裝10余次系統,嘗遍國內外各種方法,最終放棄╮(╯▽╰)╭
所以這一次小夕直接為服務器裝了ubuntu16.04的服務器版!注意服務器版是沒有圖形界面的,對shell不熟悉的童鞋要盡快打好基礎哦。果然,在服務器版下裝驅動裝cuda一路next,0errors,0warnings
由于小夕在高中時實在討厭炸了國產軟件全家桶對windows的狂轟濫炸,導致一遍遍的重復
while True:系統變亂系統變卡重裝系統的過程,于是大學里在一學長的誘惑下,成功入了mac的坑,從此整個世界都清凈了,同時對命令行(mac與linux都是基于posix標準,命令行/shell語法高度相似)的淪陷一發不可收拾。。。(好像又跑題了?咳咳,小夕是想說,由于最近幾年很少接觸windows了,所以本文所列tricks可能對windows的兼容性略差。不過話說回來,做深度學習的日常怎么可能在windows上進行啊喂,不知道pytorch都懶得出windows版本了嘛。(放鉤--->
2. ssh免密快速登錄
遠程登錄最最方便的當然就是ssh啦。看小夕的一鍵登錄!
第一行黃色的是小夕的用戶名、電腦名、當前目錄。小夕設置的命令就是sshdlnlp,敲上這個命令直接進入服務器!當然,這個方法其實非常歪門邪道╮( ̄▽ ̄"")╭更加合理的是寫在ssh配置文件中。
不過,實現這個歪門邪道非常簡單,分兩步:
首先,將你的登錄命令寫入你的pc端的bash啟動腳本中。Mac系統為 ~/.bash_profile ,linux系統為 ~/.bashrc 。例如你的服務器用戶名為dlnlp,ip為102.10.60.23,那么就把這句登錄命令寫進去:
alias sshdlnlp="ssh dlnlp@102.10.60.23" 感謝評論區 @karajan1001 補充更科學強大的方法:將你的服務器信息寫入PC端的ssh配置文件中,配置文件位于 ~/.ssh/config ,例如你的服務器用戶名為dlnlp,ip為102.10.60.23,那么就把這句寫進去:Host dlnlp
[一個Tab]User dlnlp
[一個Tab]Hostname 102.10.60.23
[一個Tab]Port 22
(Host后面那個dlnlp是你起的名字,你也可以用更簡短的名字)
這樣可以 ssh dlnlp 也能快捷登錄,注意中間的空格哈。而且scp也更加方便了。
當然,登錄命令叫sshdlnlp,你也可以改成別的。保存后別忘 source ~/.bash_profile 或者 source ~/.bashrc 激活一下啟動腳本哦。
然后,經過第一步后,只需要再敲密碼就可以進入啦。但是懶癌至深的我們怎么能容忍敲密碼這么麻煩的事情呢!(劃掉,應該是小仙女怎么能容忍敲密碼這種事情呢)但是我們又不能犧牲服務器的安全性,那怎么辦呢?考驗大學里計算機網絡基礎的時候到了~
也很簡單,把你PC端的ssh公鑰寫入服務器的ssh信任列表里就可以啦。首先用`ssh-keygen`命令生成rsa密鑰對(生成一只私鑰和一只公鑰),一路enter即可,但是注意:
之前有已經生成過的同學在此處就選擇n吧,沒有生成過的同學就一路next~
然后去 ~/.ssh/ 文件夾下將公鑰發送到服務器上的某文件夾里:
然后去服務器上,把你PC端的公鑰丟進ssh信任列表:
cat id_rsa.pub >> ~/.ssh/authorized_keys好啦~搞定啦,再回到你的PC端登錄試試吧,是不是連輸入密碼都省掉啦。
3. 內網穿透(跨網段訪問服務器)
但是注意哦,如果你的服務器是在局域網內,那你的PC離開這個局域網的時候當然就找不到你的服務器啦。想要在家里用GPU服務器?很簡單,小夕教你分分鐘內網穿透!
在內網穿透方面,小夕試了好幾種方案后,感覺還是花生殼對新手最友好也最穩定。我們的內網穿透只需要將服務器內網ip以及22端口號(即ssh端口號)映射到外網ip的某個端口號。這個過程使用花生殼非常簡單,在網上有很多教程,小夕就不啰嗦啦。之后我們要做的就是將這個外網ip和端口號也封裝成一條命令,比如花生殼分配給我們的外網ip是103.44.145.240,端口是12560,那么只需要把這個寫入客戶端shell啟動腳本:
alias sshdlnlp_remote="ssh -p 12560 dlnlp@103.44.145.240" (別忘用source刷新啟動腳本)之后就可以在世界各地用一條命令訪問你的gpu服務器啦。
---- 10.19 更新 ----
放棄花生殼了,改用更穩定并且開源免費的frp了,當然這個需要你事先有一臺外網服務器,推薦阿里云(學生每月10元)。在你的外網服務器上用frp搭一個反向代理超級容易,傻子都能學會,去frp的github看一下吧~親測比花生殼好用最少一萬倍,并且超級穩定。
4. 文件傳輸與同步
對于一次性的文件傳輸,這方面最簡單的當然還是直接使用scp命令啦,文件夾和文件都能輕松傳輸。
但是我們做深度學習的話,在服務器端大面積改代碼、重量級調試的話還是不方便,畢竟服務器上沒有圖形界面,大部分人還是用不慣vim的,那么能不能在PC端用漂亮的編輯器修改代碼,將修改結果實時的同步到服務器端呢?當然可以!這里小夕推薦文件同步神器syncthing。
剩下的就是傻瓜式配置啦。記得要更改文件夾刷新頻率哦(默認是60秒,我們可以改的短一點,比如3秒),這樣在客戶端我們用漂亮的文本編輯器對代碼的改動就能實時的同步到服務器上啦,在服務器端就只需要負責運行就可以咯。
5. 多開發環境管理
如果不幸你的GPU服務器并不是你一個人用,那么這時多人(尤其是混入小白多話)經常把服務器默認的python環境弄的烏煙瘴氣,比如有人用python2,有人用python3,有人用tensorflow1.3,有人用0.12等...最后導致大家的程序全跑崩了。
所以在服務器端管理深度學習的開發環境是極其必要的,這里anaconda直接搞定!每個人建立和管理自己的開發環境,包括python版本、各種庫的版本等,互不干擾。而且在發布project時,也方便直接將環境導出為requirements文件,免得自己去手寫啦。
6. 多任務管理(并行調參)
如果你的服務器上有多個GPU,或者你的任務消耗GPU資源不多,那么并行的訓練模型調參數是極大提高開發效率的!這里小夕給出幾種場景下的常用方案:
1、比如我們在服務器上除了訓練還要接著干別的事情(比如還要搗鼓一下貪吃蛇什么的),那么我們就可以直接將訓練任務掛后臺。具體如下。
在linux中,在命令后面加上 & 符號可以將命令在后臺執行,為了能看到訓練日志,我們當時還需要輸出重定向(否則會打印到屏幕上干擾正常工作的),所以比如我們調batchsize參數時可以這樣:
dlnlp@ubuntu:~$ python train.py --batchsize=16 > log_batch16.txt &當然再掛上其他batchsize大小,如:
dlnlp@ubuntu:~$ python train.py --batchsize=16 > log_batch16.txt & dlnlp@ubuntu:~$ python train.py --batchsize=64 > log_batch64.txt & dlnlp@ubuntu:~$ python train.py --batchsize=128 > log_batch128.txt &通過 jobs 命令可以看到后臺任務的運行狀況(running、stopped等),通過 bg [任務號] 可以讓后臺stopped的命令繼續running,通過 fg [任務號] 可以讓后臺的任務來前臺執行。對于前臺已經執行起來的任務,可以 ctrl+z 來丟進后臺(丟后臺時stop了的話用bg讓其run起來)。
感謝微信用戶A Bad Candy在微信訂閱號后臺留言提醒上面的丟后臺方法會在ssh斷開連接后進程終止,因此:如果我們還不希望ssh斷開后導致訓練任務終止,那么需要再在命令前面加上 nohup 。如:
dlnlp@ubuntu:~$ nohup python train.py --batchsize=16 > log_batch16.txt &2、如果我們特別著急,不僅要并行掛著很多訓練任務,而且都要實時的監控它們的訓練進展,那么使用 screen命令吧,這個命令就相當于可以讓你同時開很多個窗口(就像桌面上那樣,你可以開很多應用程序的很多窗口),而且多個窗口之間可以輕松切換,同樣這種方法不會因為ssh的斷開而停止訓練任務。
具體的操作可以直接在linux下 man screen 來查看screen命令的幫助文檔。英文恐懼癥的童鞋可以看本文參考文獻[1]。
7. 睡覺調參模式(串行調參)
大部分場合下我們沒有那么多充裕的GPU可以用,我們一般只能一次掛一個任務,但是我們又有很重的調參任務,那怎么辦呢?
依然很簡單啦,首先,裝好python-fire這個工具。
它可以非常輕松的將你的python程序變成命令行程序,并且可以輕松的將你要調的參數封裝成命令行參數的形式。
然后,寫一個調參shell腳本,把你要調的參數全都寫進去!比如就像這樣:
(當然別忘在代碼里將訓練的summary寫到某個文件里)
然后就可以掛上這個腳本去睡覺啦~睡到天亮發現各個最優參數都找到了,超級開心有木有。
8. 關于jupyter notebook
jupyter notebook這個神器小夕在歷史文章中寫過啦,也是一個重量級調參神器!或者直接可以說深度學習神器!在服務器端依然犀利的無可替代,只需要如下的tricks。
1、服務器端開啟jupyter notebook后
然后復制最后那一行的 token=xxx ,這個token就是遠程訪問的密碼!同時記下 最后那行顯示的端口號 8888(因為如果服務器上同時開多個的話,端口號就不一定是8888了哦),然后去PC端做一個端口映射!即通過ssh隧道來將服務器端的8888端口號映射到本地(PC端)的某個端口(如1234):
ssh -L 1234:localhost:8888 dlnlp@102.10.60.23(這個操作同樣可以用于遠程監視服務器端tensorboard)
這時就可以在PC端的瀏覽器
http://localhost:1234直接訪問服務器上的jupyter notebook啦~當然,訪問時會讓你輸入密碼,這時就輸入之前記下的那個token哦。
2、讓jupyer notebook跟anaconda開發環境融合。
默認的情況下jupyter notebook是運行在系統默認環境里的,如果要讓它運行在我們自己用ananconda創建的環境中,要進入那個環境中,然后安裝 nb_conda 這個庫:
conda install nb_conda這時再開啟jupyter notebook就能選擇在我們這個環境里運行代碼啦。
9. 單任務全霸占模式
有時我們的訓練任務非常重要且急迫,且絕對不允許被別人擠崩,或者我們明知要占用全部GPU資源了,那么這時我們就可以。。。emmm事先說明,非必要時刻請勿頻繁使用哦:
使用linux中的 run-one 命令,這個命令可以保證同一條命令最多同時運行一個。比如 run-one python xxx 就會只允許運行一個python程序,后來的python程序在這個python程序執行完畢前是得不到執行的(一執行就會出錯返回)。所以我們可以寫入.bashrc:
alias python='run-one python'(別忘source激活哦)
這時
看,我通過將第一個python掛到后臺了,后面的python完全執行不起來。除非前一個python結束。(所以其他小伙伴可能以為自己的程序出問題了,然后emmm陷入了無盡的困惑)
參考文獻
[1] 跑深度學習代碼在linux服務器上的常用操作(ssh,screen,tensorboard,jupyter notebook)
訂閱號精彩評論
總結
以上是生活随笔為你收集整理的如何与深度学习服务器优雅的交互?(长期更新)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 我拿模型当朋友,模型却想泄漏我的隐私?
- 下一篇: 梳理百年深度学习发展史-七月在线机器学习