技術背景
在前面的博客中,我們大篇幅的使用到了Docker和Singularity這兩種常見的容器化編程環境解決方案,使得我們的各個編程環境能夠更好的隔離。如果要展開講解容器化編程環境的重要性的話,我們有可能會發現容器並不是那么的必須:比如解決python庫的依賴沖突問題,我們可以選擇使用python的virtualenv或者conda的虛擬環境;比如解決gcc的版本依賴沖突,我們可以手動配置和選擇對應的版本;比如對於我們沒有root權限和對外網絡的環境,想要安裝一些工具可以采用源碼編譯安裝。那么,這些種種的問題,如果我們采用Singularity的方案,就可以一次性的解決。而且容器化是一個趨勢,比如各種的機器學習框架都會提供容器版本的安裝方案,像MindSpore和Tensorflow等等。這里我們嘗試使用Singularity的容器def文件(類似於Docker的Dockerfile,而且兼容Docker的鏡像),去構造一個Pytorch專屬的編程環境。
環境准備
這里我們假設本地的容器環境是已經安裝完畢的,可以通過如下指令進行檢驗:
dechin@ubuntu2004:~/projects/pytorch$ singularity --version
singularity version 3.8.0-rc.1
建議至少使用3.5以上版本的Singularity,否則會有編譯不兼容的問題。關於Singularity的安裝與基本使用,可以參考這篇在Manjaro Linux上安裝Singularity的方法、以及在CentOS上安裝Singularity的方法,還有這篇用Singularity來配置MindSpore環境的博客。
制作def文件
Singularity的def文件類似於Docker的Dockerfile,用於定義一個容器鏡像,而在這個文件中我們除了指定基礎鏡像之外,還可以指定下載基礎鏡像之后要執行的配置項目。我們先看一個簡單例子:
dechin@ubuntu2004:~/projects/pytorch$ cat pytorch.def
Bootstrap: docker
From: ubuntu
%post
cp -a /etc/apt/sources.list /etc/apt/sources.list.bak
sed -i "s@http://.*archive.ubuntu.com@http://repo.huaweicloud.com@g" /etc/apt/sources.list
sed -i "s@http://.*security.ubuntu.com@http://repo.huaweicloud.com@g" /etc/apt/sources.list
apt-get -y update
apt -y install python
apt -y install python3-pip
pip3 install torch==1.8.1+cu111 torchvision==0.9.1+cu111 torchaudio==0.8.1 -f https://download.pytorch.org/whl/torch_stable.html
這個例子就實現了pytorch整個的容器化安裝流程,但是這里不建議大家直接使用我寫的這個def文件來制作鏡像,這里面最后一步安裝pytorch的指令,需要適配自己本地的環境進行調整。下面解釋一下這些指令的含義:
Bootstrap
用於指定下載的倉庫類型,建議是選取docker,因為這里面的鏡像是最多的。From
用於指定一個基礎鏡像的版本,因為ubuntu是一個使用比較廣泛的發行版,因此我們指定ubuntu的時候,腳本會自動從dockerhub上面尋找最新版本的ubuntu鏡像進行下載。當然我們也可以指定一個特殊的版本,比如可以指定為ubuntu:16.04
。%post
是在容器鏡像中執行的系統指令,這些指令執行完成后生成的文件等會被打包保存到我們的鏡像sif文件中。類似的指令還有%environment
,可用於配置export環境變量,還有%runscript
可用於執行一些腳本命令。- 從
cp
到apt-get update
這4個步驟,是在容器內更新系統鏡像源,我們采用的是華為雲的鏡像源https://mirrors.huaweicloud.com/,一般國內的鏡像源在使用apt下載東西的時候會有比較明顯的加速效果,當然這個鏡像源倉庫還有很多其他的源,比如pip源等等。 - 在這個鏡像文件中我們可以直接使用
apt
來安裝python和pip,但是注意安裝的時候要加上-y
的選項,這個選項可以幫助我們默認跳過需要手動確認的項目,我們知道在apt安裝的過程經常會暫停下來,要求輸入一個y
之后才能繼續往下安裝,但是這個在使用鏡像的時候是沒辦法支持手動的輸入的。 - 最后我們按照參考鏈接1中給出的安裝指令進行安裝,注意要匹配好自己的環境,本文采用的配置項目如下截圖所示:
構建sif文件
在完成上述步驟的鏡像配置文件后,可以用如下的指令進行鏡像的構建:
sudo singularity build pytorch.sif pytorch.def
在執行的過程中會有大量的信息彈出,我們只關注下開頭和結尾即可:
INFO: Starting build...
Getting image source signatures
Copying blob 345e3491a907 skipped: already exists
Copying blob 57671312ef6f skipped: already exists
Copying blob 5e9250ddb7d0 [--------------------------------------] 0.0b / 0.0b
Copying config 7c6bc52068 done
Writing manifest to image destination
Storing signatures
2021/06/15 09:44:57 info unpack layer: sha256:345e3491a907bb7c6f1bdddcf4a94284b8b6ddd77eb7d93f09432b17b20f2bbe
2021/06/15 09:44:58 info unpack layer: sha256:57671312ef6fdbecf340e5fed0fb0863350cd806c92b1fdd7978adbd02afc5c3
2021/06/15 09:44:58 info unpack layer: sha256:5e9250ddb7d0fa6d13302c7c3e6a0aa40390e42424caed1e5289077ee4054709
INFO: Running post scriptlet
+ cp -a /etc/apt/sources.list /etc/apt/sources.list.bak
...
Successfully installed numpy-1.20.3 pillow-8.2.0 torch-1.8.1+cu111 torchaudio-0.8.1 torchvision-0.9.1+cu111 typing-extensions-3.10.0.0
INFO: Creating SIF file...
INFO: Build complete: pytorch.sif
一般如果有報錯的話中途就會停下來,如果看到上面的這個指令,基本就構建成功了,並且可以在當前目錄下看到一個新生成的sif文件:
dechin@ubuntu2004:~/projects/pytorch$ ll
總用量 4086900
drwxrwxr-x 2 dechin dechin 4096 6月 15 09:53 ./
drwxrwxr-x 8 dechin dechin 4096 6月 15 09:34 ../
-rw-rw-r-- 1 dechin dechin 498 6月 15 09:44 pytorch.def
-rwxr-xr-x 1 dechin dechin 4184969216 6月 15 09:53 pytorch.sif*
這個就是我們構建好的pytorch的鏡像了。
PyTorch鏡像測試
首先我們看一下鏡像中python的版本:
dechin@ubuntu2004:~/projects/pytorch$ singularity exec pytorch.sif python3 --version
Python 3.8.5
因為pytorch對python的版本沒有比較特殊的要求,所以這里3.7或3.8或3.9都是可以的。接下來執行一個pytorch官方給出的測試示例,生成一個隨機數矩陣:
dechin@ubuntu2004:~/projects/pytorch$ singularity exec pytorch.sif python3 -c "import torch;x = torch.rand(5, 3);print(x)"
tensor([[0.2045, 0.2268, 0.2132],
[0.4473, 0.3536, 0.8075],
[0.0951, 0.0261, 0.5950],
[0.7112, 0.0449, 0.4564],
[0.8697, 0.7536, 0.7823]])
上述運行的方式是采用了python3 -c
的方式,省去了再寫一個py文件的繁瑣,只是需要注意的地方,在於我們要將正常py文件中的換行符替換成這里的分號,這里執行成功了,那么就代表我們的容器化安裝是成功了。但是我們需要進一步的確認下,torch能否正常的使用cuda環境,因為這是GPU加速的重點配置。測試可以使用官方給出的這個運行指令:
dechin@ubuntu2004:~/projects/pytorch$ singularity exec pytorch.sif python3 -c "import torch;print(torch.cuda.is_available())"
False
第一次看到這個結果的時候,我優先考慮的是,是否cudatoolkits沒有安裝的原因?因為在MindSpore中對於這個cudatoolkits是有依賴的,並且使用的是conda來安裝,但是這里我們直接裝的python沒有采取conda的方法。但是轉念一想,這里的Singularity運行指令上沒有指定GPU環境,更有可能是這個問題。因此加上了--nv
的選項,運行結果如下:
dechin@ubuntu2004:~/projects/pytorch$ singularity exec --nv pytorch.sif python3 -c "import torch;print(torch.cuda.is_available())"
True
可以看到pytorch的GPU版本是運行成功了的,或者應該說成功調用到了GPU。
Tricky的配置
使用容器化的方案來運行的話,在運行環境的隔離上面是做的非常好的,但是有一個缺點就是運行的指令太長了,雖然容器鏡像的位置是固定不變的,但是每次執行這么一大串指令總覺得麻煩,因此就想到了在環境變量配置文件.bashrc
中加上一個聲明,用更加簡短的語句來替代長指令:
alias mindspore='singularity exec --nv /home/dechin/tools/singularity/mindspore-gpu_1.2.0.sif python'
alias pytorch='singularity exec --nv /home/dechin/projects/pytorch/pytorch.sif python3'
寫入到.bashrc
文件后,需要source ~/.bashrc
指令來使得配置生效,然后我們就可以使用pytorch這樣的指令來運行一些pytorch的代碼或者命令:
dechin@ubuntu2004:~/projects/pytorch$ pytorch -c "import torch;print('import success')"
import success
總結概要
這篇文章主要介紹Facebook所主導的機器學習框架PyTorch的容器化安裝方法,基於HPC環境常用的Singularity高性能容器,並且兼容與結合了Docker容器鏡像的生態,非常的友好。在容器化的編程環境中,我們不僅可以避免不同框架對於python庫或者系統軟件版本的依賴沖突,還可以很大程度上解決因為沒有root權限以及網絡外訪權限的環境下所帶來的極大的麻煩,故推薦使用這種方案進行安裝和運行。
版權聲明
本文首發鏈接為:https://www.cnblogs.com/dechinphy/p/pytorch.html
作者ID:DechinPhy
更多原著文章請參考:https://www.cnblogs.com/dechinphy/
打賞專用鏈接:https://www.cnblogs.com/dechinphy/gallery/image/379634.html
騰訊雲專欄同步:https://cloud.tencent.com/developer/column/91958