Apache MXNet ๋ฐ Horovod๋ฅผ ์‚ฌ์šฉํ•œ ๋ถ„์‚ฐ ํ•™์Šต

๊ธฐ์‚ฌ์˜ ๋ฒˆ์—ญ์€ ๊ณผ์ • ์‹œ์ž‘ ์ „๋‚ ์— ์ค€๋น„๋˜์—ˆ์Šต๋‹ˆ๋‹ค. "๋น…๋ฐ์ดํ„ฐ๋ฅผ ํ™œ์šฉํ•œ ์‚ฐ์—…์šฉ ML"

์—ฌ๋Ÿฌ ๊ณ ์„ฑ๋Šฅ ์ปดํ“จํŒ… ์ธ์Šคํ„ด์Šค์— ๋Œ€ํ•œ ๋ถ„์‚ฐ ํ›ˆ๋ จ์€ ๋Œ€๋Ÿ‰์˜ ๋ฐ์ดํ„ฐ์— ๋Œ€ํ•œ ํ˜„๋Œ€ ์‹ฌ์ธต ์‹ ๊ฒฝ๋ง์˜ ํ›ˆ๋ จ ์‹œ๊ฐ„์„ ๋ช‡ ์ฃผ์—์„œ ๋ช‡ ์‹œ๊ฐ„, ์‹ฌ์ง€์–ด ๋ช‡ ๋ถ„์œผ๋กœ ๋‹จ์ถ•ํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ์ด ํ›ˆ๋ จ ๊ธฐ์ˆ ์€ ๋”ฅ ๋Ÿฌ๋‹์˜ ์‹ค์ œ ์‘์šฉ ๋ถ„์•ผ์—์„œ ๋„๋ฆฌ ๋ณด๊ธ‰๋ฉ๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž๋Š” ์—ฌ๋Ÿฌ ์ธ์Šคํ„ด์Šค์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ณต์œ ํ•˜๊ณ  ๋™๊ธฐํ™”ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์ดํ•ดํ•ด์•ผ ํ•˜๋ฉฐ, ์ด๋Š” ๊ฒฐ๊ณผ์ ์œผ๋กœ ํ™•์žฅ ํšจ์œจ์„ฑ์— ํฐ ์˜ํ–ฅ์„ ๋ฏธ์นฉ๋‹ˆ๋‹ค. ๋˜ํ•œ ์‚ฌ์šฉ์ž๋Š” ๋‹จ์ผ ์ธ์Šคํ„ด์Šค์—์„œ ์‹คํ–‰๋˜๋Š” ๊ต์œก ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์—ฌ๋Ÿฌ ์ธ์Šคํ„ด์Šค์— ๋ฐฐํฌํ•˜๋Š” ๋ฐฉ๋ฒ•๋„ ์•Œ์•„์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์ด ๊ธฐ์‚ฌ์—์„œ๋Š” ๊ฐœ๋ฐฉํ˜• ๋”ฅ ๋Ÿฌ๋‹ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ธ Apache MXNet๊ณผ Horovod ๋ถ„์‚ฐ ํ•™์Šต ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ•™์Šต์„ ๋ฐฐํฌํ•˜๋Š” ๋น ๋ฅด๊ณ  ์‰ฌ์šด ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค. Horovod ํ”„๋ ˆ์ž„์›Œํฌ์˜ ์„ฑ๋Šฅ ์ด์ ์„ ๋ช…ํ™•ํ•˜๊ฒŒ ๋ณด์—ฌ์ฃผ๊ณ  Horovod์™€ ๋ถ„์‚ฐ ๋ฐฉ์‹์œผ๋กœ ์ž‘๋™ํ•˜๋„๋ก MXNet ๊ต์œก ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์ž‘์„ฑํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค.

Apache MXNet์ด๋ž€ ๋ฌด์—‡์ž…๋‹ˆ๊นŒ?

