優(yōu)化你的CPU來做深度學(xué)習(xí)
點(diǎn)擊上方“小白學(xué)視覺”,選擇加"星標(biāo)"或“置頂”
重磅干貨,第一時(shí)間送達(dá)
對(duì)于想學(xué)習(xí)深度學(xué)習(xí)的同學(xué)們來說,學(xué)習(xí)資源網(wǎng)上有很多,但是計(jì)算資源確很少,而GPU又太貴,怎么辦呢?通過簡(jiǎn)單的設(shè)置,將CPU做深度學(xué)習(xí)的速度提升到3倍以上,大家又可以愉快的學(xué)習(xí)深度學(xué)習(xí)了!

在過去的幾年里,無論是在學(xué)術(shù)界還是產(chǎn)業(yè)界,深度學(xué)習(xí)的速度都在加快?,F(xiàn)在每家公司都在尋找基于人工智能的問題解決方案。這種繁榮有它自己的優(yōu)點(diǎn)和缺點(diǎn),但這是另一篇文章,改天再說。機(jī)器學(xué)習(xí)實(shí)踐者的激增已經(jīng)滲透到學(xué)術(shù)界的根源,幾乎每個(gè)領(lǐng)域的學(xué)生都可以通過課程、mooc、書籍、文章,當(dāng)然還有課程論文,接觸到人工智能和ML知識(shí)。
然而,硬件資源的可用性阻礙了這種增長(zhǎng)。GPU是你能夠以一定的速度執(zhí)行ML任務(wù)的最佳設(shè)備之一。然而高性能GPU的價(jià)格甚至可以到20449美元(NVIDIA Tesla GPU V100 32 gb) 。此外,使用高級(jí)GPU的消費(fèi)級(jí)筆記本電腦,使用1050Ti或1080Ti之類的GPU,售價(jià)約為2000美元。為了減輕這種痛苦,谷歌、Kaggle、Intel和Nvidia免費(fèi)提供了基于云的高計(jì)算系統(tǒng),但對(duì)空間、計(jì)算能力、內(nèi)存或時(shí)間都有限制。但是這些在線服務(wù)也有其缺點(diǎn),包括管理數(shù)據(jù)(上傳/下載)、數(shù)據(jù)隱私等。這些問題導(dǎo)致了我的文章的主要觀點(diǎn),“為什么不優(yōu)化我們的cpu來實(shí)現(xiàn)深度學(xué)習(xí)任務(wù)的加速?”
對(duì)于下面提到的各種實(shí)驗(yàn),我會(huì)展示我觀察到的時(shí)間和利用率的提高。
10層深度CNN用于CIFAR-100圖像分類。
3層深度LSTM進(jìn)行IMDB情緒分析。
6層深度密集神經(jīng)網(wǎng)絡(luò)用于MNIST圖像分類。
9層全卷積MNIST自動(dòng)編碼器。
這些任務(wù)用Keras寫代碼,使用tensorflow后端,數(shù)據(jù)集和代碼和和可執(zhí)行庫放在一個(gè)盤里。所使用的是SSD硬盤。
我們將考慮以下六種優(yōu)化組合。
英特爾(R) Core (TM) i7。
Intel(R) Xeon(R) CPU E3-1535M v6。
英特爾(R)核心(TM) i7與英特爾Python(英特爾i7*)。
Intel(R) Xeon(R) CPU E3-1535M v6采用Intel Python (Intel Xeon*)。
Intel(R) Core (TM) i7與Intel Python和處理器線程優(yōu)化(Intel i7(O))。
Intel(R) Xeon(R) CPU E3-1535M v6采用Intel Python和處理器線程優(yōu)化(Intel Xeon(O))。
對(duì)于每個(gè)任務(wù),epochs的數(shù)量固定在50。從下圖中我們可以看到,對(duì)于一個(gè)Intel(R) Core (TM) i7-7700HQ CPU @ 2.80GHz CPU, epoch的平均時(shí)間接近4.67秒,經(jīng)過適當(dāng)?shù)膬?yōu)化后下降到1.48秒,即提高3.2倍。對(duì)于一個(gè)Intel(R) Xeon(R) CPU E3-1535M v6 @ 3.10GHz CPU,epoch的平均時(shí)間接近2.21秒,經(jīng)過適當(dāng)?shù)膬?yōu)化后下降到0.64秒,提高了3.45倍。

