레이블이 RNN인 게시물을 표시합니다. 모든 게시물 표시
레이블이 RNN인 게시물을 표시합니다. 모든 게시물 표시

2018년 5월 10일 목요일

RNN PTB benchmark 수행방법

CNN은 Image classification이나 object detection 같은 정적인 image 처리에 많이 사용됩니다.   그러나 기계 번역(machine translation)이나 동영상 captioning 등을 deep learning으로 처리할 때는 시계열(time-series) 분석 등을 통해 미래를 예측하는 것이 필요합니다.  여기에는 CNN 대신 LSTM과 같은 RNN을 사용합니다.

문제는 CNN과는 달리, RNN/LSTM은 그 본질상 data history를 참조해야 하므로 메모리 사용량이 많다는 점입니다.  당연히 시스템 대역폭이 전체 시스템 성능에 영향을 끼치게 됩니다.

RNN 관련 가장 일반적인 벤치마크는 tensorflow models에 포함되어 있는 language modeling이며, 이는 영어 단어 모음인 PTB dataset을 이용합니다.  이것을 이용하여 적절한 성능 벤치마크를 해볼 수 있습니다.  먼저, python3에 tensorflow 1.5.1을 설치한 환경을 준비합니다.

[u0017649@sys-93214 ~]$ git clone https://github.com/tensorflow/models.git

[u0017649@sys-93214 ~]$ cd models/tutorials/rnn/ptb

이 벤치마크에서 사용하는 PTB dataset은 아래와 같이 download 받을 수 있습니다.

[u0017649@sys-93214 ptb]$ wget http://www.fit.vutbr.cz/~imikolov/rnnlm/simple-examples.tgz

[u0017649@sys-93215 ptb]$ tar -zxvf simple-examples.tgz

이제 다음과 같이 ptb_word_lm.py를 수행하면 됩니다.

[u0017649@sys-93214 ptb]$ time python ptb_word_lm.py --data_path=./simple-examples/data/ --model=large
...
Epoch: 1 Learning rate: 1.000
0.008 perplexity: 25072.184 speed: 1565 wps
0.107 perplexity: 1574.659 speed: 2033 wps
0.206 perplexity: 974.553 speed: 2057 wps
0.306 perplexity: 754.209 speed: 2065 wps
0.405 perplexity: 643.568 speed: 2069 wps
...
0.704 perplexity: 133.906 speed: 2085 wps
0.803 perplexity: 133.743 speed: 2085 wps
0.903 perplexity: 132.101 speed: 2085 wps
Epoch: 10 Train Perplexity: 131.618
Epoch: 10 Valid Perplexity: 117.277
Test Perplexity: 113.380
...

다만 이를 그대로 수행하면 무려 55 epochs를 수행하므로 (P100 4장으로 해도 약 3시간 정도), 좀 짧게 수행하시려면 아래와 같이 max_epoch과 max_max_epoch을 수정하시면 됩니다.   또 좀더 많은 hidden parameter를 사용하면 per word perplexity를 더 줄일 수 있는데, 대신 시간도 더 많이 걸리고 더 많은 메모리를 사용하게 됩니다.

[u0017649@sys-93214 ptb]$
...
class LargeConfig(object):
  """Large config."""
  init_scale = 0.04
  learning_rate = 1.0
  max_grad_norm = 10
  num_layers = 2
  num_steps = 2
  hidden_size = 1000
  max_epoch = 4  #원래 14
  max_max_epoch = 10   #원래 55
  keep_prob = 0.35
  lr_decay = 1 / 1.15
  batch_size = 20
  vocab_size = 10000
  rnn_mode = BLOCK
...

저는 --num_gpus=0 옵션을 쓰서 GPU가 없는 CPU 환경에서 수행했는데, 이때 위의 python program이 차지하는 real memory 사용량(ps aux에서 봤을 때의 Res Set 항목)을 보면 RNN이 정말 메모리를 dynamic하게 늘였다줄였다를 반복하는 것을 보실 수 있습니다.   아래는 10분 동안만 2초 간격으로 그 메모리 사용량을 모니터링한 결과입니다.  계속 저 패턴이 반복됩니다.



2018년 3월 20일 화요일

구글 기계 번역을 위한 RNN에 IBM POWER9이 사용되고 있을까 ?