์•„ํŒŒ์น˜ MXNet ์‹ฌ์ธต ์‹ ๊ฒฝ๋ง์„ ์ƒ์„ฑ, ํ›ˆ๋ จ ๋ฐ ๋ฐฐํฌํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋˜๋Š” ์˜คํ”ˆ ์†Œ์Šค ๋”ฅ ๋Ÿฌ๋‹ ํ”„๋ ˆ์ž„์›Œํฌ์ž…๋‹ˆ๋‹ค. MXNet์€ ์‹ ๊ฒฝ๋ง ๊ตฌํ˜„๊ณผ ๊ด€๋ จ๋œ ๋ณต์žก์„ฑ์„ ์ถ”์ƒํ™”ํ•˜๊ณ  ์„ฑ๋Šฅ๊ณผ ํ™•์žฅ์„ฑ์ด ๋›ฐ์–ด๋‚˜๋ฉฐ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋„๋ฆฌ ์‚ฌ์šฉ๋˜๋Š” ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด์— ๋Œ€ํ•œ API๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. Python, C + +, Clojure, ์ž๋ฐ”, ์ค„๋ฆฌ์•„, R, ์Šค์นผ๋ผ ๋“ฑ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

๋งค๊ฐœ๋ณ€์ˆ˜ ์„œ๋ฒ„๋ฅผ ์‚ฌ์šฉํ•˜๋Š” MXNet์˜ ๋ถ„์‚ฐ ๊ต์œก

MXNet์˜ ํ‘œ์ค€ ๋ถ„์‚ฐ ํ•™์Šต ๋ชจ๋“ˆ ๋งค๊ฐœ๋ณ€์ˆ˜ ์„œ๋ฒ„ ์ ‘๊ทผ ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ๋งค๊ฐœ๋ณ€์ˆ˜ ์„œ๋ฒ„ ์„ธํŠธ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐ ์ž‘์—…์ž๋กœ๋ถ€ํ„ฐ ๊ฒฝ์‚ฌ๋„๋ฅผ ์ˆ˜์ง‘ํ•˜๊ณ , ์ง‘๊ณ„๋ฅผ ์ˆ˜ํ–‰ํ•˜๊ณ , ๋‹ค์Œ ์ตœ์ ํ™” ๋ฐ˜๋ณต์„ ์œ„ํ•ด ์—…๋ฐ์ดํŠธ๋œ ๊ฒฝ์‚ฌ๋„๋ฅผ ์ž‘์—…์ž์—๊ฒŒ ๋‹ค์‹œ ๋ณด๋ƒ…๋‹ˆ๋‹ค. ์„œ๋ฒ„์™€ ์ž‘์—…์ž์˜ ์ •ํ™•ํ•œ ๋น„์œจ์„ ๊ฒฐ์ •ํ•˜๋Š” ๊ฒƒ์ด ํšจ๊ณผ์ ์ธ ํ™•์žฅ์˜ ํ•ต์‹ฌ์ž…๋‹ˆ๋‹ค. ๋งค๊ฐœ๋ณ€์ˆ˜ ์„œ๋ฒ„๊ฐ€ ํ•˜๋‚˜๋งŒ ์žˆ๋Š” ๊ฒฝ์šฐ ๊ณ„์‚ฐ์— ๋ณ‘๋ชฉ ํ˜„์ƒ์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฐ˜๋Œ€๋กœ ๋„ˆ๋ฌด ๋งŽ์€ ์„œ๋ฒ„๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋‹ค๋Œ€๋‹ค ํ†ต์‹ ์œผ๋กœ ์ธํ•ด ๋ชจ๋“  ๋„คํŠธ์›Œํฌ ์—ฐ๊ฒฐ์ด ์ •์ฒด๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ํ˜ธ๋กœ๋ณด๋“œ๋Š” ๋ฌด์—‡์ธ๊ฐ€์š”?

ํ˜ธ๋กœ ๋ณด๋“œ Uber์—์„œ ๊ฐœ๋ฐœํ•œ ๊ฐœ๋ฐฉํ˜• ๋ถ„์‚ฐ ๋”ฅ๋Ÿฌ๋‹ ํ”„๋ ˆ์ž„์›Œํฌ์ž…๋‹ˆ๋‹ค. NCCL(NVIDIA Collective Communications Library) ๋ฐ MPI(Message Passing Interface)์™€ ๊ฐ™์€ ํšจ์œจ์ ์ธ GPU ๊ฐ„ ๋ฐ ๋…ธ๋“œ ๊ฐ„ ๊ธฐ์ˆ ์„ ํ™œ์šฉํ•˜์—ฌ vorec ์ „์ฒด์— ๋ชจ๋ธ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ๋ฐฐํฌํ•˜๊ณ  ์ง‘๊ณ„ํ•ฉ๋‹ˆ๋‹ค. ์‹ฌ์ธต ์‹ ๊ฒฝ๋ง ๋ชจ๋ธ ์ž‘์—… ์‹œ ๋„คํŠธ์›Œํฌ ๋Œ€์—ญํญ ์‚ฌ์šฉ์„ ์ตœ์ ํ™”ํ•˜๊ณ  ํ™•์žฅ์„ฑ์ด ๋›ฐ์–ด๋‚ฉ๋‹ˆ๋‹ค. ํ˜„์žฌ ์—ฌ๋Ÿฌ ๊ฐ€์ง€ ์ธ๊ธฐ ์žˆ๋Š” ๊ธฐ๊ณ„ ํ•™์Šต ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. MX ๋„ท, Tensorflow, Keras ๋ฐ PyTorch.

