前言: TensorFlow簡(jiǎn)介
TensorFlow 在新款 NVIDIA Pascal GPU 上的運(yùn)行速度可提升高達(dá) 50%,并且能夠順利跨 GPU 進(jìn)行擴(kuò)展。 如今,訓(xùn)練模型的時(shí)間可以從幾天縮短到幾小時(shí)
TensorFlow 使用優(yōu)化的 C++ 和 NVIDIA? CUDA? 工具包編寫(xiě),使模型能夠在訓(xùn)練和推理時(shí)在 GPU 上運(yùn)行,從而大幅提速
TensorFlow GPU 支持需要多個(gè)驅(qū)動(dòng)和庫(kù)。為簡(jiǎn)化安裝并避免庫(kù)沖突,建議利用 GPU 支持的 TensorFlow Docker 鏡像。此設(shè)置僅需要 NVIDIA GPU 驅(qū)動(dòng)并且安裝 NVIDIA Docker。用戶可以從預(yù)配置了預(yù)訓(xùn)練模型和 TensorFlow 庫(kù)支持的 NGC (NVIDIA GPU Cloud) 中提取容器
CPU擅長(zhǎng)邏輯控制、串行計(jì)算,而GPU擅長(zhǎng)高強(qiáng)度計(jì)算、并行計(jì)算。CUDA是NVIDIA推出用于自家GPU的并行計(jì)算框架,cuDNN & tensorflow是一系列機(jī)器學(xué)習(xí),深度學(xué)習(xí)庫(kù),用于訓(xùn)練機(jī)器學(xué)習(xí)、深度學(xué)習(xí)模型
2. 依賴環(huán)境準(zhǔn)備
選取centos7.3作為基礎(chǔ)操作系統(tǒng)鏡像,選取適配驅(qū)動(dòng):Nvidia
GPU部署預(yù)裝機(jī)器
深度學(xué)習(xí)框架:cuda、cudnn、tensorflow
由于cuda、cudnn、tensorflow等機(jī)器學(xué)習(xí)、深度學(xué)習(xí)框架,依賴python3,需要在centos7.3操作系統(tǒng)中集成python3
一、 nvidia-docker的安裝cpu架構(gòu):x86
受夠了TensorRT+cuda+opencv+ffmpeg+x264運(yùn)行環(huán)境的部署的繁瑣,每次新服務(wù)器上部署環(huán)境都會(huì)花費(fèi)很大的精力去部署環(huán)境,聽(tīng)說(shuō)nvidia-docker可以省去部署的麻煩,好多人也推薦使用docker方便部署,咱也在網(wǎng)上搜索了下,學(xué)習(xí)了下,根據(jù)網(wǎng)上的資料,開(kāi)始安裝docker學(xué)習(xí)一下,把學(xué)習(xí)記錄記在這兒,聽(tīng)說(shuō)要想使用GPU,就要安裝Docker-CE和NVIDIA Container Toolkit,好的,開(kāi)始。
1. 安裝Dokcer-CE
首先,我的機(jī)器上沒(méi)有安裝過(guò)docker,要先把docker安裝上,執(zhí)行以下腳本,開(kāi)始安裝。
curl https://get.docker.com | sh \
> && sudo systemctl --now enable docker
安裝結(jié)束后,查看Docker版本:
docker --version
結(jié)果如下:
Docker version 20.10.16, build aa7e414
CentOS7下安裝docker詳細(xì)教程
當(dāng)基于nvidia gpu開(kāi)發(fā)的docker鏡像在實(shí)際部署時(shí),需要先安裝nvidia docker。安裝nvidia docker前需要先安裝原生docker compose
安裝docker
- Docker 要求 CentOS 系統(tǒng)的內(nèi)核版本高于 3.10 ,查看本頁(yè)面的前提條件來(lái)驗(yàn)證你的CentOS 版本是否支持 Docker 。
通過(guò) uname -r
命令查看你當(dāng)前的內(nèi)核版本
uname -r
uname -a
Linux gputest 3.10.0-1160.90.1.el7.x86_64 #1 SMP Thu May 4 15:21:22 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux
uname -r
3.10.0-1160.90.1.el7.x86_64
- 使用 root 權(quán)限登錄 Centos 確保 yum 包更新到最新
sudo yum update
- 卸載舊版本(如果安裝過(guò)舊版本的話)
yum remove docker
docker-client
docker-client-latest
docker-common
docker-latest
docker-latest-logrotate
docker-logrotate
docker-selinux
docker-engine-selinux
docker-engine
- 安裝需要的軟件包, yum-util 提供yum-config-manager功能,另外兩個(gè)是devicemapper驅(qū)動(dòng)依賴的
yum install -y yum-utils device-mapper-persistent-data lvm2
- 設(shè)置yum源
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
- 可以查看所有倉(cāng)庫(kù)中所有docker版本,并選擇特定版本安裝
yum list docker-ce --showduplicates | sort -r
- 安裝docker,版本號(hào)自選
yum install docker-ce-17.12.0.ce
- 啟動(dòng)并加入開(kāi)機(jī)啟動(dòng)
systemctl start docker
systemctl status docker
systemctl enable docker
- 驗(yàn)證安裝是否成功(有client和service兩部分表示docker安裝啟動(dòng)都成功了)
docker version
2. 安裝NVIDIA Container Toolkit
執(zhí)行以下腳本:
distribution=$(. /etc/os-release;echo $ID$VERSION_ID) \
&& curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | sudo apt-key add - \
&& curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | sudo tee /etc/apt/sources.list.d/nvidia-docker.list
控制臺(tái)輸出如下:
[sudo] dingxin 的密碼: OK deb
https://nvidia.github.io/libnvidia-container/stable/ubuntu18.04/KaTeX parse error: Expected 'EOF', got '#' at position 10: (ARCH) / #?deb https://nvi…(ARCH)
/ deb
https://nvidia.github.io/nvidia-container-runtime/stable/ubuntu18.04/KaTeX parse error: Expected 'EOF', got '#' at position 10: (ARCH) / #?deb https://nvi…(ARCH)
/ deb https://nvidia.github.io/nvidia-docker/ubuntu18.04/$(ARCH) /
安裝nvidia-docker2包及其依賴
sudo apt-get update
接著執(zhí)行安裝nvidia-docker2:
sudo apt-get install -y nvidia-docker2
CentOS7下安裝NVIDIA-Docker
依賴條件
如果使用的 Tensorflow 版本大于 1.4.0,要求 CUDA 9.0 以上版本
基于docker的測(cè)試環(huán)境的建立
測(cè)試環(huán)境基于docker構(gòu)建,需要Nvidia GPU驅(qū)動(dòng)的支持(不需要安裝CUDA),安裝好GPU驅(qū)動(dòng)和docker以后,下載最新的包含tensorflow,CUDA,cudnn等的image,然后就可以運(yùn)行tf_cnn_benchmark了
- 下載nvidia-docker安裝包
$ wget https://github.com/NVIDIA/nvidia-docker/releases/download/v1.0.1/nvidia-docker-1.0.1-1.x86_64.rpm
- 安裝nvidia-docker
$ rpm -ivh nvidia-docker-1.0.1-1.x86_64.rpm
- 啟動(dòng) nvidia-docker 服務(wù)
$ sudo systemctl restart nvidia-docker
- 執(zhí)行以下命令,若結(jié)果顯示 active(running) 則說(shuō)明啟動(dòng)成功
$ systemctl status nvidia-docker.service
Active: active (running) since Fri 2023-07-21 11:15:45 CST; 1min ago
5. 使用 nvidia-docker查看 GPU 信息
$ nvidia-docker run --rm nvidia/cuda nvidia-smi
二、鏡像安裝
1. cuda 11下的安裝(可選)
sudo docker run --rm --gpus all nvidia/cuda:11.0-base nvidia-smi
查看已下載的鏡像
sudo docker images -a
2. 下載tensorflow v1.15.5版本的鏡像
官網(wǎng)下載:
https://catalog.ngc.nvidia.com/orgs/nvidia/containers/tensorflow/tags
大概1.5小時(shí)
安裝testflow1.0版本(向下兼容)
docker pull nvcr.io/nvidia/tensorflow:23.03-tf1-py3
再次查看下載的鏡像
docker image ls
image id = fc14c7fdf361為上述安裝的tensorflow1.15版本容器
三、操作tensorflow容器
nvidia-docker run -it nvcr.io/nvidia/tensorflow:23.03-tf1-py3
格式:nvidia-docker run -it {REPOSITORY容器名稱:TAG號(hào)}
pip list|grep tensor
jupyter-tensorboard 0.2.0
tensorboard 1.15.0
tensorflow 1.15.5+nv23.3
tensorflow-estimator 1.15.1
tensorrt 8.5.3.1
測(cè)試腳本:
import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
import tensorflow as tf
hello = tf.constant('--------Hello, TensorFlow!----------')
sess = tf.Session()
sess.run(hello)
在container OS中使用命令cat /proc/driver/nvidia/version或nvcc --version可正常顯示顯卡驅(qū)動(dòng)版本及CUDA版本
四、配置git
- 在本機(jī)生成公私鑰
ssh-keygen -t rsa -b 4096 -C "xx@xx.com"
默認(rèn)生成的公私鑰 ~/.ssh/
id_rsa.pub
id_rsa
-b 4096:b是bit的縮寫(xiě)
-b 指定密鑰長(zhǎng)度。對(duì)于RSA密鑰,最小要求768位,默認(rèn)是2048位。命令中的4096指的是RSA密鑰長(zhǎng)度為4096位。
DSA密鑰必須恰好是1024位(FIPS 186-2 標(biāo)準(zhǔn)的要求)
Generating public/private rsa key pair. Enter file in which to save
the key (/Users/qa/.ssh/id_rsa): yes Enter passphrase (empty for no
passphrase): Enter same passphrase again: Your identification has been
saved in yes. Your public key has been saved in yes.pub. The key
fingerprint is: SHA256:MGbV/xx/xx lishan12@xx.com The key’s randomart
image is:
±–[RSA 4096]----+ | …OBB=Eo| | . .O+oO=o=| | = .o*+B *o.| | o o o+B =… | | S.+o . | | . o |
| . . | | . . | | . |
±—[SHA256]-----+
- 配置登錄git的username email。為公司給你分配的用戶名 密碼
第一步:
git config --global user.name 'username'
git config --global user.email 'username@xx.com'
第二步: 設(shè)置永久保存
git config --global credential.helper store
第三步:手動(dòng)輸入一次用戶名和密碼,GIT會(huì)自動(dòng)保存密碼,下次無(wú)須再次輸入
git pull
-
初始化倉(cāng)庫(kù)
git init
-
拉取代碼
git clone git@gitlab.xx.com:xx/xx.git
Cloning into ‘xx-xx’…
git@gitlab.xx.com’s password:
Permission denied, please try again.
git@gitlab.xx.com’s password:
遇到的問(wèn)題:沒(méi)有出username 和 password成對(duì)的輸入項(xiàng) ,而是出了password輸入項(xiàng)
都不知道密碼是啥,跟登錄git庫(kù)的密碼不一樣。
然后使用http的方式,報(bào)一個(gè)錯(cuò)誤:
use:~/ecox # git clone https://vcs.in.ww-it.cn/ecox/ecox.git
正克隆到 ‘ecox’…
fatal: unable to access ‘https://vcs.in.ww-it.cn/ecox/ecox.git/’: SSL certificate problem: unable to get local issuer certificate
提示SSL證書(shū)錯(cuò)誤。發(fā)現(xiàn)說(shuō)這個(gè)錯(cuò)誤并不重要是系統(tǒng)證書(shū)的問(wèn)題,系統(tǒng)判斷到這個(gè)行為會(huì)造成不良影響,所以進(jìn)行了阻止,只要設(shè)置跳過(guò)SSL證書(shū)驗(yàn)證就可以了,那么用命令 :
git config --global http.sslVerify false
五、下載Benchmarks源碼并運(yùn)行
從 TensorFlow 的 Github 倉(cāng)庫(kù)上下載 TensorFlow Benchmarks,可以通過(guò)以下命令來(lái)下載。非常重要的參考代碼:
https://github.com/tensorflow/benchmarks
我的 - settings -SSH and GPG Keys 添加公鑰id_rsa.pub
拉取代碼
git clone git@github.com:tensorflow/benchmarks.git
git同步遠(yuǎn)程分支到本地,拉取tensorflow對(duì)應(yīng)版本的分支
git fetch origin 遠(yuǎn)程分支名xxx:本地分支名xxx
使用這種方式會(huì)在本地倉(cāng)庫(kù)新建分支xxx,但是并不會(huì)自動(dòng)切換到新建的分支xxx,需要手動(dòng)checkout,當(dāng)然了遠(yuǎn)程分支xxx的代碼也拉取到了本地分支xxx中。采用這種方法建立的本地分支不會(huì)和遠(yuǎn)程分支建立映射關(guān)系
root@818d19092cdc:/gpu/benchmarks# git checkout -b tf1.15 origin/cnn_tf_v1.15_compatible
運(yùn)行不同模型
root@818d19092cdc:/gpu/benchmarks/scripts/tf_cnn_benchmarks# pwd
/gpu/benchmarks/scripts/tf_cnn_benchmarks
root@818d19092cdc:/gpu/benchmarks/scripts/tf_cnn_benchmarks#
python3 tf_cnn_benchmarks.py
真實(shí)操作:
[root@gputest ~]# docker ps
進(jìn)入CONTAINER ID containerid
[root@gputest ~]# nvidia-docker exec -it 818d19092cdc /bin/bash
新開(kāi)窗口
[root@gputest ~]# nvidia-smi -l 3
該命令將3秒鐘輸出一次GPU的狀態(tài)和性能,可以通過(guò)查看輸出結(jié)果來(lái)得出GPU的性能指標(biāo)
一、resnet50模型
python3 tf_cnn_benchmarks.py --num_gpus=1 --batch_size=2 --model=resnet50 --variable_update=parameter_server
Running warm up
2023-07-21 09:50:55.398126: I tensorflow/stream_executor/platform/default/dso_loader.cc:50] Successfully opened dynamic library libcublas.so.12
2023-07-21 09:50:55.533068: I tensorflow/stream_executor/platform/default/dso_loader.cc:50] Successfully opened dynamic library libcudnn.so.8
Done warm up
Step Img/sec total_loss
1 images/sec: 10.1 +/- 0.0 (jitter = 0.0) 7.695
10 images/sec: 10.7 +/- 0.1 (jitter = 0.1) 8.022
20 images/sec: 10.7 +/- 0.1 (jitter = 0.2) 7.269
30 images/sec: 10.7 +/- 0.1 (jitter = 0.2) 7.889
40 images/sec: 10.7 +/- 0.1 (jitter = 0.2) 8.842
50 images/sec: 10.6 +/- 0.1 (jitter = 0.2) 6.973
60 images/sec: 10.6 +/- 0.1 (jitter = 0.2) 8.124
70 images/sec: 10.6 +/- 0.0 (jitter = 0.2) 7.644
80 images/sec: 10.6 +/- 0.0 (jitter = 0.2) 7.866
90 images/sec: 10.6 +/- 0.0 (jitter = 0.3) 7.687
100 images/sec: 10.6 +/- 0.0 (jitter = 0.3) 8.779
----------------------------------------------------------------total images/sec: 10.63
二、vgg16模型
python3 tf_cnn_benchmarks.py --num_gpus=1 --batch_size=2 --model=vgg16 --variable_update=parameter_server
由于阿里云服務(wù)器申請(qǐng)的是2個(gè)G顯存,所以只能跑size=1 2 和 4 ,超出會(huì)吐核
已放棄(吐核)–linux 已放棄(吐核) (core dumped) 問(wèn)題分析
出現(xiàn)這種問(wèn)題一般是下面這幾種情況:
-
1.內(nèi)存越界
2.使用了非線程安全的函數(shù)
3.全局?jǐn)?shù)據(jù)未加鎖保護(hù)
4.非法指針
5.堆棧溢出
也就是需要檢查訪問(wèn)的內(nèi)存、資源。
可以使用 strace 命令來(lái)進(jìn)行分析
在程序的運(yùn)行命令前加上 strace,在程序出現(xiàn):已放棄(吐核),終止運(yùn)行后,就可以通過(guò) strace 打印在控制臺(tái)的跟蹤信息進(jìn)行分析和定位問(wèn)題
方法2:docker啟動(dòng)普通鏡像的Tensorflow
$ docker pull tensorflow/tensorflow:1.8.0-gpu-py3
$ docker tag tensorflow/tensorflow:1.8.0-gpu-py3 tensorflow:1.8.0-gpu
nvidia-docker run -it -p 8888:8888 tensorflow:1.8.0-gpu
$ nvidia-docker run -it -p 8033:8033 tensorflow:1.8.0-gpu
瀏覽器進(jìn)入指定 URL(見(jiàn)啟動(dòng)終端回顯) 就可以利用 IPython Notebook 使用 tensorflow
評(píng)測(cè)指標(biāo)
-
訓(xùn)練時(shí)間:在指定數(shù)據(jù)集上訓(xùn)練模型達(dá)到指定精度目標(biāo)所需的時(shí)間
-
吞吐:?jiǎn)挝粫r(shí)間內(nèi)訓(xùn)練的樣本數(shù)
-
加速效率:加速比/設(shè)備數(shù)*100%。其中,加速比定義為多設(shè)備吞吐數(shù)較單設(shè)備的倍數(shù)
-
成本:在指定數(shù)據(jù)集上訓(xùn)練模型達(dá)到指定精度目標(biāo)所需的價(jià)格
-
功耗:在指定數(shù)據(jù)集上訓(xùn)練模型達(dá)到指定精度目標(biāo)所需的功耗
在初版評(píng)測(cè)指標(biāo)設(shè)計(jì)中,我們重點(diǎn)關(guān)注訓(xùn)練時(shí)間、吞吐和加速效率三項(xiàng)
六、保存鏡像的修改
執(zhí)行以下命令,保存TensorFlow鏡像的修改
docker commit -m "commit docker" CONTAINER_ID nvcr.io/nvidia/tensorflow:18.03-py3
# CONTAINER_ID可通過(guò)docker ps命令查看。
[root@gputest ~]# docker commit -m “commit docker” 818d19092cdc nvcr.io/nvidia/tensorflow:23.03-tf1-py3
sha256:fc14c7fdf361308817161d5d0cc018832575e7f2def99fe49876d2a41391c52c
查看docker進(jìn)程
[root@gputest ~]# docker ps
重新進(jìn)入CONTAINER ID containerid
[root@gputest ~]# nvidia-docker exec -it 818d19092cdc /bin/bash
七、benchmarks 支持的所有參數(shù)
參數(shù)名稱 |
描述 |
備注 |
--help |
查看幫助信息 |
|
--backend |
使用的框架名稱,如TensorFlow,PyTorch等,必須指定 |
當(dāng)前只支持TensorFlow,后續(xù)會(huì)增加對(duì)PyTorch的支持 |
--model |
使用的模型名稱,如alexnet、resnet50等,必須指定 |
請(qǐng)查閱所有支持的模型 |
--batch_size |
batch size大小 |
默認(rèn)值為32 |
--num_epochs |
epoch的數(shù)量 |
默認(rèn)值為1 |
--num_gpus |
使用的GPU數(shù)量。設(shè)置為0時(shí),僅使用CPU。
|
|
--data_dir |
輸入數(shù)據(jù)的目錄,對(duì)于CV任務(wù),當(dāng)前僅支持ImageNet數(shù)據(jù)集;如果沒(méi)有指定,表明使用合成數(shù)據(jù) |
|
--do_train |
執(zhí)行訓(xùn)練過(guò)程 |
這三個(gè)選項(xiàng)必須指定其中的至少一個(gè),可以同時(shí)指定多個(gè)選項(xiàng)。 |
--do_eval |
執(zhí)行evaluation過(guò)程 |
|
--do_predict |
執(zhí)行預(yù)測(cè)過(guò)程 |
|
--data_format |
使用的數(shù)據(jù)格式,NCHW或NHWC,默認(rèn)為NCHW。
|
|
--optimizer |
所使用的優(yōu)化器,當(dāng)前支持SGD、Adam和Momentum,默認(rèn)為SGD |
|
--init_learning_rate |
使用的初始learning rate的值 |
|
--num_epochs_per_decay |
learning rate decay的epoch間隔 |
如果設(shè)置,這兩項(xiàng)必須同時(shí)指定 |
--learning_rate_decay_factor |
每次learning rate執(zhí)行decay的因子 |
|
--minimum_learning_rate |
最小的learning rate值 |
如果設(shè)置,需要同時(shí)指定面的兩項(xiàng) |
--momentum |
momentum參數(shù)的值 |
用于設(shè)置momentum optimizer |
--adam_beta1 |
adam_beta1參數(shù)的值 |
用于設(shè)置Adam |
--adam_beta2 |
adam_beta2參數(shù)的值 |
|
--adam_epsilon |
adam_epsilon參數(shù)的值 |
|
--use_fp16 |
是否設(shè)置tensor的數(shù)據(jù)類型為float16 |
|
--fp16_vars |
是否將變量的數(shù)據(jù)類型設(shè)置為float16。如果沒(méi)有設(shè)置,變量存儲(chǔ)為float32類型,并在使用時(shí)轉(zhuǎn)換為fp16格式。 建議:不要設(shè)置 |
必須同時(shí)設(shè)置--use_fp16 |
--all_reduce_spec |
使用的AllReduce方式 |
|
--save_checkpoints_steps |
間隔多少step存儲(chǔ)一次checkpoint |
|
--max_chkpts_to_keep |
保存的checkpoint的最大數(shù)量 |
|
--ip_list |
集群中所有機(jī)器的IP地址,以逗號(hào)分隔 |
用于多機(jī)分布式訓(xùn)練 |
--job_name |
任務(wù)名稱,如‘ps'、’worker‘ |
|
--job_index |
任務(wù)的索引,如0,1等 |
|
--model_dir |
checkpoint的存儲(chǔ)目錄 |
|
--init_checkpoint |
初始模型checkpoint的路徑,用于在訓(xùn)練前加載該checkpoint,進(jìn)行finetune等 |
|
--vocab_file |
vocabulary文件 |
用于NLP |
--max_seq_length |
輸入訓(xùn)練的最大長(zhǎng)度 |
用于NLP |
--param_set |
創(chuàng)建和訓(xùn)練模型時(shí)使用的參數(shù)集。 |
用于Transformer |
--blue_source |
包含text translate的源文件,用于計(jì)算BLEU分?jǐn)?shù) |
|
--blue_ref |
包含text translate的源文件,用于計(jì)算BLEU分?jǐn)?shù) |
|
--task_name |
任務(wù)的名稱,如MRPC,CoLA等 |
用于Bert |
--do_lower_case |
是否為輸入文本使用小寫(xiě) |
|
--train_file |
訓(xùn)練使用的SQuAD文件,如train-v1.1.json |
用于Bert模型,運(yùn)行SQuAD, --run_squad必須指定 |
--predict_file |
預(yù)測(cè)所使用的SQuAD文件,如dev-v1.1.json或test-v1.1.json |
|
--doc_stride |
當(dāng)將長(zhǎng)文檔切分為塊時(shí),塊之間取的間距大小 |
|
--max_query_length |
問(wèn)題包含的最大token數(shù)。當(dāng)問(wèn)題長(zhǎng)度超過(guò)該值時(shí),問(wèn)題將被截?cái)嗟竭@一長(zhǎng)度。 |
|
--n_best_size |
nbest_predictions.json輸出文件中生成的n-best預(yù)測(cè)的總數(shù) |
|
--max_answer_length |
生成的回答的最大長(zhǎng)度 |
|
--version_2_with_negative |
如果為T(mén)rue,表明SQuAD樣本中含有沒(méi)有答案(answer)的問(wèn)題 |
|
--run_squad |
如果為T(mén)rue,運(yùn)行SQUAD任務(wù),否則,運(yùn)行sequence (sequence-pair)分類任務(wù) |
八、GPU使用注意事項(xiàng)
1. 如何在tensorflow中指定使用GPU資源
在配置好GPU環(huán)境的TensorFlow中 ,如果操作沒(méi)有明確地指定運(yùn)行設(shè)備,那么TensorFlow會(huì)優(yōu)先選擇GPU。在默認(rèn)情況下,TensorFlow只會(huì)將運(yùn)算優(yōu)先放到/gpu:0上。如果需要將某些運(yùn)算放到不同的GPU或者CPU上,就需要通過(guò)tf.device來(lái)手工指定
import tensorflow as tf
# 通過(guò)tf.device將運(yùn)算指定到特定的設(shè)備上。
with tf.device('/cpu:0'):
a = tf.constant([1.0, 2.0, 3.0], shape=[3], name='a')
b = tf.constant([1.0, 2.0, 3.0], shape=[3], name='b')
with tf.device('/gpu:1'):
c = a + b
sess = tf.Session(config=tf.ConfigProto(log_device_placement=True))
print sess.run(c)
2. 虛擬化使用GPU的方案
通過(guò)KVM虛擬化實(shí)例使用CPU和內(nèi)存等資源,GPU不參與虛擬化。不同容器共享使用物理GPU資源
3. 分布式TensorFlow
#coding=utf-8
#多臺(tái)機(jī)器,每臺(tái)機(jī)器有一個(gè)顯卡、或者多個(gè)顯卡,這種訓(xùn)練叫做分布式訓(xùn)練
import tensorflow as tf
#現(xiàn)在假設(shè)我們有A、B、C、D四臺(tái)機(jī)器,首先需要在各臺(tái)機(jī)器上寫(xiě)一份代碼,并跑起來(lái),各機(jī)器上的代碼內(nèi)容大部分相同
# ,除了開(kāi)始定義的時(shí)候,需要各自指定該臺(tái)機(jī)器的task之外。以機(jī)器A為例子,A機(jī)器上的代碼如下:
cluster=tf.train.ClusterSpec({
"worker": [
"A_IP:2222",#格式 IP地址:端口號(hào),第一臺(tái)機(jī)器A的IP地址 ,在代碼中需要用這臺(tái)機(jī)器計(jì)算的時(shí)候,就要定義:/job:worker/task:0
"B_IP:1234"#第二臺(tái)機(jī)器的IP地址 /job:worker/task:1
"C_IP:2222"#第三臺(tái)機(jī)器的IP地址 /job:worker/task:2
],
"ps": [
"D_IP:2222",#第四臺(tái)機(jī)器的IP地址 對(duì)應(yīng)到代碼塊:/job:ps/task:0
]})
使用分布式的TensorFlow比較容易。只需在集群服務(wù)器中為 worker 節(jié)點(diǎn)分配帶名字的IP。 然后 就可以手動(dòng)或者自動(dòng)為 worker 節(jié)點(diǎn)分配操作任務(wù)
. GPU 顯存資源監(jiān)控
一個(gè)Server端的外掛模塊,提供任務(wù)特征到資源特征的映射數(shù)據(jù)集,方便后續(xù)預(yù)測(cè)模型構(gòu)建以及對(duì)芯片資源能力的定義
利用 with tf.device("{device-name}")
這種寫(xiě)法,可以將with statement代碼塊中的變量或者op指定分配到該設(shè)備上。 在上面例子中,變量 W 和 b 就被分配到 /cpu:0 這個(gè)設(shè)備上。注意,如果一個(gè)變量被分配到一個(gè)設(shè)備上,讀取這個(gè)變量也就要從這個(gè)設(shè)備讀取,寫(xiě)入這個(gè)變量也將會(huì)寫(xiě)入到這個(gè)設(shè)備。 而 output (也就是一個(gè) tf.matmul 矩陣乘法的計(jì)算操作,跟著一個(gè)tensor的加法的計(jì)算操作),以及后面的 loss 的計(jì)算(即對(duì) output 調(diào)用了 f 這個(gè)函數(shù),該函數(shù)中可能還有很多邏輯,涉及很多tensor運(yùn)算的op),分配給了 /gpu:0
這個(gè)設(shè)備。
基本原則:變量放到CPU,計(jì)算放到GPU。
這時(shí),TensorFlow實(shí)際上會(huì)將代碼中定義的Graph(計(jì)算圖)分割,根據(jù)指定的device placement將圖的不同部分分配到不同的設(shè)備上,并且在設(shè)備間建立通信(如DMA,Direct Memory Access)。這些都不需要在應(yīng)用代碼層面操作。
單機(jī)多卡
當(dāng)我們?cè)谝慌_(tái)機(jī)器上有多個(gè)GPU可用時(shí),要利用多個(gè)GPU,代碼編寫(xiě)方式的示意如下:
# Calculate the gradients for each model tower.
tower_grads = []
with tf.variable_scope(tf.get_variable_scope()):
for i in xrange(FLAGS.num_gpus):
with tf.device('/gpu:%d' % i):
with tf.name_scope('%s_%d' % (cifar10.TOWER_NAME, i)) as scope:
# Dequeues one batch for the GPU
image_batch, label_batch = batch_queue.dequeue()
# Calculate the loss for one tower of the CIFAR model. This function
# constructs the entire CIFAR model but shares the variables across
# all towers.
loss = tower_loss(scope, image_batch, label_batch)
# Reuse variables for the next tower.
tf.get_variable_scope().reuse_variables()
# Retain the summaries from the final tower.
summaries = tf.get_collection(tf.GraphKeys.SUMMARIES, scope)
# Calculate the gradients for the batch of data on this CIFAR tower.
grads = opt.compute_gradients(loss)
# Keep track of the gradients across all towers.
tower_grads.append(grads)
# We must calculate the mean of each gradient. Note that this is the
# synchronization point across all towers.
grads = average_gradients(tower_grads)
本質(zhì)上分配設(shè)備的方式和單機(jī)單卡的情況是一樣的,使用同樣的語(yǔ)法。 在上例中,假設(shè)我們有2個(gè)GPU,則代碼會(huì)按照相同的邏輯定義兩套操作,先后分配給名為 /gpu:0 和 /gpu:1 的兩個(gè)設(shè)備。
注意:
-
tensorflow的代碼中cpu和gpu的設(shè)備編號(hào)默認(rèn)從0開(kāi)始
-
比如我們?cè)跈C(jī)器上看到有兩塊GPU,通過(guò)CUDA_VISIBLE_DEVICES環(huán)境變量進(jìn)行控制,起了一個(gè)進(jìn)程,只讓0號(hào)GPU對(duì)其可見(jiàn),再起一個(gè)進(jìn)程,只讓1號(hào)GPU對(duì)其可見(jiàn),在兩個(gè)進(jìn)程的tensorflow代碼中,都是通過(guò)/gpu:0來(lái)分別指代它們可用的GPU。
-
上例屬于in-graph,從tensorboard繪制的計(jì)算圖中可以明顯看出來(lái)(下文會(huì)有對(duì)比展示)
-
上例屬于數(shù)據(jù)并行
-
上例屬于同步更新
下面展示一些示例,運(yùn)行的代碼是以TensorFlow官網(wǎng)指南(https://www.tensorflow.org/guide/using_gpu )為基礎(chǔ)的,在單機(jī)2GPU的環(huán)境以multi-tower方式運(yùn)行。運(yùn)行過(guò)程中記錄了Tensorboard使用的summary
可以看到,CPU, GPU:0, GPU:1分別用三種顏色進(jìn)行了標(biāo)記。
重要參考資料
本文大部分內(nèi)容都是看了自以下幾個(gè)資料再進(jìn)行試驗(yàn)總結(jié)出來(lái)的:
Distributed Tensorflow (TensorFlow官網(wǎng)): https://www.tensorflow.org/deploy/distributed
Distributed TensorFlow (TensorFlow Dev Summit 2017): https://www.youtube.com/watch?v=la_M6bCV91M&index=11&list=PLOU2XLYxmsIKGc_NBoIhTn2Qhraji53cv
Distributed TensorFlow (TensorFlow Dev Summit 2018): https://www.youtube.com/watch?v=-h0cWBiQ8s8 (本文沒(méi)有包括Dev Summit 2018這個(gè)talk的內(nèi)容,這里面除了基本原理之外,只講了TensorFlow如何支持All Reduce,但是只適用于單機(jī)多卡,并且是High Level API。多機(jī)多卡的方面演講者也只推薦了Horovod這種方式。)文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-776731.html
另外還有官網(wǎng)關(guān)于使用GPU的指南: https://www.tensorflow.org/guide/using_gpu文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-776731.html
到了這里,關(guān)于tensorflow 1.15 gpu docker環(huán)境搭建;Nvidia Docker容器基于TensorFlow1.15測(cè)試GPU;——全流程應(yīng)用指南的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!