어제밤, Forbes지에 구글(Google)이 POWER9 프로세서를 자사 데이터센터에 활용하고 있음을 공식적으로 발표했다는 기사가 실렸습니다.

원래 자사 데이터센터에 대해서는 거의 모든 것을 비밀에 부치는 구글이 뒤늦게나마 특정 프로세서를 사용 중임을 밝힌 것은 이례적인 일입니다.  라스베가스에서 열린 OpenPOWER Summit 2018 행사에서 나온 이 발표는 굉장히 놀라운 소식은 아니고, 이미 작년부터 예고되어 있었던 것입니다.  이미 작년에 구글은 클라우드 업체인 Rackspace와 함께 POWER9 프로세서를 장착한 자체 서버 아키텍처를 OCP(Open Compute Project) 기반으로 설계 중임을 밝혔고, 그 코드네임이 자이우스(Zaius)라는 것도 공개했었습니다.

구글 부사장인 메어 머호니(Maire Mahoney)는 올해 행사에서 Zaius가 구글 데이터센터에 프로덕션용으로 배치되어 있으며, 그 숫자를 계속 늘려가고 있다고 밝혔습니다.  또한 이 플랫폼이 "Google Strong"하다라고 평가했는데, 이 표현은 안정적이고 견고하다는 뜻이라고 설명했습니다.

구글이 POWER9의 어떤 점을 마음에 들어하는지에 대해서 머호니는 3가지 사항을 이야기했습니다.

1) 핵심 구글 검색 업무를 위한 더 많은 코어와 thread 
: 이는 Intel x86의 hyperthreading에서는 HW thread가 2개 밖에 나오지 않는 것에 비해 POWER9의 SMT는 4개 혹은 8개의 HW thread를 제공하는 것을 의미합니다.  이는 다수의 사용자에게 서비스를 제공해야 하는 구글 검색 업무에 있어 특히 도움이 됩니다.

2) RNN 기계 학습을 위한 더 큰 메모리 대역폭
: 가령 Intel E5-2698 v4(Broadwell)의 경우 소켓당 76.8GB/s의 메모리 대역폭을 가지지만 (여기를 클릭), 동급 2-socket용 POWER9 프로세서는 소켓당 120GB/s의 메모리 대역폭을 자랑(여기를 클릭)합니다.  이 부분이 특히 기계 번역 등에 사용되는 RNN 기계 학습에서 매우 유효하다고 구글은 판단하는 것입니다.

3) OpenCAPI 가속 bus에 자리잡은 더 빠르고 더 개방적인 flash NAND
: 'OpenCAPI 가속 bus'라고 하는 것은 POWER9에 on-chip 형태로 내장된 25G link들을 이야기하는 것입니다.  원래 IBM 내에서의 코드명이 Bluelink였던 이 HW 기술은 PCIe를 대체하여 GPU, FPGA, ASIC 및 storage-class memory 등을 low latency high bandwidth로 연결하기 위한 하드웨어 버스 기술이라고 할 수 있습니다.  POWER9 프로세서에는 이런 25G link들이 최대 48-lane까지 내장되는데, 이들은 PCIe Gen4 lane 외에 추가로 장착되는 것이며, 특히 GPU나 FPGA와 같은 가속기를 위한 최고의 프로세서를 자처하는 POWER9에서 가장 자랑하는 기술이기도 합니다.  이 기술은 AMD, NVIDIA, HPE 및 Dell-EMC 등 주요 벤더들이 모두 참여하는 OpenCAPI.org를 통해 모든 CPU 아키텍처에서 표준적으로 사용하는 개방형 기술로 발전되고 있습니다.


1번은 원래부터 전통적인 POWER 아키텍처의 장점이었으니 별로 특별한 점은 없습니다.

2번의 경우 구글이 기계 번역(machine translation) 서비스를 제공한다는 점에서 특히 흥미롭습니다.  구글은 2016년에 RNN을 이용한 기계 번역 연구에 착수했다고 밝힌 바 (여기를 클릭) 있습니다.  RNN은 이미지 인식에 많이 쓰이는 CNN과는 달리 CPU-memory 간의 대역폭이 많이 사용되는데 (여기를 클릭), Intel x86 대비 CPU-memory 대역폭이 월등하다는 점에서 구글이 POWER9에 주목한 것으로 보입니다.