MXNet ๋ฐ Horovod ํ†ตํ•ฉ

MXNet์€ Horovod์— ์ •์˜๋œ ๋ถ„์‚ฐ ํ•™์Šต API๋ฅผ ํ†ตํ•ด Horovod์™€ ํ†ตํ•ฉ๋ฉ๋‹ˆ๋‹ค. Horovod ํ†ต์‹  API horovod.broadcast(), horovod.allgather() ะธ horovod.allreduce() ์ž‘์—… ๊ทธ๋ž˜ํ”„์˜ ์ผ๋ถ€๋กœ MXNet ์—”์ง„์˜ ๋น„๋™๊ธฐ ์ฝœ๋ฐฑ์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ตฌํ˜„๋ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๋ฐฉ์‹์œผ๋กœ MXNet ์—”์ง„์€ ํ†ต์‹ ๊ณผ ๊ณ„์‚ฐ ๊ฐ„์˜ ๋ฐ์ดํ„ฐ ์ข…์†์„ฑ์„ ์‰ฝ๊ฒŒ ์ฒ˜๋ฆฌํ•˜์—ฌ ๋™๊ธฐํ™”๋กœ ์ธํ•œ ์„ฑ๋Šฅ ์†์‹ค์„ ๋ฐฉ์ง€ํ•ฉ๋‹ˆ๋‹ค. Horovod์— ์ •์˜๋œ ๋ถ„์‚ฐ ์ตœ์ ํ™” ๊ฐœ์ฒด horovod.DistributedOptimizer ํŒฝ์ฐฝํ•˜๋‹ค ์ตœ์ ํ™” ๋ถ„์‚ฐ ๋งค๊ฐœ๋ณ€์ˆ˜ ์—…๋ฐ์ดํŠธ๋ฅผ ์œ„ํ•ด ํ•ด๋‹น Horovod API๋ฅผ ํ˜ธ์ถœํ•˜๋„๋ก MXNet์—์„œ. ์ด๋Ÿฌํ•œ ๋ชจ๋“  ๊ตฌํ˜„ ์„ธ๋ถ€ ์‚ฌํ•ญ์€ ์ตœ์ข… ์‚ฌ์šฉ์ž์—๊ฒŒ ํˆฌ๋ช…ํ•˜๊ฒŒ ๊ณต๊ฐœ๋ฉ๋‹ˆ๋‹ค.

๋น ๋ฅธ ์‹œ์ž‘

MacBook์—์„œ MXNet ๋ฐ Horovod๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ MNIST ๋ฐ์ดํ„ฐ์„ธํŠธ์—์„œ ์†Œ๊ทœ๋ชจ ์ปจ๋ฒŒ๋ฃจ์…˜ ์‹ ๊ฒฝ๋ง ํ›ˆ๋ จ์„ ๋น ๋ฅด๊ฒŒ ์‹œ์ž‘ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
๋จผ์ € PyPI์—์„œ mxnet ๋ฐ horovod๋ฅผ ์„ค์น˜ํ•ฉ๋‹ˆ๋‹ค.

pip install mxnet
pip install horovod

์ฐธ๊ณ : ๋„์ค‘์— ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ๊ฒฝ์šฐ pip ์„ค์น˜ horovod์–ด์ฉŒ๋ฉด ๋ณ€์ˆ˜๋ฅผ ์ถ”๊ฐ€ํ•ด์•ผ ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค MACOSX_DEPLOYMENT_TARGET=10.vv์–ด๋””์—์„œ vv โ€“ ์ด๋Š” MacOS ๋ฒ„์ „์˜ ๋ฒ„์ „์ž…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด MacOSX Sierra์˜ ๊ฒฝ์šฐ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ž‘์„ฑํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. MACOSX_DEPLOYMENT_TARGET=10.12 pip ์„ค์น˜ Horovod

