일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
- Git
- C++
- vscode
- UI
- CSS
- Express
- js
- react
- review
- figma
- PyTorch
- python
- DB
- PRISMA
- frontend
- html
- Linux
- sqlite
- threejs
- mongo
- ts
- GAN
- API
- ps
- ML
- CV
- postgresql
- DM
- nodejs
- SOLID
- Today
- Total
아카이브
[review] TensorFlow: A system for large-scale machine learning 본문
2016년 5월의 논문입니다.
arxiv | https://arxiv.org/abs/1605.08695
github | GitHub - tensorflow/tensorflow: An Open Source Machine Learning Framework for Everyone
Abstraction
TensorFlow(이하 TF)는 다양한 대규모 계산 환경에서 작동가능한 ML 시스템입니다. TF는 dataflow graph를 사용해 계산들과 그 공유 상태를 나타낼 수 있습니다. 또한, DNN의 학습 및 추론 과정을 효과적으로 지원해 많은 서비스의 프로덕션 환경 상에서 사용되고 있습니다. 이 논문에서는 TF의 dataflow 모델을 다른 모델들과 비교하면서 설명하고, 실제 응용 프로그램에서 얼마나 강력한 성능을 발휘할 수 있는지를 보여줍니다.
1. Introduction
최근 ML 모델의 발달, 대규모 데이터셋 처리 능력의 향상, 그리고 낮은 진입장벽의 ML 플랫폼 개발로 인해 ML 분야에서 많은 연구가 이루어졌습니다. 이 논문에서는 ML 모델을 학습시키고, 실제 제품에도 적용시킬 수 있는 TensorFlow 시스템을 소개합니다. TF는 대규모 학습 및 추론을 위해 다량의 GPU를 효율적으로 사용하며, 데이터 센터에서 부터 모바일 기기까지 다양한 플랫폼과 호환될 수 있도록 설계되었습니다.
TF는 unified dataflow graph를 사용해 ML 알고리즘과 그 상태를 나타냅니다. 기존의 dataflow graph처럼 각 node가 불변값에 대한 계산을 나타내는 것이 아니라, 가변값과 그 값을 수정하는 연산도 나타낼 수 있게 되었습니다. 이렇게 계산의 수행과 상태 관리를 하나의 모델로 통합함으로서 TF는 다양한 병렬 연산을 수행해볼 수 있게 되었습니다. 그리고 다양한 조절 프로토콜을 구축하여 scalable learning에서 동기 복제(synchronous replication)를 사용한 연산도 성공적으로 수행하였습니다.
2. Background & Motivation
이 논문에서는 대규모 ML 시스템의 필요요소를 파악하고, 관련된 연구들이 이를 충족하는지 확인하였습니다.
2.1. Requirements
Distributed Execution
일반적으로 ML 알고리즘은 학습 데이터가 많을수록 더 좋은 성능을 발휘하며, 이는 곧 효율적인 병렬 처리를 필요로 합니다. 병렬 계산에서는 분산 파일 시스템이 데이터들을 보유하고, 각 프로세스가 하위 데이터셋을 동시에 처리합니다. 이를 통해 I/O 병목 현상을 제거하고 전처리 작업들을 독립적으로 수행할 수 있습니다.
대부분의 알고리즘은 경사 하강법(gradient descent)을 사용하므로, 분산 시스템에서는 각각의 프로세스가 학습 모델과 하위 배치를 입력값으로 받습니다.
Accelerator Support
ML은 다차원 연산과 같이 많은 시간이 걸리는 연산을 필요로 합니다. 이런 경우도 병렬 계산은 가능하지만, 데이터별로 종속성이 있어 밀접하게 결합되도록 구현해야 합니다. 이를 위해 accelerator를 사용하면 성능을 향상하고 전력을 절약할 수 있습니다.
Training & Inference support
추론단계는 필요에 따라 빠른 속도로 계산을 할 수 있어야 합니다. 또한 추론과 학습은 주로 같은 코드 구조를 공유하기 때문에, 이를 모두 처리할 수 있는 시스템이 필요합니다.
2.2. Related work
- Single-machine frameworks
- Batch dataflow systems
- Parameter servers
3. TensorFlow execution model
TF는 dataflow graph를 이용해 알고리즘의 계산과 상태를 나타냅니다. 이 그래프에는 수학 연산, 매개변수, 전처리에 대한 정보를 포함하고 있습니다. 이 dataflow는 서로 독립적인 계산을 쉽게 병렬로 실행하고 분산시킬 수 있게 합니다. TF의 dataflow는 batch dataflow와 비교하여 두 가지 다른 점이 있습니다.
- 모델이 전체 그래프 중에서 중복되는 하위 그래프(subgraph)들을 동시에 실행할 수 있다.
- 각각의 node는 공유가능하고 수정가능(mutable)한 값을 가질 수 있다.
Parameter server architecture에서 중요한 점은 큰 모델을 훈련할 때 수정 가능한 상태가 필요하다는 것입니다. 이를 통해 큰 매개변수에 대한 in-place update를 할 수 있으며, 빠르게 학습 단계로 전파할 수 있게 됩니다. 학습 후 모델 매개변수를 공유하면 하위 dataflow graph를 실행할 수 있습니다. 이로써, 사용자들은 다양한 최적화 알고리즘과 병렬화 전략을 실험할 수 있습니다.
3.1. Dataflow graph elements
TF의 그래프에서 각각의 node는 가장 작은 단위의 연산(operations)을 나타내며, edge는 각 node의 출력 혹은 입력 텐서(tensors)를 나타냅니다.
Tensors
TF에서 모든 데이터는 텐서로 표현되며, ML 알고리즘에서 일반적인 수학 연산의 입력과 출력을 자연스럽게 표현하는 데 사용됩니다. 모든 텐서는 밀집되어 있어 시스템의 최하위 레벨도 메모리 할당 및 직렬화에 대한 간단한 구현을 할 수 있도록합니다. 이는 프레임워크에 걸리는 overhead를 줄일 수 있습니다. 텐서의 크기는 여러 차원이 될 수 있습니다.
Operations
연산은 0 이상의 입력 텐서를 받아 0 이상의 출력을 내놓습니다. 연산은 그 속성에 따라 컴파일 시간이 일정하거나 가변적일 수 있습니다. 예를 들어 Const 연산은 입력이 없고 단일 출력을 가집니다. 그에 반해 AddN은 가변적이어서 얼마 만큼의 입력을 허용하는지 정의하는 정수 속성 "N"이 있습니다.
Stateful operations: variables
연산은 실행될 때마다 참조되거나 수정될 수 있습니다. Variable 연산은 모델의 공유 매개변수를 저장하는 데 사용되는 buffer가 존재합니다. Variable은 입력 없이 buffer를 읽고 쓸 수 있는 '참조 핸들(reference handle)'을 생성합니다. Read 연산은 참조 핸들을 입력으로 받고 변수 값 텐서를 출력합니다.
Stateful operations: queues
몇 가지의 queue를 사용하면 더 정밀한 계산을 할 수 있습니다. 가장 간단한 queue는 FIFO Queue로, Variable처럼 참조 핸들을 생성하며 Enqueue나 Dequeue같은 연산이에 사용됩니다. Enqueue는 주어진 queue가 가득 찬 경우 막힐 것이며, Dequeue는 주어진 queue가 비어 있는 경우 막힙니다.
3.2. Partial and concurrent execution
TF는 dataflow graph를 이용해 특정 응용프로그램에서 사용되는 모든 계산을 나타낼 수 있습니다.
3.3. Distributed Execution
Dataflow graph는 하위 계산들을 subgraph로 표현할 수 있기 때문에 분산처리를 간단하게 나타낼 수 있다는 장점이 있습니다. TF는 분산 배치할 기기에 따라 여러 kernel을 등록할 수 있습니다(5절). TF의 배치 알고리즘은 각 장치의 제약에 따라 적절한 장치에 연산을 배치할 수 있도록 합니다. 또한 "특정 작업 내의 장치 중 아무거나" 또는 "아무 작업 내의 GPU"와 같은 사항도 지정할 수 있습니다.
Subgraph는 각 단계별 연산이 완료되면 다시 기기별로 분할됩니다. 기기 d에 대한 subgraph는 추가적으로 Send와 Recv 연산을 할 수 있습니다. Send는 입력값을 기기에 전달하며, 값의 이름을 지정하는 랑데부 키(rendezvous key)를 사용합니다. Recv는 특정 랑데부 키에 대한 값이 사용 가능해질 때까지 기다립니다.
한 번 subgraph가 만들어진 후 각 기기로 분할 배치되면, TF는 이를 cache에 저장하기 때문에 반복적으로 subgraph를 실행하기에 최적화 되어 있습니다.
3.4. Dynamic Control Flow
TF에서 입력값은 연산이 시행되기 전 반드시 계산이 완료된 상태여야 합니다(strict control flow). 하지만 몇몇 알고리즘의 경우 동적인 계산이 필요하기도 합니다(dynamic control flow).
이 때문에 TF는 Switch와 Merge연산을 이용한 동적 계산 또한 지원합니다. Switch는 data input과 control input 두 가지 입력값을 받아 true / false branch 중 어느 것을 선택할지 결정합니다. Merge는 두 가지 branch를 입력으로 받아 Swtich에서 선택된 branch를 출력합니다. 이 연산들은 반복자 작업도 지원하기 때문에 loop구현에도 사용할 수 있습니다.
4. Extensibility case studies
4.1. Differentiation and Optimization
이 논문에서는 SGD(Stochastic Gradient Descent)에서 자동으로 미분작업을 수행할 수 있도록 사용자 수준의 라이브러리(user-level library)를 만들었습니다. 이를 통해 사용자는 layer와 loss function을 조합하여 신경망을 만들 수 있고, library는 자동으로 역전파를 시행할 것입니다.
TF의 미분 작업은 loss function에서부터 각 매개변수들까지 dataflow graph를 역행하면서 계산합니다. 역행과정에서 gradient는 각 단계별로 계산된 값이 누적됩니다. 사용자는 특정 계산에 대해 gradient를 정의하고 batch normalization과 같은 최적화를 적용하여 훈련 속도와 안정성을 향상시킬 수 있습니다.
TF는 다양한 종류의 최적화 알고리즘도 제공합니다. Momentum, Adam grad오 같이 식 하나로 나타낼 수 없는 복잡한 최적화 함수도 variable 연산을 이용해 쉽게 사용할 수 있습니다.
4.2. Handling very large models
고차원의 데이터를 학습하기 위해서는 분산된 형태로 다뤄야 합니다. 이를 위해 TF의 graph에는 sparse embedding layer가 구현되어 있습니다. Figure 3은 embedding layer가 두 개의 작업으로 나뉘는 과정을 나타냅니다.
4.3. Fault tolerance
모델을 학습시키는 데에는 상당한 시간이 필요합니다. 그동안 학습에 사용되는 자원이 항상 유효하지 않으므로, TF는 학습동안 자원 이상으로 인한 오류가 발생해도 정상 작동할 수 있도록 설계되어야 합니다. 그렇지만 모든 매개변수에 대해서 보완을 할 필요는 없습니다. TF graph의 구조상 빠른 속도로 다시 계산할 수 있는 경우가 많으며, 서로 큰 의존성이 있는 경우가 많이 없기 때문입니다.
Fault tolerance를 위해서 TF는 사용자 수준에서 주기적으로 checkpoint를 저장하고(Save), 오류 발생시 이를 불러올 수 있도록(Restore) 합니다(Figure 1). 언제 어떤 checkpoint를 저장할 것인지는 사용자가 임의로 지정할 수 있습니다. 간혹 checkpointing과 학습 업데이트가 동시에 수행되면 checkpoint에 잘못된 값이 저장될 수도 있지만, asynchornous gradient descent를 이용한다면 실제로 모델에 미치는 영향을 무시할 수 있습니다.
4.4. Synchronous replica coordination
기존의 asynchronous 방식(Figure 4.a)은 높은 utilization을 가지지만, 각 단계들이 최신 매개변수를 바로 반영하지 못하는 문제가 있습니다. Synchronous 방식(Figure 4.b)은 block queue(3.1절)을 사용해 모든 기기가 같은 매개변수에 접근할 수 있도록 합니다. 하지만 이 방식도 속도가 느린 기기에 의해 병목현상이 발생한다는 단점이 있습니다.
이 점을 해결하기 위해 backup-worker synchronous 방식(Figure 4.c)를 채용했습니다. 이 방법은 병목이 되는 기기를 찾아내기 전에 미리 동일한 백업 작업을 실행합니다. 이후 병목현상이 발생하면, 백업 작업으로 대신 업데이트 함으로서 병목현상을 예방할 수 있습니다.
5. Implementation
TF의 핵심 라이브러리는 c++로 구현되었습니다.
Distributed master는 사용자의 요청에 따라 모델을 실행합니다. 요청된 dataflow graph를 여러 기기에 맞는 subgraph로 나눠 분담시키고, 필요에 따라 cache에 결과값을 저장하기도 합니다. Dataflow executer는 master의 요청에 따라 subgraph를 계산합니다. Executer가 kernel을 local 기기에 보내면 기기들이 병렬계산을 통해 kernel 연산을 수행하게 됩니다. Kerenel operation들은 cuDNN 등의 라이브러리를 사용해서 구현하였습니다. 기기 사이의 작업 전달은 cudaMemcpyAsync() API와 DMA 등을 이용했습니다.
4절에서 제시된 기능은 모두 사용자 수준의 C API를 이용해 구현된 것으로, 필요하다면 사용자가 직접 kernel 연산을 추가로 구현할 수도 있습니다.
6. Evaluation
이 절에서는 여러 가지 작업 환경에 따라 TF의 성능을 평가합니다. 특별한 언급이 없는 한, 모든 실험은 공유 프로덕션 클러스터에서 실행하고, 모든 그래프는 중앙값을 나타내며 10% ~ 90%의 오차구간을 표시합니다. 이 평가는 (i) 시스템의 overhead가 거의 없으며, (ii) 대규모 계산을 사용하여 실제 응용 프로그램을 가속화할 수 있음을 보여줍니다.
6.1. Single-machine benchmarks
TF가 대규모 환경에 적합한 ML 시스템이긴 하지만, 작은 규모의 환경에서도 좋은 성능을 발휘해야 하기 때문에 단일 machine에서의 성능을 측정하였습니다. Table 1은 라이브러리 별 각 신경망에 대한 실행 시간을 나타낸 것으로, TF는 Caffe보다 훨씬 빠른 속도를 보이며 Torch와 비슷한 성능을 보여줍니다. Neon의 경우 어셈블리로 convolutional kernel을 구현했기 때문에 다른 라이브러리보다 뛰어난 성능을 보입니다.
6.2. Synchronous replica microbenchmark
Figure 6.은 기기의 수에 따라 TF가 수행하는 초당 Null Training Step 수를 모델의 크기 별로 보여줍니다.
6.3. Image classification
이미지 인식분야가 ML의 주요 연구중 하나인 점에서 TF에게도 이미지 인식 및 분류가 중요한 과제라고 할 수 있습니다. TF는 Google의 Inception-v3 모델을 사용해 GPU 클러스터의 연산을 얼마나 잘 수행하는지 측정하였습니다.
6.4. Language modeling
언어모델은 주어진 단어 시퀀스 다음으로 올 만한 단어를 예측합니다. 이 실험에서는 TF가 반복 신경망을 사용하여 One Billion Word Benchmark 의 텍스트를 모델링하는 방법을 조사합니다. 어휘 크기 |V|가 주어질 때 신경망의 최종 layer는 어휘 크기 만큼의 클래스에 해당하는 확률들을 계산해야 합니다. 때문에 어휘 크기는 훈련의 성능을 제한할 수 있습니다. 이 논문에서는 작은 규모로 실험하기 위해 일반적인 40,000 단어만을 사용하게 되었습니다.
7. Conclusion
지금까지 TensorFlow의 extensible dataflow 기반 programming model을 소개했습니다. 이 논문의 요지는 TensorFlow가 다른 기존 모델의 기능을 수행할 뿐 아니라 다양한 종류의 대규모 모델을 다룰 수 있는 통일된 모델을 제공할 수 있다는 것입니다.
TensorFlow는 아직 개선될 사항이 많다고 주장합니다. 유연한 dataflow 기법이 성능에 도움을 줄 수 있지만, 대부분의 사용자에게 효과적인 기본값을 아직 정하지 못했다고 합니다. 이후 자동 최적화 기법에 대한 후속 연구로 이 문제를 해결할 것으로 보입니다. 시스템 수준에서는 자동 배치 알고리즘, 커널 융합, 메모리관리, 그리고 스케쥴링에 대해서 연구하고 있습니다.
또한 일부 사용들에게 있어 정적 dataflow graph의 한계점이 문제가 되고 있습니다. 따라서 계산 구조가 동적으로 전개되는 경우에 대해서 분산된 자원을 효율적으로 사용할 수 있는 시스템에 대해서 연구해야 합니다.