優(yōu)化不僅僅是在時(shí)間上,優(yōu)化的分布也優(yōu)化了CPU的利用率,這最終導(dǎo)致更好的熱量管理,你的筆記本電腦不會(huì)像以前訓(xùn)練深度神經(jīng)網(wǎng)絡(luò)時(shí)那么熱。

我們可以看到,在不進(jìn)行任何優(yōu)化的情況下,訓(xùn)練時(shí)CPU利用率最高達(dá)到100%,從而減慢了所有其他進(jìn)程并使系統(tǒng)升溫。然而,通過適當(dāng)?shù)膬?yōu)化,i7和Xeon的利用率分別下降到70%和65%,但是在運(yùn)行時(shí)間上卻減少了。
這兩個(gè)指標(biāo)可以用以下相關(guān)術(shù)語進(jìn)行總結(jié)。

在上面的圖中,越低的值越好,即以Intel Xeon為基準(zhǔn)進(jìn)行所有優(yōu)化,而一個(gè)Intel Core i7處理器在優(yōu)化后,每個(gè)epoch花費(fèi)的時(shí)間幾乎是Xeon的兩倍。上面的圖表清楚地顯示了從訓(xùn)練神經(jīng)網(wǎng)絡(luò)的時(shí)間和CPU的使用情況來看,英特爾Python優(yōu)化是前途光明的。