๊ทธ๋Ÿฐ ๋‹ค์Œ OpenMPI๋ฅผ ์„ค์น˜ํ•˜์‹ญ์‹œ์˜ค. ๋”ฐ๋ผ์„œ.

๋งˆ์ง€๋ง‰์œผ๋กœ ํ…Œ์ŠคํŠธ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ๋‹ค์šด๋กœ๋“œํ•˜์‹ญ์‹œ์˜ค. mxnet_mnist.py ๋”ฐ๋ผ์„œ ์ž‘์—… ๋””๋ ‰ํ† ๋ฆฌ์˜ MacBook ํ„ฐ๋ฏธ๋„์—์„œ ๋‹ค์Œ ๋ช…๋ น์„ ์‹คํ–‰ํ•˜์‹ญ์‹œ์˜ค.

mpirun -np 2 -H localhost:2 -bind-to none -map-by slot python mxnet_mnist.py

๊ทธ๋Ÿฌ๋ฉด ํ”„๋กœ์„ธ์„œ์˜ ๋‘ ์ฝ”์–ด์— ๋Œ€ํ•œ ๊ต์œก์ด ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. ์ถœ๋ ฅ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

INFO:root:Epoch[0] Batch [0-50] Speed: 2248.71 samples/sec      accuracy=0.583640
INFO:root:Epoch[0] Batch [50-100] Speed: 2273.89 samples/sec      accuracy=0.882812
INFO:root:Epoch[0] Batch [50-100] Speed: 2273.39 samples/sec      accuracy=0.870000

์„ฑ๋Šฅ ๋ฐ๋ชจ

50๊ฐœ์˜ ์ธ์Šคํ„ด์Šค๊ฐ€ ์žˆ๋Š” 1๊ฐœ GPU์˜ ImageNet ๋ฐ์ดํ„ฐ์„ธํŠธ์—์„œ ResNet64-vXNUMX ๋ชจ๋ธ์„ ํ›ˆ๋ จํ•˜๋Š” ๊ฒฝ์šฐ p3.16xlarge ๊ฐ๊ฐ AWS ํด๋ผ์šฐ๋“œ์— 2๊ฐœ์˜ NVIDIA Tesla V8 GPU๊ฐ€ ํฌํ•จ๋œ EC100์—์„œ ์ดˆ๋‹น 45000๊ฐœ ์ด๋ฏธ์ง€(์ฆ‰, ์ดˆ๋‹น ํ›ˆ๋ จ๋œ ์ƒ˜ํ”Œ ์ˆ˜)์˜ ํ›ˆ๋ จ ์ฒ˜๋ฆฌ๋Ÿ‰์„ ๋‹ฌ์„ฑํ–ˆ์Šต๋‹ˆ๋‹ค. 44๋ฒˆ์˜ ์—ํฌํฌ ์ดํ›„ 90๋ถ„ ๋งŒ์— ํ›ˆ๋ จ์ด ์™„๋ฃŒ๋˜์—ˆ์œผ๋ฉฐ ์ตœ๊ณ  ์ •ํ™•๋„๋Š” 75.7%์ž…๋‹ˆ๋‹ค.

