[Optional] NVSHMEM (NVIDIA Shared Memory)
NCCL์ ์ฌ์ ํ ๋ฅ๋ฌ๋ ํ๋ ์์ํฌ์ ๊ธฐ๋ณธ ํต์ ๋ฐฑ์๋๋ก ์ฐ์ด์ง๋ง, NCCL์ด ์ต์ ํํ์ง ๋ชปํ๋ ์์ญ(All-to-All, MoE ํต์ )์ NVSHMEM ๊ธฐ๋ฐ ์ปค๋๋ก ๋ณด์ํ๋ DeepEP์ ๊ฐ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ค์ด ๋ฑ์ฅํ๊ณ ์์ต๋๋ค. ๋ฐ๋ผ์, ๋ณธ ๋ฌธ์๋ NVSHMEM์ ๋ํ ์ปจ์ ์ ์ดํดํ๋ ์ฉ๋๋ก ์ฐธ์กฐํ๊ธฐ ๋ฐ๋๋๋ค.
1. NVSHMEM ๊ฐ์
1.1. NVSHMEM์ด๋?
NVSHMEM(NVIDIA Shared Memory)์ GPU ํด๋ฌ์คํฐ์์ ์ฌ๋ฌ ํ๋ก์ธ์ค๊ฐ GPU ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ง์ ๊ณต์ ํ๊ณ ํต์ ํ ์ ์๊ฒ ํด์ฃผ๋ ํต์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๋๋ค. ๊ธฐ์กด OpenSHMEM์ ๊ฐ๋ ์ GPU ํ๊ฒฝ์ผ๋ก ํ์ฅํ ๊ฒ์ผ๋ก, CUDA ์ปค๋ ๋ด๋ถ์์ ์ง์ ์๊ฒฉ GPU์ ๋ฉ๋ชจ๋ฆฌ์ ์ ๊ทผํ ์ ์๋ ํ์ ์ ์ธ ๊ธฐ๋ฅ์ ์ ๊ณตํฉ๋๋ค.
๊ฐ์ฅ ์ค์ํ ํน์ง์ CPU์ ๊ฐ์ ์์ด GPU๊ฐ ์ค์ค๋ก ๋ค๋ฅธ GPU์ ํต์ ํ ์ ์๋ค๋ ์ ์ ๋๋ค. ์ ํต์ ์ธ ๋ฐฉ์์์๋ GPU๊ฐ ๋ฐ์ดํฐ๋ฅผ ๋ณด๋ด๋ ค๋ฉด ๋จผ์ CPU์๊ฒ ์๋ฆฌ๊ณ , CPU๊ฐ ๋คํธ์ํฌ ์์ ์ ์์ํด์ผ ํ์ต๋๋ค. NVSHMEM์ ์ด๋ฌํ ๋ณ๋ชฉ์ ์ ๊ฑฐํ์ฌ GPU ๊ฐ ํต์ ์ ์ง์ฐ ์๊ฐ์ ํ๊ธฐ์ ์ผ๋ก ์ค์ ๋๋ค.
SPMD(Single Program Multiple Data) ์คํ ๋ชจ๋ธ
NVSHMEM ์์
์ ์ฌ๋ฌ ์ด์์ฒด์ ํ๋ก์ธ์ค๋ก ๊ตฌ์ฑ๋๋ฉฐ, ๊ฐ ํ๋ก์ธ์ค๋ฅผ Processing Element(PE)๋ผ๊ณ ๋ถ๋ฆ
๋๋ค. ๋ชจ๋ PE๋ ๋์ผํ ์คํ ํ์ผ์ ๋ณต์ฌ๋ณธ์ ์คํํ๋ SPMD(Single Program, Multiple Data) ํจ๋ฌ๋ค์์ ๋ฐ๋ฆ
๋๋ค. SPMD๋ ๋ง์น ๊ฐ์ ๋ ์ํผ๋ฅผ ๊ฐ์ง ์ฌ๋ฌ ์๋ฆฌ์ฌ๊ฐ ๊ฐ์ ๋ค๋ฅธ ์ฌ๋ฃ๋ก ์๋ฆฌํ๋ ๊ฒ๊ณผ ๊ฐ์ต๋๋ค. ๋ชจ๋ PE๊ฐ ๋์ผํ ์ฝ๋(๋ ์ํผ)๋ฅผ ์คํํ์ง๋ง, ๊ฐ PE๋ ์์ ์ ๊ณ ์ ID๋ฅผ ํตํด ์๋ก ๋ค๋ฅธ ๋ฐ์ดํฐ(์ฌ๋ฃ)๋ฅผ ์ฒ๋ฆฌํ๊ณ , ํ์์ ๋ฐ๋ผ ์กฐ๊ฑด๋ฌธ์ผ๋ก ๋ค๋ฅธ ์์
์ ์ํํ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด "if (my_id == 0)
"์ผ๋ก 0๋ฒ PE๋ง ํน์ ์์
์ ํ๊ฒ ํ๊ฑฐ๋, "process_chunk(data[my_id])
"๋ก ๊ฐ PE๊ฐ ์์ ์๊ฒ ํ ๋น๋ ๋ฐ์ดํฐ ๋ถ๋ถ์ ์ฒ๋ฆฌํ๊ฒ ๋ง๋ค ์ ์์ต๋๋ค.
๊ฐ PE์๋ 0๋ถํฐ ์์ํ๋ ๊ณ ์ ํ ์ ์ ์๋ณ์(PE ID)๊ฐ ํ ๋น๋ฉ๋๋ค. ์ด ID๋ ํต์ ์์ ์์ ์์ค๋ ๋ชฉ์ ์ง๋ฅผ ์ง์ ํ๋ ๋ฐ ์ฌ์ฉ๋๋ฉฐ, ๊ฐ๋ฐ์๊ฐ ํน์ PE์ ์์ ์ ํ ๋นํ ๋๋ ํ์ฉ๋ฉ๋๋ค. ์๋ฅผ ๋ค์ด 8๊ฐ์ GPU๋ก ์์ ์ ์คํํ๋ค๋ฉด, PE ID๋ 0๋ถํฐ 7๊น์ง ํ ๋น๋ฉ๋๋ค.
ํ๋ก๊ทธ๋จ ์์ ์ ๋ชจ๋ PE๋ ๋ฐ๋์ ๋์์, ์ฆ ์งํฉ์ ์ผ๋ก(collectively) NVSHMEM ์ด๊ธฐํ ๋ฃจํด์ ํธ์ถํด์ผ ํฉ๋๋ค. ๋ง์ฐฌ๊ฐ์ง๋ก ํ๋ก๊ทธ๋จ ์ข ๋ฃ ์ ์๋ ๋ชจ๋ PE๊ฐ ํจ๊ป ์ข ๋ฃ ํจ์๋ฅผ ํธ์ถํด์ผ ํฉ๋๋ค. ์ด๊ธฐํ๊ฐ ์๋ฃ๋๋ฉด PE๋ ์์ ์ ID์ ์ ์ฒด PE ๊ฐ์๋ฅผ ์กฐํํ ์ ์์ต๋๋ค.