Intel Software提供了一個(gè)關(guān)于如何設(shè)置此選項(xiàng)的詳盡的資源列表,但是我們通??赡軙?huì)遇到一些問題。更多關(guān)于發(fā)行版的詳細(xì)信息看這里:(https://software.intel.com/en-us/distribution-for-python)。你可以選擇安裝的類型,即本地pip或conda。我更喜歡conda,因?yàn)樗鼮槲夜?jié)省了大量的麻煩,而且我可以專注于ML,而不是解決我的庫的兼容性問題。
1) 下載安裝Anaconda
你可以從這里:(https://www.anaconda.com/distribution/)下載Anaconda。他們的網(wǎng)站列出了在windows、ubuntu和macOS環(huán)境中安裝Python的所有步驟,并且很容易做。
2) 在你的Anaconda發(fā)布中設(shè)置Intel python
這一步通常比較棘手。最好為Intel發(fā)行版創(chuàng)建一個(gè)虛擬環(huán)境,這樣你就可以隨時(shí)在一個(gè)地方添加/更改優(yōu)化后的庫。讓我們創(chuàng)建一個(gè)名為“intel.”的虛擬環(huán)境。
conda create -n intel -c intel intelpython3_full
這里-c表示通道,因此我們不將Intel添加為通道,而是通過-c調(diào)用該通道。在這里,intelpython3_full將自動(dòng)從Intel發(fā)行版獲取必要的庫,并將它們安裝到你的虛擬環(huán)境中。這個(gè)命令將安裝以下庫。
The following NEW packages will be INSTALLED:
asn1crypto intel/win-64::asn1crypto-0.24.0-py36_3
bzip2 intel/win-64::bzip2-1.0.6-vc14_17
certifi intel/win-64::certifi-2018.1.18-py36_2
cffi intel/win-64::cffi-1.11.5-py36_3
chardet intel/win-64::chardet-3.0.4-py36_3
cryptography intel/win-64::cryptography-2.3-py36_1
cycler intel/win-64::cycler-0.10.0-py36_7
cython intel/win-64::cython-0.29.3-py36_1
daal intel/win-64::daal-2019.3-intel_203
daal4py intel/win-64::daal4py-2019.3-py36h7b7c402_6
freetype intel/win-64::freetype-2.9-vc14_3
funcsigs intel/win-64::funcsigs-1.0.2-py36_7
icc_rt intel/win-64::icc_rt-2019.3-intel_203
idna intel/win-64::idna-2.6-py36_3
impi_rt intel/win-64::impi_rt-2019.3-intel_203
intel-openmp intel/win-64::intel-openmp-2019.3-intel_203
intelpython intel/win-64::intelpython-2019.3-0
intelpython3_core intel/win-64::intelpython3_core-2019.3-0
intelpython3_full intel/win-64::intelpython3_full-2019.3-0
kiwisolver intel/win-64::kiwisolver-1.0.1-py36_2
libpng intel/win-64::libpng-1.6.36-vc14_2
llvmlite intel/win-64::llvmlite-0.27.1-py36_0
matplotlib intel/win-64::matplotlib-3.0.1-py36_1
menuinst intel/win-64::menuinst-1.4.1-py36_6
mkl intel/win-64::mkl-2019.3-intel_203
mkl-service intel/win-64::mkl-service-1.0.0-py36_7
mkl_fft intel/win-64::mkl_fft-1.0.11-py36h7b7c402_0
mkl_random intel/win-64::mkl_random-1.0.2-py36h7b7c402_4
mpi4py intel/win-64::mpi4py-3.0.0-py36_3
numba intel/win-64::numba-0.42.1-np116py36_0
numexpr intel/win-64::numexpr-2.6.8-py36_2
numpy intel/win-64::numpy-1.16.1-py36h7b7c402_3
numpy-base intel/win-64::numpy-base-1.16.1-py36_3
openssl intel/win-64::openssl-1.0.2r-vc14_0
pandas intel/win-64::pandas-0.24.1-py36_3
pip intel/win-64::pip-10.0.1-py36_0
pycosat intel/win-64::pycosat-0.6.3-py36_3
pycparser intel/win-64::pycparser-2.18-py36_2
pyopenssl intel/win-64::pyopenssl-17.5.0-py36_2
pyparsing intel/win-64::pyparsing-2.2.0-py36_2
pysocks intel/win-64::pysocks-1.6.7-py36_1
python intel/win-64::python-3.6.8-6
python-dateutil intel/win-64::python-dateutil-2.6.0-py36_12
pytz intel/win-64::pytz-2018.4-py36_3
pyyaml intel/win-64::pyyaml-4.1-py36_3
requests intel/win-64::requests-2.20.1-py36_1
ruamel_yaml intel/win-64::ruamel_yaml-0.11.14-py36_4
scikit-learn intel/win-64::scikit-learn-0.20.2-py36h7b7c402_2
scipy intel/win-64::scipy-1.2.0-py36_3
setuptools intel/win-64::setuptools-39.0.1-py36_0
six intel/win-64::six-1.11.0-py36_3
sqlite intel/win-64::sqlite-3.27.2-vc14_2
tbb intel/win-64::tbb-2019.4-vc14_intel_203
tbb4py intel/win-64::tbb4py-2019.4-py36_intel_0
tcl intel/win-64::tcl-8.6.4-vc14_22
tk intel/win-64::tk-8.6.4-vc14_28
urllib3 intel/win-64::urllib3-1.24.1-py36_2
vc intel/win-64::vc-14.0-2
vs2015_runtime intel/win-64::vs2015_runtime-14.0.25420-intel_2
wheel intel/win-64::wheel-0.31.0-py36_3
win_inet_pton intel/win-64::win_inet_pton-1.0.1-py36_4
wincertstore intel/win-64::wincertstore-0.2-py36_3
xz intel/win-64::xz-5.2.3-vc14_2
zlib intel/win-64::zlib-1.2.11-vc14h21ff451_5
你可以看到,對(duì)于每個(gè)庫,都以“Intel/…”開頭,這表示正在從Intel的發(fā)行渠道下載該庫。一旦你同意安裝這些庫,就會(huì)開始下載和安裝它們。
這一步是會(huì)出現(xiàn)一個(gè)問題。有時(shí),這些庫不會(huì)被下載,列表會(huì)往下走,或者出現(xiàn)SSL錯(cuò)誤,然后命令退出。這個(gè)問題甚至可能被延遲,也就是說,現(xiàn)在所有東西都將被下載和安裝,但是稍后如果你想添加任何新的庫,提示符將拋出SSL錯(cuò)誤。有一個(gè)方式可以簡(jiǎn)單的修復(fù)這個(gè)問題,為英特爾創(chuàng)建虛擬環(huán)境之前需要完成。
在你的shell或命令提示符中,通過下面的命令關(guān)閉anaconda的默認(rèn)SSL驗(yàn)證
conda config --set ssl_verify false
一旦關(guān)閉了SLL驗(yàn)證,你可以重復(fù)步驟2,刪除之前創(chuàng)建的環(huán)境并重新啟動(dòng)。
3) 設(shè)置TensorFlow