์šฐ๋ฆฌ๋Š” ์ด๋ฅผ ๋‹จ์ผ ๋งค๊ฐœ๋ณ€์ˆ˜ ์„œ๋ฒ„์™€ ์„œ๋ฒ„ ๋Œ€ ์ž‘์—…์ž ๋น„์œจ์ด ๊ฐ๊ฐ 8:16 ๋ฐ 32:64์ธ 1, 1, 2 ๋ฐ 1 GPU์—์„œ ๋งค๊ฐœ๋ณ€์ˆ˜ ์„œ๋ฒ„๋ฅผ ์‚ฌ์šฉํ•˜๋Š” MXNet์˜ ๋ถ„์‚ฐ ๊ต์œก ์ ‘๊ทผ ๋ฐฉ์‹๊ณผ ๋น„๊ตํ–ˆ์Šต๋‹ˆ๋‹ค. ์•„๋ž˜ ๊ทธ๋ฆผ 1์—์„œ ๊ฒฐ๊ณผ๋ฅผ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์™ผ์ชฝ์˜ y์ถ•์—์„œ ๋ง‰๋Œ€๋Š” ์ดˆ๋‹น ํ›ˆ๋ จํ•  ์ด๋ฏธ์ง€ ์ˆ˜๋ฅผ ๋‚˜ํƒ€๋‚ด๊ณ , ์„ ์€ ์˜ค๋ฅธ์ชฝ์˜ y์ถ•์—์„œ ์Šค์ผ€์ผ๋ง ํšจ์œจ์„ฑ(์ฆ‰, ์‹ค์ œ ์ฒ˜๋ฆฌ๋Ÿ‰๊ณผ ์ด์ƒ์ ์ธ ์ฒ˜๋ฆฌ๋Ÿ‰์˜ ๋น„์œจ)์„ ๋ฐ˜์˜ํ•ฉ๋‹ˆ๋‹ค. ๋ณด์‹œ๋‹ค์‹œํ”ผ ์„œ๋ฒ„ ์ˆ˜ ์„ ํƒ์€ ํ™•์žฅ ํšจ์œจ์„ฑ์— ์˜ํ–ฅ์„ ๋ฏธ์นฉ๋‹ˆ๋‹ค. ๋งค๊ฐœ๋ณ€์ˆ˜ ์„œ๋ฒ„๊ฐ€ ํ•˜๋‚˜๋งŒ ์žˆ๋Š” ๊ฒฝ์šฐ GPU 38๊ฐœ์—์„œ๋Š” ํ™•์žฅ ํšจ์œจ์„ฑ์ด 64%๋กœ ๋–จ์–ด์ง‘๋‹ˆ๋‹ค. Horovod์™€ ๋™์ผํ•œ ํ™•์žฅ ํšจ์œจ์„ฑ์„ ๋‹ฌ์„ฑํ•˜๋ ค๋ฉด ์ž‘์—…์ž ์ˆ˜์— ๋น„ํ•ด ์„œ๋ฒ„ ์ˆ˜๋ฅผ ๋‘ ๋ฐฐ๋กœ ๋Š˜๋ ค์•ผ ํ•ฉ๋‹ˆ๋‹ค.

Apache MXNet ๋ฐ Horovod๋ฅผ ์‚ฌ์šฉํ•œ ๋ถ„์‚ฐ ํ•™์Šต
๊ทธ๋ฆผ 1. Horovod ๋ฐ ๋งค๊ฐœ๋ณ€์ˆ˜ ์„œ๋ฒ„์™€ ํ•จ๊ป˜ MXNet์„ ์‚ฌ์šฉํ•œ ๋ถ„์‚ฐ ํ•™์Šต ๋น„๊ต

์•„๋ž˜ ํ‘œ 1์—์„œ๋Š” 64๊ฐœ์˜ GPU์—์„œ ์‹คํ—˜์„ ์‹คํ–‰ํ•  ๋•Œ ์ธ์Šคํ„ด์Šค๋‹น ์ตœ์ข… ๋น„์šฉ์„ ๋น„๊ตํ•ฉ๋‹ˆ๋‹ค. Horovod์™€ ํ•จ๊ป˜ MXNet์„ ์‚ฌ์šฉํ•˜๋ฉด ์ตœ์ € ๋น„์šฉ์œผ๋กœ ์ตœ๊ณ ์˜ ์ฒ˜๋ฆฌ๋Ÿ‰์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

Apache MXNet ๋ฐ Horovod๋ฅผ ์‚ฌ์šฉํ•œ ๋ถ„์‚ฐ ํ•™์Šต
ํ‘œ 1. ์„œ๋ฒ„ ๋Œ€ ์ž‘์—…์ž ๋น„์œจ์ด 2:1์ธ Horovod์™€ Parameter Server ๊ฐ„์˜ ๋น„์šฉ ๋น„๊ต.

์žฌํ˜„ ๋‹จ๊ณ„

๋‹ค์Œ ๋‹จ๊ณ„์—์„œ๋Š” MXNet ๋ฐ Horovod๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ถ„์‚ฐ ๊ต์œก ๊ฒฐ๊ณผ๋ฅผ ์žฌํ˜„ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋ณด์—ฌ ๋“œ๋ฆฌ๊ฒ ์Šต๋‹ˆ๋‹ค. MXNet์„ ํ†ตํ•œ ๋ถ„์‚ฐ ํ•™์Šต์— ๋Œ€ํ•ด ์ž์„ธํžˆ ์•Œ์•„๋ณด๋ ค๋ฉด ์ฝ์–ด๋ณด์„ธ์š”. ์ด ๊ฒŒ์‹œ๋ฌผ.