3번은 더욱 흥미롭습니다.  구글이 OpenCAPI를 이용한 flash NAND 사용에 관심이 있거나 또는 이미 사용하고 있다는 것을 밝힌 것이기 때문입니다.   OpenCAPI 컨소시엄에 참가한 Mellanox, Nallatech, Xilinx 등의 여러 업체들이 이번 OpenPOWER Summit 2018 행사에서 다양한 FPGA 등의 관련 제품을 내놓기도 했습니다만, 이렇게 구글이 실질적인 use case를 가지고 있다는 것은 의미하는 바가 큽니다.


OpenCAPI 주요 회원사들 중 일부  (출처 http://opencapi.org/membership/current-members)


OpenCAPI 주요 속성 (출처 http://opencapi.org/wp-content/uploads/2016/09/OpenCAPI-Exhibit-SC17.pdf)


자세한 소식은 아래의 포브스지 본문을 읽어보시기 바랍니다.

https://www.forbes.com/sites/patrickmoorhead/2018/03/19/headed-into-its-fifth-year-openpower-has-momentum-into-the-power9-generation

2018년 3월 14일 수요일

Deep Learning용 GPU 서버 성능 측정을 위한 benchmark test 방법 몇가지

Deep Learning을 위한 GPU 서버들은 대부분 NVIDIA GPU를 사용하니까,  그 서버의 성능은 NVIDIA GPU 중 어떤 것을 몇 개 장착했느냐가 가장 중요합니다.  하지만 서버 벤더별 모델별로 그 특장점이 다 다르고 또 어떤 서버들은 NVLink 등 GPU와 GPU, GPU와 CPU의 연결 방식에 있어 차별점을 두고 있습니다.  어떤 경우엔 값비싼 최신 GPU를 잔뜩 달았지만 시스템 대역폭이 부족하여 제 성능을 내지 못할 수도 있고요.

이런 점을 확인해보려면 그냥 자신의 data를 이용하여 자신의 신경망을 직접 돌려보고 성능을 비교하는 것이 좋습니다만, 거기에는 많은 시간과 돈, 노력이 필요하지요.

여기서는 그런 점들을 비교적 쉽게 테스트해볼 수 있는 사실상 표준적인 벤치마크 방법론 몇가지를 소개합니다.  어느 경우든 linux의 time 명령을 이용해서 전체 수행 시간만 측정하면 되니까 매우 편리합니다.   평가 대상이 신경망 자체가 아니라 GPU 서버 하드웨어이고 다 같은 data와 같은 신경망을 사용하니까 테스트 결과의 accuracy 등은 비교해 보실 필요가 없습니다.

아래 테스트들은 tensorflow 1.4.1, 그리고 Anaconda3에서 제공되는 python3.6을 사용해서 수행한 것입니다.

[user1@gpusvr ~]$ which python
~/anaconda3/bin/python

먼저, 다음과 같이 github로부터 tensorflow models를 clone 합니다.

[user1@gpusvr ~]$ git clone https://github.com/tensorflow/models.git


1. CIFAR10

이중 가장 많이 사용되는 것이 cifar10입니다.  수행할 cifar10_multi_gpu_train.py code를 열어보면 조정 가능한 parameter가 무엇이고 그 default 값이 무엇인지 보실 수 있습니다.  그를 명령어에서 적절히 수정하여 수행하시면 됩니다. 

[user1@gpusvr ~]$ cd models/tutorials/image/cifar10

[user1@gpusvr cifar10]$  vi cifar10_multi_gpu_train.py
...
parser.add_argument('--max_steps', type=int, default=1000000, 
...
parser.add_argument('--num_gpus', type=int, default=1, 

이제 아래와 같이 수행합니다.  여기서는 # max_steps=10000 num_gpus=4 으로 수행합니다.  다만, 처음에 이 테스트를 수행할 때는 internet에서 dataset을 download 받는 것부터 시작합니다.  그 부분은 당연히 테스트 수행 시간에서 제외해야 합니다.  따라서 처음 테스트는 측정하지 마시고, 2번째 테스트 이후를 측정하시면 됩니다.  그때는 이미 download 받아놓은 data를 사용하거든요.

[user1@gpusvr cifar10]$ time python cifar10_multi_gpu_train.py --max_steps=10000 --num_gpus=4 --batch_size 512
...
2018-03-09 11:36:47.084991: step 9990, loss = 0.58 (25710.1 examples/sec; 0.020 sec/batch)

이렇게 수행해보면 GPU 사용량은 17~22% 정도로 상당히 낮습니다.  batch_size를 8배인 4096으로 키워도 되는데, 이때 그에 따라 max_steps도 1/8로 줄여야 합니다.  아래는 # max_steps=1250 num_gpus=4 으로 수행한 것입니다.

[user1@gpusvr cifar10]$ time python cifar10_multi_gpu_train.py --max_steps=1250 --num_gpus=4 --batch_size 4096 
...
2018-03-09 13:11:57.589629: step 1240, loss = 2.08 (28222.4 examples/sec; 0.145 sec/batch)

성능이 조금 나아지긴 합니다만, 극적으로 나아지진 않습니다.


2. Alexnet

여기에 포함된 alexnet_benchmark.py은 single GPU만 이용합니다.

[user1@gpusvr alexnet]$ time python alexnet_benchmark.py --batch_size=1024 --num_batches=1000
...
2018-03-09 14:32:56.566184: step 990, duration = 0.522
2018-03-09 14:33:01.260806: Forward-backward across 1000 steps, 0.521 +/- 0.002 sec / batch

그러나 여기서도 다음과 같이 script를 짜서 여러개의 GPU를 사용하는 벤치마크를 할 수 있습니다.  CUDA_VISIBLE_DEVICES 환경변수를 이용하여 각 세션마다 특정 GPU를 할당한 뒤, GPU 개수만큼 alexnet_benchmark.py를 병렬로 수행하는 것입니다.  이것도 의미가 있는 테스트입니다.  실제 대부분의 고객들이 여러개의 GPU가 달린 서버를 사용할 때, 여러개의 GPU를 이용하여 하나의 model을 training하는 경우보다는 아래 script처럼 여러 연구원이 1개씩의 GPU를 가지고 각자의 training을 수행하는 경우가 대부분이기 때문입니다.  그런 경우에도 CPU-GPU 간의 병목 없이 원활한 성능이 나오는지 확인하는 것도 중요합니다.

[user1@gpusvr alexnet]$ vi alexrun.sh
echo "Starting !"
CUDA_VISIBLE_DEVICES=0 python alexnet_benchmark.py --batch_size=1024 --num_batches=1000 &
CUDA_VISIBLE_DEVICES=1 python alexnet_benchmark.py --batch_size=1024 --num_batches=1000 &
CUDA_VISIBLE_DEVICES=2 python alexnet_benchmark.py --batch_size=1024 --num_batches=1000 &
CUDA_VISIBLE_DEVICES=3 python alexnet_benchmark.py --batch_size=1024 --num_batches=1000 &
wait
echo "Completed !"

[user1@gpusvr alexnet]$ chmod a+x alexrun.sh
[user1@gpusvr alexnet]$ time ./alexrun.sh
Starting !
....
2018-03-09 14:50:15.533991: step 990, duration = 0.523
2018-03-09 14:50:17.971840: step 990, duration = 0.521
2018-03-09 14:50:18.197058: step 990, duration = 0.524
2018-03-09 14:50:20.202855: step 990, duration = 0.525
2018-03-09 14:50:20.231726: Forward-backward across 1000 steps, 0.522 +/- 0.001 sec / batch
2018-03-09 14:50:22.691048: Forward-backward across 1000 steps, 0.524 +/- 0.002 sec / batch
2018-03-09 14:50:22.908471: Forward-backward across 1000 steps, 0.523 +/- 0.002 sec / batch
2018-03-09 14:50:24.927234: Forward-backward across 1000 steps, 0.525 +/- 0.002 sec / batch
Completed !

실제 수행 결과를 보면 아무래도 1개 GPU만 사용했을 때보다 약간 더 느리게 나오는 것을 보실 수 있습니다.


3. RNN PTB  

이것도 1개의 GPU만 이용하는 benchmark test입니다.  다른 것과는 달리 image에 대한 CNN 트레이닝이 아니라 text에 대한 RNN 트레이닝이라는 점이 주목할 만 합니다.

[user1@gpusvr ptb]$ pwd
/home/user1/models/tutorials/rnn/ptb

이 테스트를 위한 sample data는 아래에서 따로 download 받아야 합니다.

[user1@gpusvr ptb]$ wget http://www.fit.vutbr.cz/~imikolov/rnnlm/simple-examples.tgz

[user1@gpusvr ptb]$ tar xvfz simple-examples.tgz -C $HOME

[user1@gpusvr ptb]$ du ~/simple-examples
17256   /home/user1/simple-examples/data
74840   /home/user1/simple-examples/models
516     /home/user1/simple-examples/rnnlm-0.2b
12      /home/user1/simple-examples/1-train
12      /home/user1/simple-examples/3-combination
0       /home/user1/simple-examples/2-nbest-rescore/lattices/nbest
2860    /home/user1/simple-examples/2-nbest-rescore/lattices
2900    /home/user1/simple-examples/2-nbest-rescore
12      /home/user1/simple-examples/5-one-iter
12      /home/user1/simple-examples/6-recovery-during-training
12      /home/user1/simple-examples/7-dynamic-evaluation
0       /home/user1/simple-examples/temp
12      /home/user1/simple-examples/8-direct
12      /home/user1/simple-examples/4-data-generation
12      /home/user1/simple-examples/9-char-based-lm
95608   /home/user1/simple-examples

Training에 사용되는 data는 총 94MB 정도로서 작은 편입니다.

[user1@gpusvr ptb]$ du -sm ~/simple-examples
94      /home/user1/simple-examples

Data 내용은 아래에 보시다시피 text들입니다.

[user1@gpusvr ~]$ cd /home/user1/simple-examples/data

[user1@gpusvr data]$ head ptb.train.txt
 aer banknote berlitz calloway centrust cluett fromstein gitano guterman hydro-quebec ipo kia memotec mlx nahb punts rake regatta rubens sim snack-food ssangyong swapo wachter
 pierre <unk> N years old will join the board as a nonexecutive director nov. N
 mr. <unk> is chairman of <unk> n.v. the dutch publishing group
 rudolph <unk> N years old and former chairman of consolidated gold fields plc was named a nonexecutive director of this british industrial conglomerate
 a form of asbestos once used to make kent cigarette filters has caused a high percentage of cancer deaths among a group of workers exposed to it more than N years ago researchers reported
 the asbestos fiber <unk> is unusually <unk> once it enters the <unk> with even brief exposures to it causing symptoms that show up decades later researchers said
 <unk> inc. the unit of new york-based <unk> corp. that makes kent cigarettes stopped using <unk> in its <unk> cigarette filters in N
 although preliminary findings were reported more than a year ago the latest results appear in today 's new england journal of medicine a forum likely to bring new attention to the problem
 a <unk> <unk> said this is an old story
 we 're talking about years ago before anyone heard of asbestos having any questionable properties

[user1@gpusvr data]$ head ptb.char.train.txt
a e r _ b a n k n o t e _ b e r l i t z _ c a l l o w a y _ c e n t r u s t _ c l u e t t _ f r o m s t e i n _ g i t a n o _ g u t e r m a n _ h y d r o - q u e b e c _ i p o _ k i a _ m e m o t e c _ m l x _ n a h b _ p u n t s _ r a k e _ r e g a t t a _ r u b e n s _ s i m _ s n a c k - f o o d _ s s a n g y o n g _ s w a p o _ w a c h t e r
 p i e r r e _ < u n k > _ N _ y e a r s _ o l d _ w i l l _ j o i n _ t h e _ b o a r d _ a s _ a _ n o n e x e c u t i v e _ d i r e c t o r _ n o v . _ N
 m r . _ < u n k > _ i s _ c h a i r m a n _ o f _ < u n k > _ n . v . _ t h e _ d u t c h _ p u b l i s h i n g _ g r o u p
 r u d o l p h _ < u n k > _ N _ y e a r s _ o l d _ a n d _ f o r m e r _ c h a i r m a n _ o f _ c o n s o l i d a t e d _ g o l d _ f i e l d s _ p l c _ w a s _ n a m e d _ a _ n o n e x e c u t i v e _ d i r e c t o r _ o f _ t h i s _ b r i t i s h _ i n d u s t r i a l _ c o n g l o m e r a t e
 a _ f o r m _ o f _ a s b e s t o s _ o n c e _ u s e d _ t o _ m a k e _ k e n t _ c i g a r e t t e _ f i l t e r s _ h a s _ c a u s e d _ a _ h i g h _ p e r c e n t a g e _ o f _ c a n c e r _ d e a t h s _ a m o n g _ a _ g r o u p _ o f _ w o r k e r s _ e x p o s e d _ t o _ i t _ m o r e _ t h a n _ N _ y e a r s _ a g o _ r e s e a r c h e r s _ r e p o r t e d
 t h e _ a s b e s t o s _ f i b e r _ < u n k > _ i s _ u n u s u a l l y _ < u n k > _ o n c e _ i t _ e n t e r s _ t h e _ < u n k > _ w i t h _ e v e n _ b r i e f _ e x p o s u r e s _ t o _ i t _ c a u s i n g _ s y m p t o m s _ t h a t _ s h o w _ u p _ d e c a d e s _ l a t e r _ r e s e a r c h e r s _ s a i d
 < u n k > _ i n c . _ t h e _ u n i t _ o f _ n e w _ y o r k - b a s e d _ < u n k > _ c o r p . _ t h a t _ m a k e s _ k e n t _ c i g a r e t t e s _ s t o p p e d _ u s i n g _ < u n k > _ i n _ i t s _ < u n k > _ c i g a r e t t e _ f i l t e r s _ i n _ N
 a l t h o u g h _ p r e l i m i n a r y _ f i n d i n g s _ w e r e _ r e p o r t e d _ m o r e _ t h a n _ a _ y e a r _ a g o _ t h e _ l a t e s t _ r e s u l t s _ a p p e a r _ i n _ t o d a y _ ' s _ n e w _ e n g l a n d _ j o u r n a l _ o f _ m e d i c i n e _ a _ f o r u m _ l i k e l y _ t o _ b r i n g _ n e w _ a t t e n t i o n _ t o _ t h e _ p r o b l e m
 a _ < u n k > _ < u n k > _ s a i d _ t h i s _ i s _ a n _ o l d _ s t o r y
 w e _ ' r e _ t a l k i n g _ a b o u t _ y e a r s _ a g o _ b e f o r e _ a n y o n e _ h e a r d _ o f _ a s b e s t o s _ h a v i n g _ a n y _ q u e s t i o n a b l e _ p r o p e r t i e s

이제 training을 해보겠습니다.  아래와 같이 전체 training 및 test에 걸린 시간을 측정하면 됩니다.

[user1@gpusvr ptb]$ time python ptb_word_lm.py --data_path=$HOME/simple-examples/data/ --model=small
...
Epoch: 1 Learning rate: 1.000
...
Epoch: 1 Train Perplexity: 268.322
Epoch: 1 Valid Perplexity: 178.848
Epoch: 2 Learning rate: 1.000
...
Epoch: 13 Train Perplexity: 40.549
Epoch: 13 Valid Perplexity: 119.536
Test Perplexity: 114.159

위의 Alexnet 테스트에서처럼, 이 test도 여러개의 세션을 동시에 수행함으로써 시스템 대역폭이 충분하여 multi-user 동시 사용시에도 충분한 성능을 내는지 확인해보실 수 있습니다.

[user1@gpusvr ptb]$ vi ptbrun.sh
echo "Starting !"
CUDA_VISIBLE_DEVICES=0 python ptb_word_lm.py --data_path=$HOME/simple-examples/data/ --model=small &
CUDA_VISIBLE_DEVICES=1 python ptb_word_lm.py --data_path=$HOME/simple-examples/data/ --model=small &
CUDA_VISIBLE_DEVICES=2 python ptb_word_lm.py --data_path=$HOME/simple-examples/data/ --model=small &
CUDA_VISIBLE_DEVICES=3 python ptb_word_lm.py --data_path=$HOME/simple-examples/data/ --model=small &
wait
echo "Completed !"

실제로 아래와 같이 수행해보면 single session으로 single GPU를 이용했을 때에 비해 약간 성능이 떨어지는 것을 보실 수 있습니다.

[user1@gpusvr ptb]$ time ./ptbrun.sh
Starting !
...
Epoch: 13 Valid Perplexity: 119.785
...
Test Perplexity: 113.431
Completed !