恭喜你?。‖F(xiàn)在,你已經(jīng)在電腦中設(shè)置了Intel的python發(fā)行版?,F(xiàn)在是進(jìn)入ML pipeline的時(shí)候了。
英特爾已經(jīng)通過所有的發(fā)行版為tensorflow提供了優(yōu)化,設(shè)置起來非常順利。(https://software.intel.com/en-us/ai/frameworks/tensorflow)。讓我們看看如何為CPU安裝優(yōu)化過的tensorflow。英特爾軟件提供了一個(gè)優(yōu)化的數(shù)學(xué)內(nèi)核庫(mkl),優(yōu)化數(shù)學(xué)操作,并為用戶提供所需的加速。因此,我們將按如下方式安裝tensorflow-mkl。
conda install tensorflow-mkl
或者使用pip,可以將其設(shè)置為如下所示。
pip install intel-tensorflow
Tensorflow現(xiàn)在已經(jīng)啟動(dòng)并在你的系統(tǒng)中運(yùn)行,并進(jìn)行了必要的優(yōu)化。如果你是Keras的粉絲,你可以用一個(gè)簡(jiǎn)單的命令來設(shè)置它:-
conda install keras -c intel
4) 設(shè)置Jupyter
由于我們創(chuàng)建了一個(gè)新的虛擬環(huán)境,但它不是spyder或jupyter notebooks的默認(rèn)環(huán)境。然而,設(shè)置這些是很簡(jiǎn)單的。只要一行命令,我們就能做到。
conda install jupyter -c intel
5) 激活環(huán)境開始做實(shí)驗(yàn)
既然我們已經(jīng)設(shè)置好了所有的東西,現(xiàn)在是動(dòng)手的時(shí)候了,我們開始在優(yōu)化的CPU系統(tǒng)上編寫代碼并嘗試各種ML和DL方法。首先,在執(zhí)行任何代碼之前,確保使用了正確的環(huán)境。在使用安裝在虛擬環(huán)境中的庫之前,需要激活虛擬環(huán)境。這個(gè)激活步驟是一個(gè)永久的過程,并且是毫不費(fèi)力的。在anaconda提示符中編寫以下命令,就可以開始了。
conda activate intel
要對(duì)環(huán)境進(jìn)行全面檢查,在激活環(huán)境后,在命令提示符/shell中鍵入以下命令。
python
輸入python后按enter,命令提示符中應(yīng)該出現(xiàn)以下文本。確保顯示的是“Intel Corporation”,并顯示“Intel(R) Distribution for Python is brought to you by Intel Corporation.”。這些驗(yàn)證了英特爾Python發(fā)行版的正確安裝。
Python 3.6.8 |Intel Corporation| (default, Feb 27 2019, 19:55:17) [MSC v.1900 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
Intel(R) Distribution for Python is brought to you by Intel Corporation.
Please check out: https://software.intel.com/en-us/python-distribution
現(xiàn)在,你可以使用命令行進(jìn)行試驗(yàn),或者在其他地方編寫腳本來運(yùn)行。
(intel) C:\Users\User>python script.py
通過以下步驟1到4,使你的系統(tǒng)具備上面的性能基準(zhǔn)圖中提到的Intel xyz級(jí)別。這些仍然不是基于多處理器的線程優(yōu)化。我將在下面討論如何進(jìn)一步優(yōu)化你的多核CPU。
要為你的多核系統(tǒng)添加進(jìn)一步的優(yōu)化,你可以將以下代碼行添加到.py文件中,它將相應(yīng)地執(zhí)行腳本。這里NUMPARALLELEXEC_UNITS表示內(nèi)核的數(shù)量,我有一個(gè)四核i7,因此這個(gè)數(shù)字是4。
from keras import backend as K
import tensorflow as tf
NUM_PARALLEL_EXEC_UNITS = 4
config = tf.ConfigProto(intra_op_parallelism_threads=NUM_PARALLEL_EXEC_UNITS, inter_op_parallelism_threads=2,
allow_soft_placement=True, device_count={'CPU': NUM_PARALLEL_EXEC_UNITS})
session = tf.Session(config=config)
K.set_session(session)
os.environ["OMP_NUM_THREADS"] = "4"
os.environ["KMP_BLOCKTIME"] = "30"
os.environ["KMP_SETTINGS"] = "1"
os.environ["KMP_AFFINITY"] = "granularity=fine,verbose,compact,1,0"
如果你不喜歡使用Keras而更喜歡使用tensorflow,那么腳本幾乎保持不變,只需刪除以下兩行。
from keras import backend as K
K.set_session(session)
在你的代碼中添加了這些行之后,應(yīng)該可以達(dá)到上面性能圖表中的Intel xyz(O)條目相當(dāng)?shù)男阅堋?/p>
如果你的系統(tǒng)中有GPU,并且它與當(dāng)前庫集沖突,或者拋出一個(gè)cudnn錯(cuò)誤,那么你可以在代碼中添加以下行來禁用GPU。
os.environ["CUDA_VISIBLE_DEVICES"] = "-1"
現(xiàn)在你已經(jīng)有了一個(gè)用于測(cè)試和開發(fā)機(jī)器學(xué)習(xí)項(xiàng)目和思想的優(yōu)化pipeline。這一渠道為學(xué)生提供了大量的機(jī)會(huì),讓他們參與到學(xué)術(shù)研究中,用他們所擁有的資源繼續(xù)他們的工作。這條pipeline還將防止從業(yè)者的私有數(shù)據(jù)的隱私泄露問題。
同樣值得注意的是,通過適當(dāng)?shù)奈⒄{(diào),一個(gè)人可以在他們的工作流程中獲得3.45倍的加速,這意味著如果你正在試驗(yàn)?zāi)愕南敕?,你現(xiàn)在可以比以前快三倍。
交流群
歡迎加入公眾號(hào)讀者群一起和同行交流,目前有SLAM、三維視覺、傳感器、自動(dòng)駕駛、計(jì)算攝影、檢測(cè)、分割、識(shí)別、醫(yī)學(xué)影像、GAN、算法競(jìng)賽等微信群(以后會(huì)逐漸細(xì)分),請(qǐng)掃描下面微信號(hào)加群,備注:”昵稱+學(xué)校/公司+研究方向“,例如:”張三?+?上海交大?+?視覺SLAM“。請(qǐng)按照格式備注,否則不予通過。添加成功后會(huì)根據(jù)研究方向邀請(qǐng)進(jìn)入相關(guān)微信群。請(qǐng)勿在群內(nèi)發(fā)送廣告,否則會(huì)請(qǐng)出群,謝謝理解~