1 ๋‹จ๊ณ„

๋ถ„์‚ฐ ํ•™์Šต์„ ์‚ฌ์šฉํ•˜๋ ค๋ฉด MXNet ๋ฒ„์ „ 1.4.0 ์ด์ƒ ๋ฐ Horovod ๋ฒ„์ „ 0.16.0 ์ด์ƒ์œผ๋กœ ๋™์ข… ์ธ์Šคํ„ด์Šค ํด๋Ÿฌ์Šคํ„ฐ๋ฅผ ์ƒ์„ฑํ•˜์„ธ์š”. GPU ํ›ˆ๋ จ์„ ์œ„ํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋„ ์„ค์น˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์šฐ๋ฆฌ์˜ ๊ฒฝ์šฐ GPU ๋“œ๋ผ์ด๋ฒ„ 16.04, CUDA 396.44, cuDNN 9.2 ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ, NCCL 7.2.1 ์ปค๋ฎค๋‹ˆ์ผ€์ดํ„ฐ ๋ฐ OpenMPI 2.2.13์ด ํฌํ•จ๋œ Ubuntu 3.1.1 Linux๋ฅผ ์„ ํƒํ–ˆ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ ๋‹น์‹ ์€ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค ์•„๋งˆ์กด ๋”ฅ ๋Ÿฌ๋‹ AMI, ์ด๋Ÿฌํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋Š” ์ด๋ฏธ ์‚ฌ์ „ ์„ค์น˜๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

2 ๋‹จ๊ณ„

MXNet ๊ต์œก ์Šคํฌ๋ฆฝํŠธ์— Horovod API๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•˜์„ธ์š”. MXNet Gluon API๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•˜๋Š” ์•„๋ž˜ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ๊ฐ„๋‹จํ•œ ํ…œํ”Œ๋ฆฟ์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•ด๋‹น ํ›ˆ๋ จ ์Šคํฌ๋ฆฝํŠธ๊ฐ€ ์ด๋ฏธ ์žˆ๋Š” ๊ฒฝ์šฐ ๊ตต์€ ๊ธ€์”จ์˜ ์ค„์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. Horovod๋ฅผ ๋ฐฐ์šฐ๊ธฐ ์œ„ํ•ด ์ˆ˜ํ–‰ํ•ด์•ผ ํ•  ๋ช‡ ๊ฐ€์ง€ ์ค‘์š”ํ•œ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • ํ›ˆ๋ จ์ด ์˜ฌ๋ฐ”๋ฅธ ๊ทธ๋ž˜ํ”ฝ ์ฝ”์–ด์—์„œ ์ˆ˜ํ–‰๋œ๋‹ค๋Š” ๊ฒƒ์„ ์ดํ•ดํ•˜๋ ค๋ฉด ๋กœ์ปฌ Horovod ์ˆœ์œ„(8ํ–‰)์— ๋”ฐ๋ผ ์ปจํ…์ŠคํŠธ๋ฅผ ์„ค์ •ํ•˜์‹ญ์‹œ์˜ค.
  • ๋ชจ๋“  ์ž‘์—…์ž๊ฐ€ ๋™์ผํ•œ ์ดˆ๊ธฐ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ์‹œ์ž‘ํ•˜๋„๋ก ํ•˜๋ ค๋ฉด ํ•œ ์ž‘์—…์ž์˜ ์ดˆ๊ธฐ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ๋ชจ๋“  ์ž‘์—…์ž์—๊ฒŒ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค(18ํ–‰).
  • ํ˜ธ๋กœ๋ณด๋“œ ๋งŒ๋“ค๊ธฐ ๋ถ„์‚ฐ ์ตœ์ ํ™” ํ”„๋กœ๊ทธ๋žจ (๋ผ์ธ 25) ๋ถ„์‚ฐ ๋ฐฉ์‹์œผ๋กœ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์—…๋ฐ์ดํŠธํ•ฉ๋‹ˆ๋‹ค.

