[CS231n]Lecture08-Deep learning Software

GPU

  • Graphics card 또는 Graphics Processing Unit이라고 하는데 결국엔 우리가 아는 사실 처럼 computer graphics를 랜더링하기 위해 더 와닿게 말하자면 게임을 더 최적의 환경에서 하기 위해 만들어 졌다고 할 수 있다.
# Cores Clock speed Memory Price
CPU 4 4.4 GHz Shared with system $339
CPU 10 3.5 GHz Shared with system $1723
GPU 3840 1.6 GHz 12GB GDDR5X $1200
GPU 1920 1.68 GHz 8GB GDDR5 $399
  • 위의 표에서 볼 수 있듯이 CPU의 경우 core의 수가 적다. GPU는 CPU보다 훨씬 더 많은 core를 가지고 있지만 각각의 코어가 더 느린 clock speed에서 동작하며 그 코어들이 CPU처럼 독립적으로 동작하지 않으며 많은 일을 처리할 수 없다. GPU는 코어마다 독립적인 테스크가 있는 것이 아니라 많은 코어들이 하나의 테스크를 병렬적으로 수행한다. GPU의 코어의 수가 많다는 것은 어떤 테스크가 있을 때 그 테스크에 대해 병렬로 수행하기 아주 적합하다는 것을 알 수 있다.

  • CPU에도 캐시가 있지만 비교적 작다. 대부분의 memory는 RAM에서 끌어다 쓴다. 실제 RAM과 GPU간의 통신은 상당한 보틀넥을 초래한다. 그렇기 때문에 GPU는 보통 RAM이 내장되어 있다. GPU는 내장되어있는 메모리와 코어 사이의 캐싱을 하기 위한 일종의 다계층 캐싱 시스템을 가지고 있다. 이는 CPU의 캐싱구조와 매우 유사하다.

  • CPU는 범용처리에 적합하고, GPU는 병렬처리에 더 특화되어 있다. GPU에서 정말 잘 동작하고 아주 적합한 알고리즘은 바로 행렬곱 연산이다.

  • 실제로 GPU로 학습을 할 때 생기는 문제 중 하나는 바로 Model과 Model의 가중치는 전부 GPU RAM에 상주하고 있는 반면에 Train data는 하드드라이브(SSD)에 있다는 것이다. 때문에 Train time에 디스크에 디스크에서 데이터를 읽어들이는 작업을 세심하게 신경쓰지 않으면 보틀넥이 발생할 수 있다. 즉,GPU는 forward/backward 가 아주 빠른 것은 사실이지만, 디스크에서 데이터를 읽어들이는 것이 보틀넥(병목현상)이 되는 것이다. 이러한 문제를 해결하기 위한 해결책 중 하나는 데이터셋이 작다면 데이터 전체를 RAM에 올려 놓는 것이다. 또는 데이터셋이 작지 않더라도, 서버에 RAM 용량이 크다면 가능 할 수도 있을 것이다. 또한 기본적으로 HDD 대신 SSD를 사용하는 것이 좋다. 또 다른 방법으로는 CPU의 multiple CPU threads(CPU의 다중스레드)를 이용해서 데이터를 RAM에 미리 올려 놓는 것이다.(Pre-fetching)GPU는 빠른데 데이터 전송 자체가 충분히 빠르지 못하면 보틀넥이 생길수 밖에 없다.

Deep learning framework

Deep learning framework를 사용하는 이유

1) 딥러닝 프레임워크를 이용하면 엄청 복잡한 그래프를 우리가 직접 만들지 않아도 된다.
2) forward pass만 잘 구현해 놓는다면 Back propagation은 알아서 구성되어 gradient를 쉽게 계산할 수 있다.
3) cuBLAS, cuDNN, CUDA 그리고 memory등을 직접 세심하게 다루지 않고 GPU를 효율적으로 사용할 수 있다.

framework의 존재 목표는 forward pass 코드를 Numpy스럽게 작서을 해 놓으면 GPU에서도 동작하고 gradient도 알아서 계산해 주는 것이다.

[그림1]
[그림2]

Tensorflow
  • placeholder는 그래프 밖에서 데이터를 넣어주는 변수이고, variable은 그래프 내부에 있는 변수이다.
  • Tensorflow는 분산처리도 지원하기 떄문에 서로 다른 머신을 이용해 graph를 쪼개서 실행시킬 수도 있다. 혹 분산처리를 계획한다면 Tensorflow가 유일한 선택지가 될 것이다.
Pytorch
  • Facebook에서 나온 PyTorch는 TensorFlow와는 다르게 3가지 추상화 레벨을 정의해 놓았다. 이미 고수준의 추상화를 내장하고 있기에 (Module 객체) TensorFlow 처럼 어떤 모듈을 선택할 지 고민할 필요가 없다.
    • tensor : Numpy array와 유사한 tensor object가 있으며 GPU에서 작동한다.
      • tensorflow의 Numpy array
    • variable : 그래프의 노드(그래프를 구성하고 gradient 등을 계산)
      • tensorflow의 Tensor, Variable, Placeholder
    • Module : 전체 Neural network를 구성
      • tensorflow의 tf.layers, TFSlim, TFLearn 등

Static computational graph vs Dynamic graph

Pytorch와 TensorFlow의 주된 차이점 중 하나이다.

  • TensorFlow는 두단계로 나누어진다.(Static computational graph - 그래프가 단 하나만 고정적으로 존재하기 때문이다.)
    • 1) 그래프를 구성하는 단계
    • 2) 구성된 그래프를 반복적으로 돌리는 단계
    • 그래프를 한번 구성해 놓으면 학습시에는 동일한 그래프를 아주 많이 재사용하게 된다. 그러므로 그런 그래프를 최적화시킬 기회가 주어질 수 있다. 처음 최적화 시킬 때 까지 시간이 소요된다 하더라도 최적화된 그래프를 여러번 사용한다는 것을 고려해보면 그에 따른 소요된 시간은 중요치 않을 수 도 있다. 또한 메모리내에 그 네트워크 구조를 갖고 있다는 것이되므로 네트워크 구조를 파일 형태로 저장할 수 있다.
    • 그래프의 모든 전체적인 연산들을 다 고려해서 만들어 주어야한다.(ex.loop문)
    • TensorFlow Fold라는 TF 라이브러리가 static graph으로 만든 트릭으로 dynamic graphs를 작성하게 해준다.
  • Pytorch는 하나의 단계이다.(Dynamic computational graph)
    • 매번 forward pass 할 때 마다 새로운 그래프를 구성한다.
    • 또한, 그래프 구성과 그래프 실행하는 과정이 얽혀 있기에 모델을 재사용하기 위해서는 항상 원본 코드가 필요하다.
    • 코드가 훨씬 깔끔하고 작성하기 더 쉽다.
    • tensorflow와는 다르게 python 명령어들을 활용할 수 있다.
    • 다양한 데이터에도 유동적인 네트워크를 만들 수 있다.(RNN사용 - NLP에서 문장을 파싱하는 문제 중 트리를 파싱하기 위해 recursive한 네트워크가 필요할 수 있다.)
    • Recurrent network, Recursive network, Modular Networks(이미지와 질문을 던지면 적절한 답을 하는 구조)를 구성할 때 조금 더 편할 수 있다.