Symmetric Memory
NVSHMEM์ ํต์ฌ์ ๋์นญ ๋ฉ๋ชจ๋ฆฌsymmetric memory ๊ฐ๋ ์ ๋๋ค. ์ด๋ ๋ชจ๋ PE์ ๋์ผํ ํฌ๊ธฐ์ ๋ ์ด์์์ผ๋ก ํ ๋น๋๋ GPU ๋ฉ๋ชจ๋ฆฌ ์์ญ์ ์๋ฏธํฉ๋๋ค. ๊ฐ PE๋ ์์ ์ GPU ๋ฉ๋ชจ๋ฆฌ์ symmetric heap์ด๋ผ๋ ํน๋ณํ ์์ญ์ ๊ฐ์ง๊ณ ์์ผ๋ฉฐ, NVSHMEM API๋ฅผ ํตํด ์ด ํ์์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ํ ๋น๋ฐ์ต๋๋ค.
๋์นญ ๋ฉ๋ชจ๋ฆฌ ํ ๋น์ ์งํฉ ์ฐ์ฐcollective operation์ ๋๋ค. ๋ชจ๋ PE๋ ๋์ผํ ํฌ๊ธฐ ์ธ์๋ฅผ ์ ๋ฌํ์ฌ ํ ๋น ํจ์๋ฅผ ํธ์ถํด์ผ ํ๋ฉฐ, ๊ทธ ๊ฒฐ๊ณผ ๊ฐ PE์ ๋์นญ ํsymmetric heap์์ ์ง์ ๋ ํฌ๊ธฐ์ ๋ฉ๋ชจ๋ฆฌ๊ฐ ํ ๋น๋ฉ๋๋ค. ์ด๋ ๊ฒ ํ ๋น๋ ๋ฉ๋ชจ๋ฆฌ๋ ๋์นญ์ ์ด๋ผ๋ ํน๋ณํ ์์ฑ์ ๊ฐ์ง๋๋ค. PE ID์ ๋์นญ ์ฃผ์์ ์กฐํฉ์ ์ฌ์ฉํ๋ฉด ๋ค๋ฅธ PE์์๋ ์ด ๋ฉ๋ชจ๋ฆฌ์ ์ ๊ทผํ ์ ์์ต๋๋ค.
์ค์ํ ์ ์ NVSHMEM API๋ฅผ ํตํ์ง ์๊ณ ํ ๋น๋ ๋ฉ๋ชจ๋ฆฌ๋ ํด๋น PE์ private memory๋ก ๊ฐ์ฃผ๋์ด ๋ค๋ฅธ PE๊ฐ ์ ๊ทผํ ์ ์๋ค๋ ๊ฒ์
๋๋ค. ์ค์ง nvshmem_malloc
๊ฐ์ NVSHMEM ํ ๋น ํจ์๋ฅผ ํตํด ์ป์ ๋ฉ๋ชจ๋ฆฌ๋ง์ด ๋ค๋ฅธ PE์ ๊ณต์ ๊ฐ๋ฅํ ๋์นญ ๋ฉ๋ชจ๋ฆฌsymmetric memory๊ฐ ๋ฉ๋๋ค.
PGAS(Partitioned Global Address Space) ๋ชจ๋ธ: ์ ์ญ ์ฃผ์ ๊ณต๊ฐ์ ํํฐ์
๋ชจ๋ PE์ ๋์นญ ๋ฉ๋ชจ๋ฆฌ ์ธ๊ทธ๋จผํธ๋ฅผ ํฉ์น ๊ฒ์ Partitioned Global Address Space(PGAS, ํํฐ์ ๋ ์ ์ญ ์ฃผ์ ๊ณต๊ฐ)๋ผ๊ณ ๋ถ๋ฆ ๋๋ค. ์ด๋ ๋ถ์ฐ ๋ฉ๋ชจ๋ฆฌ ์์คํ ์ ๋ง์น ํ๋์ ๊ฑฐ๋ํ ์ ์ญ ๋ฉ๋ชจ๋ฆฌ์ฒ๋ผ ๋ค๋ฃฐ ์ ์๊ฒ ํด์ฃผ๋ ์ถ์ํ์ ๋๋ค.
PGAS ๋ชจ๋ธ์์ ๋ฐ์ดํฐ์ ์์น๋ ์ฃผ์ ์ง์ ๋ชจ๋ธ์ ๋ณธ์ง์ ์ธ ๋ถ๋ถ์
๋๋ค. NVSHMEM ์ฐ์ฐ์ <symmetric_address, destination_PE>
ํํ๋ก symmetric ๊ฐ์ฒด์ ์ ๊ทผํฉ๋๋ค. symmetric address๋ NVSHMEM ํ ๋น ํจ์๊ฐ ๋ฐํํ ์ฃผ์์ ํฌ์ธํฐ ์ฐ์ฐ์ ์ํํ์ฌ ์์ฑํ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด &X[10]
์ด๋ &ptr->x
๊ฐ์ ํํ์์ ์ฌ์ฉํ ์ ์์ต๋๋ค.
์ฃผ์ํ ์ ์ symmetric address๋ ํ ๋น์ ๋ฐ์ PE์์๋ง ์ ํจํ๋ค๋ ๊ฒ์ ๋๋ค. ๋ค๋ฅธ PE์ ์ด ์ฃผ์ ๊ฐ์ ๊ณต์ ํ ์ ์์ต๋๋ค. NVSHMEM ๋ฐํ์์ ๋ด๋ถ์ ์ผ๋ก symmetric address๋ฅผ ์ค์ ์๊ฒฉ ์ฃผ์๋ก ๋ณํํ๋ฉฐ, ๊ณ ๊ธ CUDA ๋ฉ๋ชจ๋ฆฌ ๋งคํ ๊ธฐ๋ฒ์ ์ฌ์ฉํ์ฌ ์ด ๋ณํ ์ค๋ฒํค๋๋ฅผ ์ต์ํํฉ๋๋ค.
ํต์ ๋ชจ๋ธ: Put, Get, ๊ทธ๋ฆฌ๊ณ AMO
NVSHMEM์ symmetric ๊ฐ์ฒด๋ก ๋ฐ์ดํฐ๋ฅผ ๋ณต์ฌํ๋ put API์ symmetric ๊ฐ์ฒด๋ก๋ถํฐ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๋ get API๋ฅผ ์ ๊ณตํฉ๋๋ค. ๋๋ ์ ์ก, ์ค์นผ๋ผ ์ ์ก, ๊ทธ๋ฆฌ๊ณ ์ธํฐ๋ฆฌ๋ธ ๋ฒ์ ์ API๋ค์ด ๋ชจ๋ ์ ๊ณต๋ฉ๋๋ค. ๋ํ Atomic Memory Operations(AMO)๋ ์ ๊ณต๋์ด symmetric ๋ณ์์ ๋ํ ์์์ ์ ๋ฐ์ดํธ๋ฅผ ์ํํ ์ ์์ต๋๋ค.
์ด๋ฌํ API๋ค์ ํตํด NVSHMEM์ CUDA ์ปค๋๋ก๋ถํฐ PGAS์ ์ ์ฅ๋ ๋ฐ์ดํฐ์ ๋ํ ์ธ๋ฐํ๊ณ ๋ฎ์ ์ค๋ฒํค๋์ ์ ๊ทผ์ ์ ๊ณตํฉ๋๋ค. ์ปค๋ ๋ด๋ถ์์ ํต์ ์ ์ํํจ์ผ๋ก์จ, NVSHMEM์ GPU ์ํ ์ค์ผ์ค๋ง ํ๋์จ์ด์ ๋ณธ์ง์ ์ธ ์ง์ฐ ์๋ ๊ธฐ๋ฅ์ ์ด์ ์ ํ์ฉํ ์ ์์ต๋๋ค.
put, get, AMO ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๋ฃจํด ์ธ์๋, ์ ํ๋ฆฌ์ผ์ด์
์ nvshmem_ptr
๋ฃจํด์ ์ฌ์ฉํ์ฌ ๋ค๋ฅธ PE์ PGAS ํํฐ์
์ ์์นํ ๋ฐ์ดํฐ์ ๋ํ ์ง์ ํฌ์ธํฐ๋ฅผ ์กฐํํ ์ ์์ต๋๋ค. ์ง์ ๋ PE์ ๋ฉ๋ชจ๋ฆฌ๊ฐ ์ง์ ์ ๊ทผ ๊ฐ๋ฅํ ๊ฒฝ์ฐ, ์ด ํจ์๋ ์ ํจํ ํฌ์ธํฐ๋ฅผ ๋ฐํํฉ๋๋ค. ๊ทธ๋ ์ง ์์ผ๋ฉด null ํฌ์ธํฐ๋ฅผ ๋ฐํํฉ๋๋ค. ์ด๋ฅผ ํตํด ์ ํ๋ฆฌ์ผ์ด์
์ ์ ์ญ ๋ฉ๋ชจ๋ฆฌ์ ์ง์ ๋ก๋์ ์คํ ์ด๋ฅผ ๋ฐํํ ์ ์์ต๋๋ค.
NVSHMEM API์ ํ๋์จ์ด๊ฐ ํ์ฉํ๋ ๊ฒฝ์ฐ์ ๋ก๋/์คํ ์ด๋ ๋ก์ปฌ ๋ฐ ์๊ฒฉ ๋ฐ์ดํฐ์ ์ ๊ทผํ๋ ๋ฐ ์ฌ์ฉ๋ ์ ์์ด, ํ๋์ ์ฝ๋ ๊ฒฝ๋ก๋ก ๋ก์ปฌ๊ณผ ์๊ฒฉ ๋ฐ์ดํฐ๋ฅผ ๋ชจ๋ ์ฒ๋ฆฌํ ์ ์์ต๋๋ค. ๋ํ Hopper ์ํคํ
์ฒ์ ๋ฉํฐ์บ์คํธ ๊ธฐ๋ฅ์ ์ง์ํ๋ ํ๋ซํผ์์๋ nvshmemx_mc_ptr
๋ฃจํด์ ์ฌ์ฉํ์ฌ ํ์ PGAS ํํฐ์
์ ์๋ ๋ฐ์ดํฐ์ ๋ํ ์ง์ ๋ฉํฐ์บ์คํธ ํฌ์ธํฐ๋ฅผ ์กฐํํ ์ ์์ต๋๋ค.
OpenSHMEM๊ณผ์ ์ฐจ์ด์
NVSHMEM์ OpenSHMEM์ GPU ํ์ฅ์ด์ง๋ง ๋ช ๊ฐ์ง ์ค์ํ ์ฐจ์ด๊ฐ ์์ต๋๋ค. ์ฒซ์งธ, NVSHMEM ํ ๋น API๋ฅผ ์ฌ์ฉํ์ฌ ํ ๋น๋ ๋ชจ๋ symmetric ๋ฉ๋ชจ๋ฆฌ๋ ํ๋(pinned) GPU ๋๋ฐ์ด์ค ๋ฉ๋ชจ๋ฆฌ์ ๋๋ค. ๋์งธ, NVSHMEM์ GPU ์ธก๊ณผ CPU ์ธก ํต์ ๋ฐ ๋๊ธฐํ API๋ฅผ ๋ชจ๋ ์ง์ํ๋ฉฐ, ๊ด๋ จ ๋ฉ๋ชจ๋ฆฌ๊ฐ NVSHMEM์ ์ํด ํ ๋น๋ GPU ๋๋ฐ์ด์ค ๋ฉ๋ชจ๋ฆฌ์ด๊ธฐ๋ง ํ๋ฉด ๋ฉ๋๋ค. ๋ค๋ฅธ OpenSHMEM ๊ตฌํ์์๋ ์ด๋ฌํ API๋ฅผ CPU์์๋ง ํธ์ถํ ์ ์์ต๋๋ค.
NVSHMEM์ ์ํ๋ฅผ ๊ฐ์งstateful ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๋๋ค. PE๊ฐ NVSHMEM ์ด๊ธฐํ ๋ฃจํด์ ํธ์ถํ๋ฉด, ์ด๋ค GPU๋ฅผ ์ฌ์ฉํ๊ณ ์๋์ง ๊ฐ์งํ๊ณ ์ด ์ ๋ณด๋ฅผ ๋ฐํ์์ ์ ์ฅํฉ๋๋ค. PE๊ฐ ์ํํ๋ ๋ชจ๋ symmetric ํ ๋น ํธ์ถ์ ์ ํ๋ GPU์ ๋๋ฐ์ด์ค ๋ฉ๋ชจ๋ฆฌ๋ฅผ ๋ฐํํฉ๋๋ค. PE๊ฐ ์ํํ๋ ๋ชจ๋ NVSHMEM ํธ์ถ์ ์ ํ๋ GPU์ ๋ํด ๋๋ ์ด GPU์์ ์คํ๋ ์ปค๋ ๋ด๋ถ์์ ์ด๋ฃจ์ด์ง ๊ฒ์ผ๋ก ๊ฐ์ ๋ฉ๋๋ค.
NVSHMEM์ ์ฅ์ ๊ณผ ์ ์ค์ผ์ด์ค
NVSHMEM์ GPU ๊ฐ์ ์ ํ๋ฆฌ์ผ์ด์ ์์ ํต์ ์ค๋ฒํค๋๋ฅผ ๊ทน์ ์ผ๋ก ์ค์ ๋๋ค. CPU ๊ฐ์ ์์ด GPU๊ฐ ์ง์ ํต์ ์ ์ ์ดํ๋ฏ๋ก, ์ง์ฐ ์๊ฐ์ด ๋ง์ดํฌ๋ก์ด ๋จ์๋ก ์ค์ด๋ค๊ณ CPU ์์์ ์ ์ฝํ ์ ์์ต๋๋ค. ํนํ ์์ ๋ฉ์์ง๋ฅผ ๋น๋ฒํ๊ฒ ์ฃผ๊ณ ๋ฐ์์ผ ํ๋ ์ ํ๋ฆฌ์ผ์ด์ ์์ ๊ทธ ํจ๊ณผ๊ฐ ๋๋๋ฌ์ง๋๋ค.
๊ฐํ ์ค์ผ์ผ๋ง์ด ํ์ํ HPC ์ ํ๋ฆฌ์ผ์ด์ ์์ NVSHMEM์ ํ์์ ์ ๋๋ค. GPU ์๊ฐ ๋์ด๋ ์๋ก ๊ฐ GPU๊ฐ ์ฒ๋ฆฌํ๋ ์์ ํฌ๊ธฐ๊ฐ ์ค์ด๋ค๊ณ , ๋ฐ๋ผ์ ํต์ ๋ฉ์์ง ํฌ๊ธฐ๋ ์์์ง๋๋ค. ์ด๋ฌํ ํ๊ฒฝ์์ NVSHMEM์ ์ ์ง์ฐ ํน์ฑ์ ์ ์ฒด ์์คํ ์ ํ์ฅ์ฑ์ ํฌ๊ฒ ํฅ์์ํต๋๋ค.
๊ทธ๋ํ ์๊ณ ๋ฆฌ์ฆ, ํฌ์ ํ๋ ฌ ์ฐ์ฐ, ๋ถ์ ๋์ญํ ์๋ฎฌ๋ ์ด์ ๊ณผ ๊ฐ์ด ๋ถ๊ท์นํ๊ณ ๋์ ์ธ ํต์ ํจํด์ ๊ฐ์ง ์ ํ๋ฆฌ์ผ์ด์ ๋ NVSHMEM์ ์ฃผ์ ์ฌ์ฉ ์ฌ๋ก์ ๋๋ค. ์ด๋ฌํ ์ ํ๋ฆฌ์ผ์ด์ ์ ์คํ ์ค์ ์ด๋ค ๋ฐ์ดํฐ๋ฅผ ์ด๋ PE๋ก๋ถํฐ ๊ฐ์ ธ์์ผ ํ๋์ง๊ฐ ๋์ ์ผ๋ก ๊ฒฐ์ ๋๋๋ฐ, NVSHMEM์ one-sided ํต์ ๋ชจ๋ธ์ด ์ด๋ฅผ ์์ฐ์ค๋ฝ๊ฒ ํํํ ์ ์๊ฒ ํด์ค๋๋ค.
MoEMixture-of-Experts ๋ชจ๋ธ์ฒ๋ผ ํ ํฐ๋ง๋ค ๋ค๋ฅธ ์ ๋ฌธ๊ฐ๋ก ๋ผ์ฐํ ๋๋ ํ๋์ ์ธ AI ์ํคํ ์ฒ์์๋ NVSHMEM์ ํต์ฌ์ ์ธ ์ญํ ์ ํฉ๋๋ค. DeepEP ๊ฐ์ MoE ํนํ ํต์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ NVSHMEM์ ๊ธฐ๋ฐ์ผ๋ก ๊ตฌ์ถ๋ ๊ฒ์ ์ฐ์ฐ์ด ์๋๋๋ค. GPU ์ปค๋ ๋ด์์ ์ฆ์ ํต์ ๊ฒฐ์ ์ ๋ด๋ฆฌ๊ณ ์คํํ ์ ์๋ NVSHMEM์ ๋ฅ๋ ฅ์ด MoE์ ๋์ ์ด๊ณ ๋ถ๊ท์นํ ํต์ ํจํด์ ํจ์จ์ ์ผ๋ก ์ฒ๋ฆฌํ๋ ๋ฐ ์ด์์ ์ด๊ธฐ ๋๋ฌธ์ ๋๋ค.
InfiniBand GPUDirect Async ์ ์ก
NVSHMEM์ InfiniBand ๋คํธ์ํฌ ํต์ ์ ์ ์ด ํ๋ ์ธ๊ณผ ๋ฐ์ดํฐ ํ๋ ์ธ์ ๋ชจ๋ GPU์์ ์์ ํ ๊ตฌํํ๋ ๊ฒ์ ์ง์ํฉ๋๋ค. ์ด๋ ๋๋ฐ์ด์ค๊ฐ ์์ํ ํต์ ์ ์ญ๋ฐฉํฅ ํ๋ก์ํ ํ์๋ฅผ ์ ๊ฑฐํฉ๋๋ค. ์ด ๊ธฐ๋ฅ์ InfiniBand GPUDirect Async(IBGDA) ์๊ฒฉ ์ ์ก์ผ๋ก ๋ ธ์ถ๋ฉ๋๋ค.
IBGDA ์ ์ก์ ์ฌ์ฉํ๊ธฐ ์ํ ์ ์ ์กฐ๊ฑด์ด ์์ต๋๋ค. Mellanox HCA์ NIC๋ง ์ง์๋๋ฉฐ, Mellanox OFED 5.0 ์ด์์ด ํ์ํฉ๋๋ค. ๋ํ nvidia.ko ๋๋ผ์ด๋ฒ๋ 510.40.3 ์ด์์ด์ด์ผ ํ๊ณ , nvidia_peermem 510.40.3 ์ด์ ๋๋ nv_peer_mem 1.3 ์ด์์ด ํ์ํฉ๋๋ค. ์ด๋ฌํ ์๊ตฌ์ฌํญ์ด ์ถฉ์กฑ๋๋ฉด GPU๊ฐ CPU ์์ด ์ง์ InfiniBand ๋คํธ์ํฌ ์ด๋ํฐ๋ฅผ ์ ์ดํ ์ ์๊ฒ ๋ฉ๋๋ค.
1.2. ์ค์ ์ฌ์ฉ ์์
๋ง ํต์ ํจํด
๊ฐ๋จํ ์์ ๋ฅผ ํตํด NVSHMEM์ ์ฌ์ฉ๋ฒ์ ์ดํด๋ณด๊ฒ ์ต๋๋ค. ๋ค์์ PE๋ค์ด ๋ง ๊ตฌ์กฐ๋ก ํต์ ํ๋ ํ๋ก๊ทธ๋จ์ ๋๋ค.
__global__ void simple_shift(int *destination) {
int mype = nvshmem_my_pe();
int npes = nvshmem_n_pes();
int peer = (mype + 1) % npes;
nvshmem_int_p(destination, mype, peer);
}
int main(void) {
int mype_node, msg;
cudaStream_t stream;
// NVSHMEM ์ด๊ธฐํ
nvshmem_init();
// ๋
ธ๋ ๋ด PE ID ์กฐํ ๋ฐ ๋๋ฐ์ด์ค ์ค์
mype_node = nvshmem_team_my_pe(NVSHMEMX_TEAM_NODE);
cudaSetDevice(mype_node);
cudaStreamCreate(&stream);
// Symmetric ๋ฉ๋ชจ๋ฆฌ ํ ๋น
int *destination = (int *) nvshmem_malloc(sizeof(int));
// ์ปค๋ ์คํ
simple_shift<<<1, 1, 0, stream>>>(destination);
// ๋ชจ๋ PE์ ์
๋ฐ์ดํธ ์๋ฃ ๋๊ธฐ
nvshmemx_barrier_all_on_stream(stream);
// ๊ฒฐ๊ณผ๋ฅผ ํธ์คํธ๋ก ๋ณต์ฌ
cudaMemcpyAsync(&msg, destination, sizeof(int),
cudaMemcpyDeviceToHost, stream);
cudaStreamSynchronize(stream);
printf("%d: received message %d\n", nvshmem_my_pe(), msg);
// ์ ๋ฆฌ
nvshmem_free(destination);
nvshmem_finalize();
return 0;
}
์ด ํ๋ก๊ทธ๋จ์ ๋์์ ๋จ๊ณ๋ณ๋ก ์ดํด๋ณด๊ฒ ์ต๋๋ค. main ํจ์๋ ๋จผ์ nvshmem_init()
์ผ๋ก NVSHMEM ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ด๊ธฐํํฉ๋๋ค. ๊ทธ ๋ค์ ๋
ธ๋ ๋ด ํ์์์ PE ID๋ฅผ ์กฐํํ์ฌ CUDA ๋๋ฐ์ด์ค๋ฅผ ์ค์ ํฉ๋๋ค. ๋๋ฐ์ด์ค ์ค์ ์ ๋ฉ๋ชจ๋ฆฌ ํ ๋น์ด๋ ์ปค๋ ์คํ ์ ์ ๋ฐ๋์ ์ํ๋์ด์ผ ํฉ๋๋ค.
nvshmem_malloc
์ ํตํด ๋ชจ๋ PE์ symmetric integer ๋ณ์ destination
์ ํ ๋นํฉ๋๋ค. ๊ทธ๋ฆฌ๊ณ simple_shift
์ปค๋์ ํ๋์ ์ค๋ ๋๋ก ์คํํ๋๋ฐ, ์ด ์ปค๋์ ์ธ์๋ก symmetric ๊ฐ์ฒด์ ํฌ์ธํฐ๋ฅผ ์ ๋ฌํฉ๋๋ค.
์ปค๋ ๋ด๋ถ์์๋ ์ ์ญ PE ID์ ์คํ ์ค์ธ PE์ ์ด ๊ฐ์๋ฅผ ์กฐํํฉ๋๋ค. ๊ทธ๋ฐ ๋ค์ nvshmem_int_p
ํจ์๋ฅผ ์ฌ์ฉํ์ฌ ๋จ์ผ ์ ์ put ์ฐ์ฐ์ ์ํํฉ๋๋ค. ์ด ์ฐ์ฐ์ ์์ ์ PE ID๋ฅผ ๋ค์ ๋ฒํธ์ PE(๋๋ ๋ง์ง๋ง PE์ ๊ฒฝ์ฐ 0๋ฒ PE)์ destination
์ ์๋๋ค. 8๊ฐ์ PE๋ก ์คํํ๋ฉด PE 0์ PE 7๋ก๋ถํฐ ๋ฉ์์ง๋ฅผ ๋ฐ๊ณ , PE 1์ PE 0์ผ๋ก๋ถํฐ ๋ฐ๋ ์์ผ๋ก ๋ง ํจํด์ด ํ์ฑ๋ฉ๋๋ค.
์ปค๋์ด ๋น๋๊ธฐ์ ์ผ๋ก ์คํ๋ ํ, nvshmemx_barrier_all_on_stream
์ผ๋ก ์คํธ๋ฆผ ์์์ ๋ฐฐ๋ฆฌ์ด๋ฅผ ์ํํ์ฌ ๋ชจ๋ ์
๋ฐ์ดํธ๊ฐ ์๋ฃ๋์๋์ง ํ์ธํฉ๋๋ค. ๊ทธ ๋ค์ ์
๋ฐ์ดํธ๋ destination
๊ฐ์ ๋น๋๊ธฐ์ ์ผ๋ก ํธ์คํธ๋ก ๋ณต์ฌํ๊ณ , ์คํธ๋ฆผ์ ๋๊ธฐํํ ํ ๊ฒฐ๊ณผ๋ฅผ ์ถ๋ ฅํฉ๋๋ค. ๋ง์ง๋ง์ผ๋ก ํ ๋นํ ๋ฒํผ๋ฅผ ํด์ ํ๊ณ NVSHMEM ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ข
๋ฃํฉ๋๋ค.
MPI์์ ํตํฉ: ์ ์ง์ ๋ง์ด๊ทธ๋ ์ด์
๊ธฐ์กด MPI ์ ํ๋ฆฌ์ผ์ด์ ์ NVSHMEM์ผ๋ก ์ ์ง์ ์ผ๋ก ํฌํ ํ๋ ค๋ ๊ฒฝ์ฐ, ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ํจ๊ป ์ฌ์ฉํ ์ ์์ต๋๋ค. ๋ค์ ์์ ๋ MPI ํ๋ก๊ทธ๋จ์์ NVSHMEM์ ์ด๊ธฐํํ๋ ๋ฐฉ๋ฒ์ ๋ณด์ฌ์ค๋๋ค.
#include <mpi.h>
#include <nvshmem.h>
#include <nvshmemx.h>
int main(int argc, char *argv[]) {
int rank, ndevices;
nvshmemx_init_attr_t attr;
MPI_Comm comm = MPI_COMM_WORLD;
attr.mpi_comm = &comm;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
cudaGetDeviceCount(&ndevices);
cudaSetDevice(rank % ndevices);
nvshmemx_init_attr(NVSHMEMX_INIT_WITH_MPI_COMM, &attr);
// ... NVSHMEM ์์
...
nvshmem_finalize();
MPI_Finalize();
return 0;
}
์ด ์์ ์์ MPI ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ๋จผ์ ์ด๊ธฐํํ๊ณ , MPI ๋ญํฌ๋ฅผ ์กฐํํ์ฌ CUDA ๋๋ฐ์ด์ค๋ฅผ ์ค์ ํฉ๋๋ค. nvshmemx_init_attr_t
๊ตฌ์กฐ์ฒด๋ฅผ ์์ฑํ๊ณ mpi_comm
ํ๋์ MPI ์ปค๋ฎค๋์ผ์ดํฐ ํธ๋ค์ ์ฐธ์กฐ๋ฅผ ํ ๋นํฉ๋๋ค. MPI ํธํ ๋ชจ๋๋ฅผ ํ์ฑํํ๊ธฐ ์ํด nvshmem_init
๋์ nvshmemx_init_attr
์ฐ์ฐ์ ์ฌ์ฉํฉ๋๋ค. ์ด๋ ๊ฒ ํ๋ฉด ๊ฐ MPI ํ๋ก์ธ์ค๊ฐ ๋์์ NVSHMEM PE๊ฐ ๋์ด, MPI ๋ญํฌ์ NVSHMEM ๋ญํฌ๋ฅผ ๋ชจ๋ ๊ฐ์ง๊ฒ ๋ฉ๋๋ค.
์ปดํ์ผ๊ณผ ์คํ
NVSHMEM ์ ํ๋ฆฌ์ผ์ด์
์ nvcc
๋ก ์ปดํ์ผํ๊ณ ๋งํฌํ ์ ์์ต๋๋ค. NVSHMEM์ ๋ ๊ฐ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ก ๋น๋๋ฉ๋๋ค. ๊ณต์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ libnvshmem_host.so
์ ์ ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ libnvshmem_device.a
์
๋๋ค. ์ ํ๋ฆฌ์ผ์ด์
์ ํธ์คํธ API๋ง ์ฌ์ฉํ๊ฑฐ๋ ๋๋ฐ์ด์ค API๋ง ์ฌ์ฉํ๋๋ผ๋ ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ๋ชจ๋ ๋งํฌํด์ผ ํฉ๋๋ค.
์ปดํ์ผ ์์ ๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
nvcc -rdc=true -ccbin g++ -gencode=$NVCC_GENCODE \
-I $NVSHMEM_HOME/include nvshmem_hello.cu \
-o nvshmem_hello.out \
-L $NVSHMEM_HOME/lib -lnvshmem_host -lnvshmem_device
NVSHMEM ์ ํ๋ฆฌ์ผ์ด์
์ mpirun
๋ฐ์ฒ๋ก ์ง์ ์คํํ ์ ์์ต๋๋ค. NVSHMEM ํน์ ์ต์
์ด๋ ๊ตฌ์ฑ ํ์ผ์ด ํ์ํ์ง ์์ต๋๋ค. ์๋ฅผ ๋ค์ด:
mpirun -n 4 -ppn 2 -hosts hostname1,hostname2 /path/to/nvshmem/app/binary
๋ํ srun
์ผ๋ก๋ ์ถ๊ฐ ๊ตฌ์ฑ ์์ด ์ง์ ์คํํ ์ ์์ต๋๋ค. ๊ธฐ๋ณธ์ ์ผ๋ก NVSHMEM ์ ํ๋ฆฌ์ผ์ด์
์ PMI-1์ ์ฌ์ฉํ์ฌ ํต์ ํ๋ ค๊ณ ์๋ํ์ง๋ง, NVSHMEM_BOOTSTRAP_PMI
ํ๊ฒฝ ๋ณ์๋ฅผ ์ค์ ํ์ฌ ๋ฐํ์์ ์ฌ์ฉ๋๋ PMI ์ธํฐํ์ด์ค๋ฅผ ์์ ํ ์ ์์ต๋๋ค.
NVSHMEM์ ๋
๋ฆฝ์ ์ธ ์ ํ๋ฆฌ์ผ์ด์
๊ฐ๋ฐ์ ๊ฐ๋ฅํ๊ฒ ํ๊ธฐ ์ํด Hydra Process Manager ์ค์น ์คํฌ๋ฆฝํธ๋ฅผ scripts/install_hydra.sh
์ ํจํค์งํฉ๋๋ค. ์ด๋ ์ธ๋ถ MPI ์ค์น ์์ด๋ NVSHMEM์ ์ฌ์ฉํ ์ ์๊ฒ ํฉ๋๋ค. ์ค์น๋ Hydra ๋ฐ์ฒ๋ nvshmrun.hydra
๋ก ๋ถ๋ฆฌ๋ฉฐ, ์ฌ์ด ์ ๊ทผ์ ์ํด nvshmrun
์ฌ๋ณผ๋ฆญ ๋งํฌ๊ฐ ์์ฑ๋ฉ๋๋ค.
1.3. ์ฑ๋ฅ ์ต์ ํ ๋ฐ ๋๋ฒ๊น
์ฑ๋ฅ ์ต์ ํ
NVSHMEM์ ์ฑ๋ฅ์ ์ต๋ํํ๊ธฐ ์ํด์๋ CUDA ํ๋ก๊ทธ๋๋ฐ ๋ชจ๋ฒ ์ฌ๋ก๋ฅผ ๋ฐ๋ผ์ผ ํฉ๋๋ค. ํนํ ๋ฐ์ดํฐ ๋ณํฉdata coalescing์ ์ด์งํ๋ ๋ฉ๋ชจ๋ฆฌ ์ ๊ทผ ํจํด์ ์ฌ์ฉํ๋ ๊ฒ์ด ์ค์ํฉ๋๋ค. GPU ํ๋์จ์ด์ ๋ฐ์ดํฐ ๋ณํฉ ๊ธฐ๋ฅ์ ์์กดํ์ฌ ๋คํธ์ํฌ ์์์ ํจ์จ์ฑ์ ๋ฌ์ฑํ๊ธฐ ๋๋ฌธ์ ๋๋ค.
์ํ ๋ด์ ์ค๋ ๋๋ค์ด ์ฐ์๋ ๋ฉ๋ชจ๋ฆฌ ์ฃผ์์ ์ ๊ทผํ๋๋ก ์ฝ๋๋ฅผ ๊ตฌ์ฑํ๋ฉด, NVSHMEM์ด ์ด๋ฌํ ์ ๊ทผ์ ํ๋์ ํจ์จ์ ์ธ ๋คํธ์ํฌ ์ ์ก์ผ๋ก ๋ณํฉํ ์ ์์ต๋๋ค. ๋ฐ๋๋ก ๋ฌด์์์ ์ด๊ฑฐ๋ ์คํธ๋ผ์ด๋๊ฐ ํฐ ์ ๊ทผ ํจํด์ ์ฌ๋ฌ ๊ฐ์ ์์ ๋คํธ์ํฌ ์ ์ก์ ๋ฐ์์์ผ ์ฑ๋ฅ์ ์ ํ์ํต๋๋ค.
๋์นญ ๋ฉ๋ชจ๋ฆฌ ํ ๋น ํฌ๊ธฐ๋ ์ ์คํ๊ฒ ์ ํํด์ผ ํฉ๋๋ค. ๋๋ฌด ์์ ํ ๋น์ ๊ด๋ฆฌ ์ค๋ฒํค๋๋ฅผ ์ฆ๊ฐ์ํค๊ณ , ๋๋ฌด ํฐ ํ ๋น์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ๋ญ๋นํฉ๋๋ค. ์ ํ๋ฆฌ์ผ์ด์ ์ ํต์ ํจํด์ ๋ถ์ํ์ฌ ์ ์ ํ ํ ๋น ๋จ์๋ฅผ ๊ฒฐ์ ํ๋ ๊ฒ์ด ์ข์ต๋๋ค.
fence์ quiet ์ฐ์ฐ์ ์ฑ๋ฅ์ ์ํฅ์ ์ค ์ ์์ผ๋ฏ๋ก ํ์ํ ๊ฒฝ์ฐ์๋ง ์ฌ์ฉํด์ผ ํฉ๋๋ค. fence๋ ํน์ PE์ ๋ํ ์์๋ง ๋ณด์ฅํ๋ฏ๋ก quiet๋ณด๋ค ๊ฐ๋ฒผ์ฐ๋ฉฐ, ์ ๋์ ํต์ ์์๋ง ํ์ํ ๊ฒฝ์ฐ์๋ fence๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ํจ์จ์ ์ ๋๋ค. quiet๋ ๋ชจ๋ PE์ ๋ํ ์ ์ญ ์์๋ฅผ ๋ณด์ฅํ๋ฏ๋ก ๋ ๋ฌด๊ฑฐ์ด ์ฐ์ฐ์ ๋๋ค.
๋๋ฒ๊น
NVSHMEM ์ ํ๋ฆฌ์ผ์ด์ ์ ๋๋ฒ๊น ํ ๋๋ ๋ช ๊ฐ์ง ์ผ๋ฐ์ ์ธ ํจ์ ์ ํผํด์ผ ํฉ๋๋ค. ๊ฐ์ฅ ํํ ๋ฌธ์ ๋ ๋์นญ ์ฃผ์symmetric address๋ฅผ ๋ค๋ฅธ PE์ ๊ณต์ ํ๋ ค๊ณ ์๋ํ๋ ๊ฒ์ ๋๋ค. ๋์นญ ์ฃผ์๋ ํ ๋น๋ฐ์ PE์์๋ง ์ ํจํ๋ฉฐ, ๋ค๋ฅธ PE์๊ฒ ์ด ์ฃผ์ ๊ฐ์ ์ ๋ฌํด๋ ์๋ฏธ๊ฐ ์์ต๋๋ค. ๋์ ๋ฐ์ดํฐ ์์ฒด๋ฅผ ์ ์กํ๊ฑฐ๋, ๋ชจ๋ PE๊ฐ ๋์ผํ ์ธ๋ฑ์ค๋ฅผ ์ฌ์ฉํ์ฌ symmetric ๋ฐฐ์ด์ ์ ๊ทผํ๋๋ก ์ฝ๋๋ฅผ ๊ตฌ์ฑํด์ผ ํฉ๋๋ค.
์ด๊ธฐํ์ ์ข
๋ฃ ์์๋ ์ค์ํฉ๋๋ค. nvshmem_init()
์ ๋ชจ๋ NVSHMEM ์ฐ์ฐ๋ณด๋ค ๋จผ์ ํธ์ถ๋์ด์ผ ํ๋ฉฐ, nvshmem_finalize()
๋ ๋ชจ๋ PE๊ฐ NVSHMEM ์ฌ์ฉ์ ์๋ฃํ ํ์๋ง ํธ์ถ๋์ด์ผ ํฉ๋๋ค. ์ด๋ฌํ ํธ์ถ๋ค์ ์งํฉ ์ฐ์ฐ์ด๋ฏ๋ก ๋ชจ๋ PE๊ฐ ๋์์ ์ํํด์ผ ํฉ๋๋ค. ์ผ๋ถ PE๋ง ์ด๊ธฐํํ๊ฑฐ๋ ์ข
๋ฃํ๋ฉด ํ๋ก๊ทธ๋จ์ด ๋ฉ์ถ๊ฒ ๋ฉ๋๋ค.
๋๊ธฐํ API๋ฅผ ์ฌ์ฉํ๋ ์ปค๋์์ ๋ฐ๋๋ฝ์ด ๋ฐ์ํ๋ค๋ฉด, ์งํฉ ์ปค๋ ์คํ API๋ฅผ ์ฌ์ฉํ๊ณ ์๋์ง ํ์ธํด์ผ ํฉ๋๋ค. ๋ํ ๋ชจ๋ PE๊ฐ ๋์ผํ ๋๊ธฐํ ์ง์ ์ ๋๋ฌํ๋์ง, GPU ์ค๋ฒ์๋ธ์คํฌ๋ฆฝ์
์ด ๋ฐ์ํ์ง ์๋์ง ์ ๊ฒํด์ผ ํฉ๋๋ค. ํ๊ฒฝ ๋ณ์ NVSHMEM_DEBUG
๋ฅผ ์ค์ ํ๋ฉด ๋ ์์ธํ ๋๋ฒ๊ทธ ์ ๋ณด๋ฅผ ์ป์ ์ ์์ต๋๋ค.
2. NVSHMEM๊ณผ NCCL: ๊ทผ๋ณธ์ ์ผ๋ก ๋ค๋ฅธ ๋ ๊ฐ์ง ์ฒ ํ
2.1. NVSHMEM vs. NCCL
์ ์ด
GPU ์ปค๋์์ ์ง์
CPU๊ฐ ๋ช ๋ น
๋ฐฉ์
One-sided (put/get)
Two-sided (์งํฉ ์ฐ์ฐ)
ํฌ๊ธฐ
์์ ๋ฉ์์ง ์ต์ ํ
๋๋ ๋ฐ์ดํฐ ์ต์ ํ
์ฉ๋
๋น์ ํ, ์ฆ๊ฐ ํต์
ํ์ค ์งํฉ ํต์
๋ ๋ฒจ
์ ์์ค, ์ธ๋ฐํ ์ ์ด
๊ณ ์์ค, ์ฌ์ฉ ํธ๋ฆฌ
ํต์ ์ ์ฃผ์ฒด
NVSHMEM๊ณผ NCCL์ ๊ฐ์ฅ ๊ทผ๋ณธ์ ์ธ ์ฐจ์ด๋ ํต์ ์ ๋๊ฐ ์์ํ๊ณ ์ ์ดํ๋๋์ ๋๋ค. NVSHMEM์ GPU๊ฐ ์ง์ ํต์ ์ ์ฃผ๋ํ๋ ์ ์์ค API์ ๋๋ค. CUDA ์ปค๋ ์์์ ์คํ๋๋ GPU ์ค๋ ๋๊ฐ "๋๋ ์ง๊ธ 3๋ฒ GPU์ ๋ฉ๋ชจ๋ฆฌ์์ ์ด ๋ฐ์ดํฐ๋ฅผ ์ฝ์ด์ฌ ๊ฒ"์ด๋ผ๊ณ ๊ฒฐ์ ํ๊ณ ์ฆ์ ์คํํฉ๋๋ค. CPU๋ ์ด ๊ณผ์ ์ ์ ํ ๊ด์ฌํ์ง ์์ผ๋ฉฐ, GPU๊ฐ ์์ ํ ์์จ์ ์ผ๋ก ํต์ ์ ์ํํฉ๋๋ค.
๋ฐ๋ฉด NCCL์ CPU๊ฐ ํต์ ์ ์งํํ๋ ๊ณ ์์ค API์ ๋๋ค. ํธ์คํธ ์ฝ๋์์ ์คํ๋๋ CPU๊ฐ "๋ชจ๋ GPU๋ค์ด์ฌ, ์ง๊ธ๋ถํฐ AllReduce ์ฐ์ฐ์ ์ํํ๋ผ"๊ณ ๋ช ๋ น์ ๋ด๋ฆฌ๋ฉด, GPU๋ค์ด ์ด์ ์๋ตํ์ฌ ์งํฉ ํต์ ์ ์ํํฉ๋๋ค. ํต์ ์ ์์๊ณผ ์กฐ์จ์ ์ฌ์ ํ CPU์ ์์ญ์ ๋จ์์๋ ๊ฒ์ ๋๋ค.
One-sided vs Two-sided: ํต์ ๋ชจ๋ธ์ ์ฐจ์ด
NVSHMEM์ one-sided ํต์ ๋ชจ๋ธ์ ์ฌ์ฉํฉ๋๋ค. ์ด๋ ํ์ชฝ์ด ์ผ๋ฐฉ์ ์ผ๋ก ํต์ ์ ์์ํ ์ ์๋ค๋ ์๋ฏธ์
๋๋ค. nvshmem_put
์ฐ์ฐ์ ์ฌ์ฉํ๋ฉด "๋ด๊ฐ ๋ํํ
์ด ๋ฐ์ดํฐ๋ฅผ ์ค๊ฒ"๋ผ๊ณ ์ผ๋ฐฉ์ ์ผ๋ก ์๋๋ฐฉ ๋ฉ๋ชจ๋ฆฌ์ ๋ฐ์ดํฐ๋ฅผ ์ธ ์ ์๊ณ , nvshmem_get
์ฐ์ฐ์ผ๋ก๋ "๋ด๊ฐ ๋ํํ
์ ์ด ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ฌ๊ฒ"๋ผ๊ณ ์๋๋ฐฉ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ฝ์ ์ ์์ต๋๋ค. ์ค์ํ ์ ์ ๋ฐ๋ ์ชฝ์ด๋ ์ฃผ๋ ์ชฝ์ด ์ด ํต์ ์ด ์ผ์ด๋๋ ๊ฒ์ ๋ช
์์ ์ผ๋ก ์ ํ์๊ฐ ์๋ค๋ ๊ฒ์
๋๋ค. ๋ง์น ๊ณต์ ์ฌ๋ฌผํจ์ ๋ฌผ๊ฑด์ ๋ฃ๊ฑฐ๋ ๊บผ๋ด๋ ๊ฒ์ฒ๋ผ ์๋ํฉ๋๋ค.
NCCL์ two-sided ํต์ ๋ชจ๋ธ์ ๊ธฐ๋ฐ์ผ๋ก ํฉ๋๋ค. AllReduce, Broadcast, AllGather์ ๊ฐ์ ์งํฉ ํต์ ์ฐ์ฐ์์๋ ๋ชจ๋ ์ฐธ์ฌ์๊ฐ "์ฐ๋ฆฌ๋ ์ง๊ธ ํจ๊ป ์ด ์์ ์ ์ํํ ๊ฒ์ด๋ค"๋ผ๋ ๊ฒ์ ์๊ณ ์์ด์ผ ํฉ๋๋ค. ๋ชจ๋ GPU๊ฐ ๋์์ ํต์ ์ ์ฐธ์ฌํ๋ฉฐ, ์๋ก ํ๋ ฅํ์ฌ ๋๋์ ๋ฐ์ดํฐ๋ฅผ ๊ตํํฉ๋๋ค. ์ด๋ ํ์์ค์ ๋ชจ๋ ๋ชจ์ฌ์ ์ ๋ณด๋ฅผ ๊ณต์ ํ๋ ๊ฒ๊ณผ ์ ์ฌํ ๊ฐ๋ ์ ๋๋ค.
๋ฐ์ดํฐ ํฌ๊ธฐ์ ์ต์ ํ ์์ญ
NVSHMEM์ ์์ ๋ฉ์์ง ์ ์ก์ ํนํ ๊ฐ์ ์ ๋ณด์ ๋๋ค. ๋ช ๋ฐ์ดํธ์์ ์ ํฌ๋ก๋ฐ์ดํธ ๋ฒ์์ ๋ฐ์ดํฐ๋ฅผ ๋น๋ฒํ๊ฒ ์ฃผ๊ณ ๋ฐ๋ ์ํฉ์์ ๋ฐ์ด๋ ์ฑ๋ฅ์ ๋ฐํํฉ๋๋ค. GPU ์ปค๋์ด ์คํ๋๋ ๋์ค์ ํ์ํ ์์ ๋ฐ์ดํฐ๋ฅผ ์ฆ์ ๊ฐ์ ธ์ค๊ฑฐ๋ ๋ณด๋ผ ์ ์๊ธฐ ๋๋ฌธ์, ์ง์ฐ ์๊ฐ์ด ๋งค์ฐ ์ค์ํ ์์ ์ ์ด์์ ์ ๋๋ค. ๊ฐํ ์ค์ผ์ผ๋ง(strong scaling)์ด ํ์ํ ์ ํ๋ฆฌ์ผ์ด์ ์์ GPU ์๊ฐ ๋์ด๋ ์๋ก ๋ฉ์์ง ํฌ๊ธฐ๊ฐ ์์์ง๋ ๊ฒฝํฅ์ด ์๋๋ฐ, ์ด๋ฌํ ์๋๋ฆฌ์ค์์ NVSHMEM์ ์ฅ์ ์ด ๊ทน๋ํ๋ฉ๋๋ค.
NCCL์ ๋๋ ๋ฐ์ดํฐ ์ ์ก์ ์ต์ ํ๋์ด ์์ต๋๋ค. ์ ๊ธฐ๊ฐ๋ฐ์ดํธ์ ๋ฌํ๋ ํ ์๋ฅผ ์ฌ๋ฌ GPU ๊ฐ์ ๋๊ธฐํํด์ผ ํ๋ ์ํฉ์์ ํ์ํ ์ฑ๋ฅ์ ๋ณด์ฌ์ค๋๋ค. ๋ถ์ฐ ํ์ต์์ ๋ชจ๋ธ ๊ฐ์ค์น๋ ๊ทธ๋๋์ธํธ๋ฅผ ๋ชจ๋ GPU์ ๊ฑธ์ณ ์ง๊ณํ๊ณ ๋ถ์ฐํ๋ ์์ ์ NCCL์ ์ ํ์ ์ธ ์ฌ์ฉ ์ฌ๋ก์ ๋๋ค. ์งํฉ ํต์ ํจํด์ด ๋ฏธ๋ฆฌ ์ ํด์ ธ ์๊ณ , ๋ชจ๋ ์ฐธ์ฌ์๊ฐ ๋์์ ๋๋์ ๋ฐ์ดํฐ๋ฅผ ์ฒ๋ฆฌํด์ผ ํ๋ ์ํฉ์์ NCCL์ ํจ์จ์ฑ์ด ๋น์ ๋ฐํฉ๋๋ค.
API ๋ ๋ฒจ๊ณผ ์ฌ์ฉ ๋ฐฉ์
NVSHMEM์ ์ ์์ค API๋ก์ ๋งค์ฐ ์ธ๋ฐํ ์ ์ด๊ฐ ๊ฐ๋ฅํฉ๋๋ค. CUDA ์ปค๋ ์ฝ๋ ์์์ ์ง์ ํธ์ถ๋๋ฉฐ, GPU ํ๋ก๊ทธ๋๋จธ๊ฐ ๋ฉ๋ชจ๋ฆฌ ์ ๊ทผ ํจํด์ ์ ํํ๊ฒ ์ ์ดํ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด __global__ void my_kernel()
ํจ์ ์์์ int data = nvshmem_int_g(&remote_data, target_pe);
์ ๊ฐ์ด ์๊ฒฉ GPU์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ๋ง์น ๋ก์ปฌ ๋ฉ๋ชจ๋ฆฌ์ฒ๋ผ ์ฝ์ ์ ์์ต๋๋ค. ์ด๋ฌํ ์ ์์ค ์ ๊ทผ์ ๋ณต์กํ ํต์ ํจํด์ ๊ตฌํํ ์ ์๋ ์ ์ฐ์ฑ์ ์ ๊ณตํ์ง๋ง, ๋์์ ํ๋ก๊ทธ๋๋จธ๊ฐ ๋ ๋ง์ ์ธ๋ถ ์ฌํญ์ ๊ด๋ฆฌํด์ผ ํ๋ค๋ ๊ฒ์ ์๋ฏธํฉ๋๋ค.
// CUDA ์ปค๋ ์์์ ์ง์ ์ ์ด
__global__ void my_kernel() {
int data = nvshmem_int_g(&remote_data, target_pe);
// GPU๊ฐ ์ง์ ์๊ฒฉ ๋ฉ๋ชจ๋ฆฌ ์ฝ๊ธฐ
}
NCCL์ ๊ณ ์์ค API๋ก์ ์ฌ์ฉ์ด ๊ฐํธํฉ๋๋ค. CPU ํธ์คํธ ์ฝ๋์์ ncclAllReduce(sendbuff, recvbuff, count, ncclFloat, ncclSum, comm, stream);
์ ๊ฐ์ด ํจ์๋ฅผ ํธ์ถํ๋ฉด, ๋ณต์กํ ์งํฉ ํต์ ์ด ์๋์ผ๋ก ์ต์ ํ๋์ด ์คํ๋ฉ๋๋ค. ๋ด๋ถ์ ์ผ๋ก ๋ง ์๊ณ ๋ฆฌ์ฆ์ด๋ ํธ๋ฆฌ ์๊ณ ๋ฆฌ์ฆ ๊ฐ์ ์ต์ ํ๋ ํต์ ํจํด์ด ์ ์ฉ๋์ง๋ง, ์ฌ์ฉ์๋ ์ด๋ฌํ ์ธ๋ถ ์ฌํญ์ ์ ๊ฒฝ ์ธ ํ์๊ฐ ์์ต๋๋ค. ์ด๋ฌํ ์ถ์ํ ๋๋ถ์ ๋ถ์ฐ ํ์ต ์ฝ๋๋ฅผ ๋น ๋ฅด๊ฒ ์์ฑํ๊ณ ์ ์ง๋ณด์ํ ์ ์์ต๋๋ค.
// CPU ํธ์คํธ ์ฝ๋์์
ncclAllReduce(sendbuff, recvbuff, count,
ncclFloat, ncclSum, comm, stream);
// CPU๊ฐ ์งํฉ ํต์ ์์
2.2. ์ ์ค์ผ์ด์ค๋ณ ์ ํ ๊ฐ์ด๋
NVSHMEM์ด ์ ํฉํ ๊ฒฝ์ฐ
์๊ณ ๋น๋ฒํ ํต์ ์ด ํ์ํ ์ ํ๋ฆฌ์ผ์ด์ ์์ NVSHMEM์ด ๋น์ ๋ฐํฉ๋๋ค. GPU ์ปค๋ ๋ด์์ ์ฆ์ ํต์ ๊ฒฐ์ ์ด ๋ด๋ ค์ง๊ณ ์คํ๋์ด์ผ ํ๋ ๊ฒฝ์ฐ, ์๋ฅผ ๋ค์ด ์๋ ด ์กฐ๊ฑด์ ์ฒดํฌํ๊ฑฐ๋ ์์ ์ํ ํ๋๊ทธ๋ฅผ ๊ตํํ๋ ์์ ์ ์ด์์ ์ ๋๋ค. ๊ทธ๋ํ ์๊ณ ๋ฆฌ์ฆ์ด๋ ํฌ์ ํ๋ ฌ ์ฐ์ฐ์ฒ๋ผ ํต์ ํจํด์ด ๋น์ ํ์ ์ด๊ณ ๋์ ์ผ๋ก ๋ณํ๋ ๊ฒฝ์ฐ์๋ NVSHMEM์ ์ ์ฐ์ฑ์ด ํ์์ ์ ๋๋ค. MoE ๋ชจ๋ธ์ ํ ํฐ ๋ผ์ฐํ ์ฒ๋ผ ๊ฐ ํ ํฐ์ด ๋์ ์ผ๋ก ๋ค๋ฅธ ์ ๋ฌธ๊ฐ๋ก ๋ณด๋ด์ ธ์ผ ํ๋ ์ํฉ์์๋ NVSHMEM์ ์ ์์ค ์ ์ด๊ฐ ์ค์ํ ์ญํ ์ ํฉ๋๋ค.
NCCL์ด ์ ํฉํ ๊ฒฝ์ฐ
๋๋ ๋ฐ์ดํฐ์ ์งํฉ ํต์ ์ด ํ์ํ ๊ฒฝ์ฐ NCCL์ด ์ต์ ์ ์ ํ์ ๋๋ค. ๋ถ์ฐ ๋ฐ์ดํฐ ๋ณ๋ ฌ ํ์ต์์ ๋ชจ๋ GPU์ ๊ทธ๋๋์ธํธ๋ฅผ ํฉ์น๋ AllReduce ์ฐ์ฐ์ด ๋ํ์ ์ ๋๋ค. ๋ชจ๋ GPU๊ฐ ๋์์ ์ฐธ์ฌํ์ฌ ํ๋ ฅํด์ผ ํ๋ ํ์ค์ ์ธ ํต์ ํจํด์์ NCCL์ ๊ณ ์์ค API๋ ๊ตฌํ์ ํฌ๊ฒ ๋จ์ํํฉ๋๋ค. ์ ๊ธฐ๊ฐ๋ฐ์ดํธ์ ๋ฌํ๋ ๋ชจ๋ธ ๊ฐ์ค์น๋ฅผ ์ฌ๋ฌ GPU์ ๋ธ๋ก๋์บ์คํธํ๊ฑฐ๋, ์ ์ฒด ๋ฐฐ์น์ ํต๊ณ๋ฅผ ๋ชจ์ผ๋ ์์ ์ฒ๋ผ ๋๋ ๋ฐ์ดํฐ ์ด๋์ด ์ฃผ๋ ๋ณ๋ชฉ์ธ ๊ฒฝ์ฐ NCCL์ ์ต์ ํ๋ ์งํฉ ํต์ ์๊ณ ๋ฆฌ์ฆ์ด ํ์ํ ์ฑ๋ฅ์ ์ ๊ณตํฉ๋๋ค.
GPU ๊ฐ ํต์ ์ ๋ ์ด์ ๋จ์ํ ๋ฐ์ดํฐ ์ด๋์ ๋ฌธ์ ๊ฐ ์๋๋๋ค. NVSHMEM๊ณผ NCCL์ ๊ฐ๊ฐ ๋ค๋ฅธ ์ฒ ํ๊ณผ ์ฌ์ฉ ์ฌ๋ก๋ฅผ ๊ฐ์ง๊ณ ์์ผ๋ฉฐ, ํ๋์ ๋ณต์กํ AI ์์คํ ์์๋ ๋ ๊ฐ์ง ์ ๊ทผ ๋ฐฉ์์ ์ ์ ํ ์กฐํฉํ๋ ๊ฒ์ด ์ค์ํฉ๋๋ค. Megatron-Core๋ ํฌ๊ด์ ์ธ ํ์ต ํ๋ ์์ํฌ๋ก์ ๋ค์ํ ๋ณ๋ ฌํ ์ ๋ต์ ์ ๊ณตํ๋ฉฐ, DeepEP๋ MoE ํน์ ์ ํต์ ํจํด์ ์ํด NVSHMEM๊ณผ GPUDirect Async๋ฅผ ํ์ฉํ ์ ๋ฌธํ๋ ์๋ฃจ์ ์ ์ ์ํฉ๋๋ค.
References
NVIDIA NVSHMEM Documentation: https://docs.nvidia.com/nvshmem/api/using.html
NVSHMEM: GPU-Integrated Communication for NVIDIA GPU Clusters: https://www.nvidia.com/en-us/on-demand/session/gtcspring21-s32515
NCCL and NVSHMEM: https://www.youtube.com/watch?v=zxGVvMN6WaM
Last updated