์ „์ฒด ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์–ป์œผ๋ ค๋ฉด Horovod-MXNet ์˜ˆ์ œ๋ฅผ ์ฐธ์กฐํ•˜์„ธ์š”. MNIST ะธ IMAGEnet.

1  import mxnet as mx
2  import horovod.mxnet as hvd
3
4  # Horovod: initialize Horovod
5  hvd.init()
6
7  # Horovod: pin a GPU to be used to local rank
8  context = mx.gpu(hvd.local_rank())
9
10 # Build model
11 model = ...
12
13 # Initialize parameters
14 model.initialize(initializer, ctx=context)
15 params = model.collect_params()
16
17 # Horovod: broadcast parameters
18 hvd.broadcast_parameters(params, root_rank=0)
19
20 # Create optimizer
21 optimizer_params = ...
22 opt = mx.optimizer.create('sgd', **optimizer_params)
23
24 # Horovod: wrap optimizer with DistributedOptimizer
25 opt = hvd.DistributedOptimizer(opt)
26
27 # Create trainer and loss function
28 trainer = mx.gluon.Trainer(params, opt, kvstore=None)
29 loss_fn = ...
30
31 # Train model
32 for epoch in range(num_epoch):
33    ...

3 ๋‹จ๊ณ„

MPI ์ง€์นจ์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ถ„์‚ฐ ๊ต์œก์„ ์‹œ์ž‘ํ•˜๋ ค๋ฉด ์ž‘์—…์ž ์ค‘ ํ•œ ๋ช…์— ๋กœ๊ทธ์ธํ•˜์„ธ์š”. ์ด ์˜ˆ์—์„œ ๋ถ„์‚ฐ ๊ต์œก์€ ๊ฐ๊ฐ 4๊ฐœ์˜ GPU๊ฐ€ ์žˆ๋Š” 16๊ฐœ์˜ ์ธ์Šคํ„ด์Šค์—์„œ ์‹คํ–‰๋˜๋ฉฐ ํด๋Ÿฌ์Šคํ„ฐ์—๋Š” ์ด XNUMX๊ฐœ์˜ GPU๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. SGD(Stochastic Gradient Descent) ์ตœ์ ํ™” ํ”„๋กœ๊ทธ๋žจ์€ ๋‹ค์Œ ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ์™€ ํ•จ๊ป˜ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.

  • ๋ฏธ๋‹ˆ ๋ฐฐ์น˜ ํฌ๊ธฐ: 256
  • ํ•™์Šต๋ฅ : 0.1
  • ์šด๋™๋Ÿ‰: 0.9
  • ์ค‘๋Ÿ‰ ๊ฐ์†Œ: 0.0001

64๊ฐœ์˜ GPU์—์„œ 0,1๊ฐœ์˜ GPU๋กœ ํ™•์žฅํ•˜๋ฉด์„œ GPU ์ˆ˜์— ๋”ฐ๋ผ ํ›ˆ๋ จ ์†๋„๋ฅผ ์„ ํ˜•์ ์œผ๋กœ ํ™•์žฅํ–ˆ์œผ๋ฉฐ(1 GPU์˜ ๊ฒฝ์šฐ 6,4์—์„œ 64 GPU์˜ ๊ฒฝ์šฐ 256), GPU๋‹น ์ด๋ฏธ์ง€ ์ˆ˜๋Š” 256๊ฐœ(๋ฐฐ์น˜์—์„œ)๋กœ ์œ ์ง€ํ–ˆ์Šต๋‹ˆ๋‹ค. 1๊ฐœ GPU์˜ ๊ฒฝ์šฐ 16๊ฐœ ์ด๋ฏธ์ง€๋ถ€ํ„ฐ 384๊ฐœ GPU์˜ ๊ฒฝ์šฐ 64๊ฐœ ์ด๋ฏธ์ง€๊นŒ์ง€). GPU ์ˆ˜๊ฐ€ ์ฆ๊ฐ€ํ•จ์— ๋”ฐ๋ผ ๋ฌด๊ฒŒ ๊ฐ์†Œ ๋ฐ ์šด๋™๋Ÿ‰ ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ๋ณ€๊ฒฝ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. NVIDIA Tesla GPU์—์„œ ์ง€์›ํ•˜๋Š” float16 ๊ณ„์‚ฐ ์†๋„๋ฅผ ๋†’์ด๊ธฐ ์œ„ํ•ด ์ˆœ๋ฐฉํ–ฅ ์ „๋‹ฌ์—๋Š” float32 ๋ฐ์ดํ„ฐ ์œ ํ˜•์„, ๊ฒฝ์‚ฌ์—๋Š” float16 ๋ฐ์ดํ„ฐ ์œ ํ˜•์„ ์‚ฌ์šฉํ•˜๋Š” ํ˜ผํ•ฉ ์ •๋ฐ€๋„ ๊ต์œก์„ ์‚ฌ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค.

