안녕하세요, Sigmoid입니다.
예전엔 주로 받던 GPU관련 질문은, "무슨 게임을 하는데 안끊기는게 뭐냐" 였는데,
요즘들어 질문의 추세가 많이 바뀐것 같습니다.
요즘 주로 받는 질문은 아래와 같습니다.
질문이 워낙 자주 오거니와, GPU를 Graphic이 아닌 Compute로 사용하는데 있어 자료가 많지 않은것 같기도 해서, 답변용 참조 링크로 사용할 겸, 이 포스팅을 작성해 봅니다. 앞으로 몇번에 걸쳐서 글을 쓰게 될지 잘모르지만, 우선 첫번째 이야기를 시작해보겠습니다.
여기서 우리는 한가지 사실만 알면됩니다. 초록색 픽셀들에 대해 동일한 연산이 일어난다!. 왜그런지는 다음문단에서 이해하실 수 있습니다.
그림상 초록 네모가 쉐이더 코어입니다. cpu는 동시에 두개의 코어가 동작하고, gpu는 수십개가 동작합니다
참고로 저 코어는 회사마다 설계가 다르고, 따라서 사용하는 어셈블리도 다릅니다. 그래서 공통적으로는 shader language로 코드를 작성하면, 각 회사별로 제공되는 컴파일러를 이용하여 사용하게 됩니다.
여기서 우리가 알아야 할것은 NVIDIA는 쿠다, 그외의 GPU vendor에서는 OpenCL을 사용하면 여러분이 GPU를 연산용으로 사용할 수 있다 입니다.
머신러닝이 왜 matmul이냐라고 궁금해 하시는 분들을 위해 아래 링크를 추천합니다.
(그림출처 및 참조: https://petewarden.com/2015/04/20/why-gemm-is-at-the-heart-of-deep-learning/)
제가 정리해 드린 몇가지 배경지식을 이해하셨다면, 앞으로 조금은 편하게 문제를 풀어보실수 있지 않을까 생각합니다.
아래와 같은 네트워크를 텐서플로우로 구현했다고 가정해 봅니다.
Q: gpu를 언제 쓸수 있을까요?
A: pooling layer를 제외한 matmul로 표현되는 conv와 fully-connected 레이어에서 쓸수 있겠네요.
네트워크를 구성하고 훈련하는 부분은 gpu에겐 관심분야가 아닙니다. gpu는 오직 matmul을 병렬처리 하는데 목적이 있고, fully connected layer가 matmul이라고 이미 말씀드렸으니 결국, 레이어 별로 가속된다고 생각해도 무방합니다.
Q: 첫번째 conv레이어에서 gpu에게 어떻게 일을 주어야 할까요?
A: 먼저 conv를 처리하기 위한 matmul shader 코드와, 곱해질 모델의 weight값과 input을 주어야 합니다.
해당 코드들이 다 메모리에 올라가 있어야 한다는 뜻입니다.
Q: 메모리에 어떻게 코드랑 input/weight를 올리나요?
A: Cuda/OpenCL 함수들이 저업무를 합니다. 조금더 자세히 말씀드리면 특정함수 호출시 드라이버를 통해 명령이 gpu로 전달될텐데, 그과정에서 드라이버는 gpu 메모리에 필요한 데이터들을 준비하는 작업을 동시에 합니다.
Q: 배치값을 바꾸면 어떤 일이 일어나나요?
A: GPU메모리에 한번에 올려야하는 량이 변합니다.
Q: 몇개의 코어를 사용하게 될지는 어떻게 결정됩니까?
A: 드라이버가 input의 량을 보고 결정하게 됩니다. 최대한 병렬성을 해치지 않도록
Q: 쿠다 버전이 안맞는건 어떤 의미인가요?
A: GPU제품마다 지원하는 쿠다버전이 다른 이유는 하드웨어의 상태(지원하는 operation, 메모리 크기, 코어 갯수)등이 다르기 때문입니다. 해당 하드웨어 스펙에 따라 드라이버들이 다르게 동작합니다. 때로는 함수의 원형이 아예 변경되기도 하지요. 주로 문제가 발생하는 이유가 여기에 있습니다.
부족한 글 읽어주셔서 감사드리며, 혹시 문제가 되는 내용이나 틀린 내용이 있다면 언제든 피드백 부탁드립니다.
여러분의 up vote 가 큰 도움이 됩니다.
후원: 0x62467Ca1b449c854c4720395Dd9a7c6Ed5df47B7(ethereum)