$ mpirun -np 16 
    -H server1:4,server2:4,server3:4,server4:4 
    -bind-to none -map-by slot 
    -mca pml ob1 -mca btl ^openib 
    python mxnet_imagenet_resnet50.py

๊ฒฐ๋ก 

์ด ๊ธฐ์‚ฌ์—์„œ๋Š” Apache MXNet ๋ฐ Horovod๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ถ„์‚ฐ ๋ชจ๋ธ ๊ต์œก์— ๋Œ€ํ•œ ํ™•์žฅ ๊ฐ€๋Šฅํ•œ ์ ‘๊ทผ ๋ฐฉ์‹์„ ์‚ดํŽด๋ณด์•˜์Šต๋‹ˆ๋‹ค. ResNet50-v1 ๋ชจ๋ธ์ด ํ›ˆ๋ จ๋œ ImageNet ๋ฐ์ดํ„ฐ์„ธํŠธ์— ๋Œ€ํ•œ ๋งค๊ฐœ๋ณ€์ˆ˜ ์„œ๋ฒ„ ์ ‘๊ทผ ๋ฐฉ์‹๊ณผ ๋น„๊ตํ•˜์—ฌ ํ™•์žฅ ํšจ์œจ์„ฑ๊ณผ ๋น„์šฉ ํšจ์œจ์„ฑ์„ ์ž…์ฆํ–ˆ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ Horovod๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋‹ค์ค‘ ์ธ์Šคํ„ด์Šค ๊ต์œก์„ ์‹คํ–‰ํ•˜๊ธฐ ์œ„ํ•ด ๊ธฐ์กด ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์ˆ˜์ •ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๋‹จ๊ณ„๋„ ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

MXNet๊ณผ ๋”ฅ๋Ÿฌ๋‹์„ ์ด์ œ ๋ง‰ ์‹œ์ž‘ํ•˜์…จ๋‹ค๋ฉด ์„ค์น˜ ํŽ˜์ด์ง€๋กœ ์ด๋™ํ•˜์„ธ์š” MXNe๋จผ์ € MXNet์„ ๊ตฌ์ถ•ํ•˜์„ธ์š”. ์šฐ๋ฆฌ๋Š” ๋˜ํ•œ ๊ธฐ์‚ฌ๋ฅผ ์ฝ๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค 60๋ถ„ ๋งŒ์— MXNet์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค.

์ด๋ฏธ MXNet์„ ์‚ฌ์šฉํ•ด๋ณธ ์ ์ด ์žˆ๊ณ  Horovod๋กœ ๋ถ„์‚ฐ ํ•™์Šต์„ ์‹œ๋„ํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด ๋‹ค์Œ์„ ์‚ดํŽด๋ณด์„ธ์š”. Horovod ์„ค์น˜ ํŽ˜์ด์ง€, MXNet์—์„œ ๋นŒ๋“œํ•˜๊ณ  ์˜ˆ์ œ๋ฅผ ๋”ฐ๋ฅด์„ธ์š”. MNIST ๋˜๋Š” IMAGEnet.

*๋น„์šฉ์€ ๋‹ค์Œ์„ ๊ธฐ์ค€์œผ๋กœ ๊ณ„์‚ฐ๋ฉ๋‹ˆ๋‹ค. ์‹œ๊ฐ„๋‹น ์š”๊ธˆ EC2 ์ธ์Šคํ„ด์Šค์šฉ AWS

๊ณผ์ •์— ๋Œ€ํ•ด ์ž์„ธํžˆ ์•Œ์•„๋ณด๊ธฐ "๋น…๋ฐ์ดํ„ฐ๋ฅผ ํ™œ์šฉํ•œ ์‚ฐ์—…์šฉ ML"

์ถœ์ฒ˜ : habr.com

์ฝ”๋ฉ˜ํŠธ๋ฅผ ์ถ”๊ฐ€