brunch

You can make anything
by writing

C.S.Lewis

by Chris송호연 Aug 23. 2020

Ray 아키텍쳐 백서 (번역)

모던 인공지능 엔지니어링 아키텍쳐

Ray의 아키텍쳐에 대해 정리되어 있는 논문을 번역했습니다. 원문은 아래 링크에 있습니다. 

https://www.usenix.org/system/files/osdi18-moritz.pdf


많이들 알고 계시겠지만, Ray는 인공지능 엔지니어링 분야에서 아주 잘 만들어지고, 모던한 오픈소스입니다. 코드를 읽어보면, 구글 기반 라이브러리들이 많아서 구글러가 만들었다는 것을 알 수 있죠. 분산 강화학습, 분산 학습, 분산 AutoML(Tune) 등 최근 인공지능 엔지니어링에서 가장 필요로 하는 컴포넌트들을 추상화해둔 라이브러리입니다. 아키텍쳐 면에서 상당히 많은 고민이 녹아져있으며, 대규모로 분산 학습 시스템을 만들 수 있는 중요한 인사이트를 제공합니다. 강화학습 뿐만 아니라, 조금 복잡한 분산 환경이 필요한 인공지능 회사라면 꼭 리뷰하면 좋을 논문이라 생각합니다. 


현재 대부분의 인공지능 회사들은 지도학습 기반의 ML Pipeline이 주로 구축되고 있지만, 저는 강화학습 기반의 엔지니어링 인프라가 필요할 날이 올 거라고 확실히 믿습니다. 준비합시다 :) 


쓰라린 교훈에서 배워야 할 한 가지는 사용 가능한 컴퓨터의 성능이 증가함에 따라 계속 확장되는 범용 방법의 강력한 힘입니다. - 리차드 서튼



요약


차세대 AI 응용 프로그램은 지속적으로 환경과 상호 작용하고 이러한 상호 작용을 통해 배웁니다. 이러한 응용 프로그램은 성능과 유연성 측면에서 새롭고 까다로운 시스템 요구 사항을 부과합니다. 본 백서에서는 이러한 요구 사항을 고려하고이를 해결하기위한 분산 시스템 인 Ray를 제시합니다. Ray는 단일 동적 실행 엔진이 지원하는 작업 병렬 및 Actor 기반 계산을 모두 표현할 수있는 통합 인터페이스를 구현합니다. 성능 요구 사항을 충족하기 위해 Ray는 분산 스케줄러와 분산 및 Fault-tolerant 저장소를 사용하여 시스템 제어 상태를 관리합니다. 우리의 실험에서 우리는 몇 가지 까다로운 강화 학습 응용 프로그램에 대해 기존의 특수 시스템보다 초당 180 만 개 이상의 작업과 더 나은 성능을 보여줍니다.


1. 소개

지난 20 년 동안 많은 조직에서 점점 더 많은 양의 데이터를 수집하고 활용하기 위해 노력해 왔습니다. 이로 인해 배치, 스트리밍 및 그래프 처리 시스템을 포함한 분산 데이터 분석을위한 다양한 프레임 워크가 개발되었습니다. 이러한 프레임 워크의 성공으로 인해 조직은 비즈니스 또는 과학 전략의 핵심 부분으로 대용량 데이터 세트를 분석 할 수 있었으며 “빅 데이터”시대를 열었습니다. 


최근에는 데이터 중심 응용 프로그램의 범위가보다 복잡한 인공 지능 (AI) 또는 기계 학습 (ML) 기술을 포함하도록 확장되었습니다. 패러다임 사례는지도 학습과 데이터 포인트에 레이블이 붙어 있고 데이터 포인트를 레이블에 매핑하기 위한 기술이 심층 신경망에 의해 제공되는 경우입니다. 이러한 심층 네트워크의 복잡성은 심층 신경망의 훈련 * 균등 한 기여와 예측에서의 사용에 중점을 둔 또 다른 프레임 워크로 이어졌다. 이러한 프레임 워크는 배치 설정에서 학습 시간을 단축하기 위해 특수 하드웨어 (예 : GPU 및 TPU)를 활용합니다. 예로는 TensorFlow, MXNet 및 PyTorch가 있습니다. 그러나 AI의 약속은 클래스 감독 학습보다 훨씬 넓습니다. 새로운 AI 응용 프로그램은 점점 더 역동적 인 환경에서 작동하고 환경의 변화에 대응하고 장기적인 목표를 달성하기 위해 일련의 작업을 수행해야합니다. 


수집 된 데이터를 활용하는 것뿐만 아니라 가능한 조치의 공간을 탐색하는 것을 목표로해야합니다. 이러한 광범위한 요구 사항은 강화 학습 (RL)의 패러다임 내에 자연스럽게 구성되어 있습니다. RL은 지연되고 제한된 피드백에 기초하여 불확실한 환경에서 지속적으로 작동하는 학습을 다룹니다. RL 기반 시스템은 이미 Google의 AlphaGo가 인간 세계 챔피언을 제치고, 대화 시스템, UAV 및 로봇 조작에 이르기까지 놀라운 결과를 낳았습니다. RL 응용 프로그램의 핵심 목표는 게임을이기거나 드론을 조종하는 등 시간이 지남에 따라 효과적인 성능을 제공하는 정책 (환경 상태에서 작업 선택으로 매핑)을 배우는 것입니다. 대규모 응용 프로그램에서 효과적인 정책을 찾으려면 세 가지 주요 기능이 필요합니다. 


첫 째, RL 방법은 종종 정책을 평가하기 위해 시뮬레이션에 의존합니다. 시뮬레이션을 통해 다양한 동작 순서 선택을 탐색하고 해당 선택의 장기적 결과에 대해 배울 수 있습니다. 


둘 째, RL 알고리즘은지도 학습 대상과 마찬가지로 물리적 환경과의 시뮬레이션 또는 상호 작용을 통해 생성 된 데이터를 기반으로 정책을 개선하기 위해 분산 학습을 수행해야합니다. 


셋 째, 정책은 제어(Control) 문제를 해결하기위한 솔루션을 제공하기위한 것이므로 대화식 폐 루프 및 개 루프 제어 시나리오(Interactive closed-loop or open-loop scenarios)에서 정책을 제공해야합니다. 


이들 이러한 특성으로 인해 새로운 시스템 요구 사항이 발생합니다.RL 시스템은 세밀한 계산을 지원해야하며 (예 : 실제 세계와 상호 작용할 때 밀리 초 단위로 렌더링 작업을 수행하고 수많은 시뮬레이션을 수행해야 함) 시간에 따라 이질성을 지원해야합니다 (예 : 시뮬레이션에 밀리 초 또는 시간이 걸릴 수 있음). 자원 사용 (예 : 훈련 용 GPU 및 시뮬레이션 용 CPU)에서 시뮬레이션 결과 또는 환경과의 상호 작용으로 인해 향후 계산이 변경 될 수 있으므로 동적 실행을 지원해야합니다. 따라서 밀리 초 수준의 대기 시간으로 초당 수백만 개의 이기종 작업을 처리하는 동적 계산 프레임 워크가 필요합니다. 


Big Data 워크로드 또는 감독 된 학습 워크로드를 위해 개발 된 기존 프레임 워크는 이러한 새로운 RL 요구 사항을 충족시키지 못합니다. Map-Reduce, Apache Spark와 같은 대량 동기식 병렬 시스템 Dryad는 세밀한 시뮬레이션 또는 정책 제공을 지원하지 않습니다. CIEL 및 Dask와 같은 작업 병렬 시스템은 분산 학습 및 서빙을 거의 지원하지 않습니다. Naiad 및 Storm 과 같은 스트리밍 시스템에서도 마찬가지입니다. TensorFlow 및 MXNet 과 같은 분산 딥 러닝 프레임 워크는 자연스럽게 시뮬레이션 및 서빙을 지원하지 않습니다. 마지막으로, TensorFlow Serving 및 Clipper 와 같은 모델 서비스 시스템은 훈련이나 시뮬레이션을 지원하지 않습니다. 원칙적으로 여러 기존 시스템 (예 : 분산 학습용 Horovod, 서빙 용 Clipper 및 시뮬레이션 용 CIEL)을 함께 연결하여 엔드 투 엔드 솔루션을 개발할 수 있지만 실제로 이러한 접근 방식은 이러한 시스템의 긴밀한 결합으로 인해 불가능합니다 응용 프로그램 내의 구성 요소. 결과적으로 오늘날 연구원과 실무자들은 전문화 된 RL 애플리케이션을위한 일회용 시스템을 구축합니다. 이 접근 방식은 스케줄링, 내결함성 및 데이터 이동과 같은 표준 시스템 과제를 각 애플리케이션으로 근본적으로 밀어 냄으로써 분산 애플리케이션 개발에 막대한 시스템 엔지니어링 부담을 부과합니다. 


본 논문에서는 RL 어플리케이션을 시뮬레이션, 학습 및 제공 할 수있는 범용 클러스터 컴퓨팅 프레임 워크 인 Ray를 제안합니다. 이러한 워크로드의 요구 사항은 시뮬레이션과 같은 경량 및 상태 비 저장 계산에서 훈련과 같은 장기적이고 상태 기반 계산에 이르기까지 다양합니다. 이러한 요구 사항을 충족시키기 위해 Ray는 작업 병렬 및 Actor 기반 계산을 모두 표현할 수있는 통합 인터페이스를 구현합니다. 작업을 통해 Ray는 시뮬레이션을 효율적이고 동적으로로드 밸런스합니다. 큰 입력과 상태 공간 (예 : 이미지, 비디오)을 처리하고 오류를 복구합니다. 대조적으로, 액터는 Ray가 모델 훈련과 같은 상태 저장 계산을 효율적으로 지원하고 공유 변경 가능 상태를 클라이언트 (예 : 매개 변수 서버)에 노출시킵니다. Ray는 확장 성이 뛰어나고 내결함성이있는 단일 동적 실행 엔진을 통해 Actor와 작업 중단을 구현합니다. 성능 요구 사항을 충족하기 위해 Ray는 기존 프레임 워크에서 일반적으로 중앙 집중화되는 두 가지 구성 요소, 즉 (1) 작업 스케줄러 및 (2) 계산 계보 및 데이터 개체의 디렉토리를 유지 관리하는 메타 데이터 저장소를 배포합니다. 이를 통해 Ray는 밀리 초 수준의 대기 시간으로 초당 수백만 개의 작업을 예약 할 수 있습니다. 또한 Ray는 작업 및 Actor에 대한 계보 기반 내결함성을 제공합니다. 및 메타 데이터 저장소에 대한 복제 기반 내결함성. Ray가 RL 애플리케이션의 맥락에서 서비스, 학습 및 시뮬레이션을 지원하지만 이것이 다른 상황에서 이러한 워크로드에 대한 솔루션을 제공하는 시스템을 대체하는 것으로 간주되는 것은 아닙니다. 특히 Ray는 Clipper 및 TensorFlow Serving과 같은 시스템을 대체하는 것을 목표로하지 않습니다. 이러한 시스템은 모델 관리, 테스트 및 모델 구성을 포함하여 모델을 배포 할 때 광범위한 문제를 해결하기 때문입니다. 마찬가지로, 유연성에도 불구하고 Ray는 Spark [64]와 같은 일반적인 데이터 병렬 프레임 워크를 대체하지 않습니다. 현재 이러한 프레임 워크가 제공하는 풍부한 기능과 API (예 : 스 트래 글러 완화, 쿼리 최적화)가 없기 때문입니다. 우리는 다음과 같은 기여를합니다. 


새로운 RL 애플리케이션의 필수 구성 요소 인 학습, 시뮬레이션 및 서비스를 통합하는 최초의 분산 프레임 워크를 설계하고 구축합니다.

이러한 작업을 지원하기 위해 동적 작업 실행 엔진 위에 액터와 작업 병렬 추상화를 통합합니다. 

확장 성과 내결함성을 달성하기 위해 제어 상태가 샤딩 된 메타 데이터 저장소에 저장되고 다른 모든 시스템 구성 요소는 상태가없는 시스템 설계 원칙을 제안합니다.

확장 성을 달성하기 위해 상향식 분산 스케줄링 전략을 제안합니다. 제어 상태가 샤딩 된 메타 데이터 저장소에 저장되고 다른 모든 시스템 구성 요소는 상태가없는 시스템 설계 원칙을 제안합니다.


2. 요구사항과 개발 동기

그림 1: 강화학습 시스템의 예시

먼저 RL 시스템의 기본 구성 요소를 고려하고 Ray의 핵심 요구 사항을 구체화합니다. 그림 1에 표시된 것처럼 RL 설정에서 에이전트는 환경과 반복적으로 상호 작용합니다. 에이전트의 목표는 보상을 극대화하는 정책을 배우는 것입니다. 정책은 환경 상태에서 작업 선택으로의 매핑입니다. 환경, 에이전트, 상태, 조치 및 보상에 대한 정확한 정의는 애플리케이션에 따라 다릅니다. 정책을 배우기 위해 에이전트는 일반적으로 2 단계를 사용합니다.


프로세스 : (1) 정책 평가(Policy Evaluation) 및 (2) 정책 개선(Policy Improvement). 정책을 평가하기 위해 에이전트는 환경 (예 : 환경 시뮬레이션)과 상호 작용하여 궤적을 생성합니다. 여기서 궤적은 현재 정책에 의해 생성 된 (상태, 보상) 튜플의 시퀀스로 구성됩니다. 그런 다음 에이전트는 이러한 궤적을 사용하여 정책을 개선합니다. 즉, 보상을 극대화하는 기울기 방향으로 정책을 업데이트합니다. 그림 2는 에이전트가 정책을 학습하기 위해 사용하는 의사 코드의 예를 보여줍니다. 이 의사 코드는 궤적을 생성하기 위해 롤아웃 (환경, 정책)을 호출하여 정책을 평가합니다. 그런 다음 train policy ()는 이러한 궤도를 사용하여 policy.update (trajectories)를 통해 현재 정책을 개선합니다. 이 프로세스는 정책이 수렴 될 때까지 반복됩니다. 따라서 RL 애플리케이션을위한 프레임 워크는 학습, 서비스 및 시뮬레이션을위한 효율적인 지원을 제공해야합니다 (그림 1). 다음으로 이러한 워크로드에 대해 간략하게 설명합니다. 훈련에는 일반적으로 정책을 업데이트하기 위해 종종 분산 설정에서 확률 적 경사 하강 법 (SGD) 실행이 포함됩니다. 분산 SGD는 일반적으로 allreduce 집계 단계 또는 매개 변수 서버 [32]에 의존합니다.



Serving은 훈련 된 정책을 사용하여 환경의 현재 상태에 따라 작업을 렌더링합니다. 서빙 시스템은 지연 시간을 최소화하고 초당 결정 수를 최대화하는 것을 목표로합니다. 확장을 위해로드는 일반적으로 정책을 제공하는 여러 노드에서 균형을 이룹니다. 마지막으로, 대부분의 기존 RL 애플리케이션은 시뮬레이션을 사용하여 정책을 평가합니다. 현재 RL 알고리즘은 실제 세계와의 상호 작용에서 얻은 데이터에만 의존 할만큼 충분히 샘플 효율적이지 않습니다. 이러한 시뮬레이션은 복잡도가 매우 다양합니다. 몇 ms (예 : 체스 게임에서 움직임 시뮬레이션)에서 몇 분 (예 : 자율 주행 자동차의 현실적인 환경 시뮬레이션)이 소요될 수 있습니다. 학습과 서빙을 서로 다른 시스템에서 개별적으로 처리 할 수있는지도 학습과는 달리 RL에서는 이러한 세 가지 워크로드가 모두 단일 애플리케이션에서 긴밀하게 결합되어 있으며 이들간에 엄격한 지연 시간이 요구됩니다. 현재는 이러한 워크로드 커플 링을 지원하는 프레임 워크가 없습니다. 이론적으로는 여러 특수 프레임 워크를 함께 연결하여 전체 기능을 제공 할 수 있지만 실제로는 RL의 맥락에서 시스템 간의 결과 데이터 이동 및 대기 시간이 엄청납니다. 그 결과 연구자와 실무자들은 자신 만의 일회성 시스템을 구축하고 있습니다. 이러한 상황에서는 학습, 서비스 및 시뮬레이션을 효율적으로 지원할 수있는 RL을위한 새로운 분산 프레임 워크의 개발이 필요합니다. 특히 이러한 프레임 워크는 다음 요구 사항을 충족해야합니다. 세분화 된 이기종 계산. 계산 기간은 밀리 초 (예 : 조치 수행)에서 몇 시간 (예 : 복잡한 정책 훈련)까지 다양합니다.


또한 학습에는 종종 이기종 하드웨어 (예 : CPU, GPU 또는 TPU)가 필요합니다. 유연한 계산 모델. RL 애플리케이션에는 상태 비 저장 및 상태 저장 계산이 모두 필요합니다. 상태 비 저장 컴퓨팅은 시스템의 모든 노드에서 실행될 수 있으므로 필요한 경우로드 밸런싱 및 데이터로의 계산 이동을 쉽게 수행 할 수 있습니다. 따라서 상태 비 저장 컴퓨팅은 이미지 또는 비디오에서 특징 추출과 같은 세분화 된 시뮬레이션 및 데이터 처리에 적합합니다. 대조적으로 상태 저장 계산은 매개 변수 서버를 구현하거나 GPU 지원 데이터에서 반복 계산을 수행하거나 상태를 노출하지 않는 타사 시뮬레이터를 실행하는 데 적합합니다. 동적 실행. 계산이 끝나는 순서 (예 : 시뮬레이션이 끝나는 순서)가 항상 미리 알려지지는 않고 계산 결과가 미래의 계산 (예 : 시뮬레이션은 더 많은 시뮬레이션을 수행해야하는지 여부를 결정합니다.) 우리는 두 가지 마지막 코멘트를합니다. 


첫째, 대규모 클러스터에서 높은 활용도를 달성하려면 이러한 프레임 워크가 초당 수백만 개의 작업을 처리해야합니다. * 

둘째, 이러한 프레임 워크는 심층 신경망이나 복잡한 시뮬레이터를 처음부터 구현하기위한 것이 아닙니다. 대신 기존 시뮬레이터 및 딥 러닝 프레임 워크와 원활하게 통합 할 수 있어야합니다.


Serving은 훈련 된 정책을 사용하여 환경의 현재 상태에 따라 작업을 렌더링합니다. 서빙 시스템은 지연 시간을 최소화하고 초당 결정 수를 최대화하는 것을 목표로합니다. 확장을 위해로드는 일반적으로 정책을 제공하는 여러 노드에서 균형을 이룹니다. 마지막으로, 대부분의 기존 RL 애플리케이션은 시뮬레이션을 사용하여 정책을 평가합니다. 현재 RL 알고리즘은 실제 세계와의 상호 작용에서 얻은 데이터에만 의존 할만큼 충분히 샘플 효율적이지 않습니다. 이러한 시뮬레이션은 복잡도가 매우 다양합니다. 몇 ms (예 : 체스 게임에서 움직임 시뮬레이션)에서 몇 분 (예 : 자율 주행 자동차의 현실적인 환경 시뮬레이션)이 소요될 수 있습니다. 학습 및 서빙을 서로 다른 시스템에서 개별적으로 처리 할 수있는지도 학습과는 달리 RL에서는 이러한 세 가지 워크로드가 모두 단일 애플리케이션에서 긴밀하게 결합되어 있으며 이들간에 엄격한 지연 시간이 요구됩니다. 현재는 이러한 워크로드 커플 링을 지원하는 프레임 워크가 없습니다. 이론적으로는 여러 특수 프레임 워크를 결합하여 전체 기능을 제공 할 수 있지만 실제로는 RL의 맥락에서 시스템 간의 결과 데이터 이동 및 대기 시간이 엄청납니다. 결과적으로 연구자와 실무자들은 자신의 일회성 시스템을 구축하고 있습니다. 이러한 상황에서는 학습, 서비스 및 시뮬레이션을 효율적으로 지원할 수있는 RL을위한 새로운 분산 프레임 워크의 개발이 필요합니다. 특히 이러한 프레임 워크는 다음 요구 사항을 충족해야합니다. 세분화 된 이기종 계산. 계산 기간은 밀리 초 (예 : 조치 수행)에서 몇 시간 (예 : 복잡한 정책 학습)까지 다양합니다.


또한 학습에는 종종 이기종 하드웨어 (예 : CPU, GPU 또는 TPU)가 필요합니다. 유연한 계산 모델. RL 애플리케이션에는 상태 비 저장(stateless) 및 상태 저장(stateful) 계산이 모두 필요합니다. 상태 비 저장 계산은 시스템의 모든 노드에서 실행될 수 있으므로 필요한 경우로드 밸런싱 및 계산을 데이터로 쉽게 이동할 수 있습니다. 따라서 상태 비 저장 계산은 이미지 또는 비디오에서 특징 추출과 같은 세분화 된 시뮬레이션 및 데이터 처리에 적합합니다. 대조적으로 상태 저장 계산은 매개 변수 서버를 구현하거나 GPU 지원 데이터에서 반복 계산을 수행하거나 상태를 노출하지 않는 타사 시뮬레이터를 실행하는 데 적합합니다. 동적 실행. 계산이 끝나는 순서 (예 : 시뮬레이션이 끝나는 순서)가 항상 미리 알려지지는 않고 계산 결과가 미래의 계산 (예 : 시뮬레이션은 더 많은 시뮬레이션을 수행해야하는지 여부를 결정합니다.) 우리는 두 가지 마지막 코멘트를합니다. 첫째, 대규모 클러스터에서 높은 활용도를 달성하려면 이러한 프레임 워크가 초당 수백만 개의 작업을 처리해야합니다. * 둘째, 이러한 프레임 워크는 심층 신경망이나 복잡한 시뮬레이터를 처음부터 구현하기위한 것이 아닙니다. 대신 기존 시뮬레이터 [13, 11, 59] 및 딥 러닝 프레임 워크와 원활하게 통합 할 수 있어야합니다.



1) features = f.remote(args)

원격으로 기능 f를 실행합니다. f.remote ()는 객체 또는 퓨처를 입력으로 취하고 하나 이상의 퓨처를 반환 할 수 있습니다. 이것은 비 블록킹(non-blocking)입니다.


2) objects = ray.get(futures)

하나 이상의 future와 관련된 리턴 값을 반환합니다. 이것은 블록킹(blocking)입니다.


3) ready futures = ray.wait(futures,k, timeout)

k가 완료되거나 시간 초과가 만료되는 즉시 해당 작업이 완료된 Future를 반환합니다.


4) actor = Class.remote(args)

futures = actor.method.remote(args)

Class를 원격 액터로 인스턴스화하고 핸들을 반환합니다. 원격 액터(remote actor)에서 메서드를 호출하고 하나 이상의 퓨처를 반환합니다. 둘 다 논블록킹(non-blocking)입니다.



3 프로그래밍 및 계산 모델


Ray는 동적 작업 그래프 계산 모델을 구현합니다. 즉, 애플리케이션을 실행 중에 진화하는 종속 작업의 그래프로 모델링합니다. 이 모델 위에 레이는 액터와 작업 병렬 프로그래밍 추상화를 모두 제공합니다. 이러한 통합은 Ray를 작업 병렬 추상화 만 제공하는 CIEL과 같은 관련 시스템과 주로 액터 추상화를 제공하는 Orleans [14] 또는 Akka [1]와 구별합니다.


3.1 프로그래밍 모델


Task: Task는 stateless worker의 원격 기능 상의 실행을 나타냅니다. 원격 함수가 호출되면 작업 결과를 나타내는 future가 즉시 반환됩니다. 퓨처는 ray.get()을 사용하여 검색 할 수 있으며 결과를 기다리지 않고 다른 원격 함수에 인수로 전달할 수 있습니다. 이를 통해 사용자는 데이터 종속성을 캡처하는 동안 병렬 처리를 표현할 수 있습니다. 표 1은 Ray의 API를 보여줍니다. 


원격 함수는 변경 불가능한 객체에서 작동하며 상태 비 저장 및 부작용이 없을 것으로 예상됩니다. 출력은 입력에 의해서만 결정됩니다. 이는 장애시 기능 재실행을 통해 내결함성을 단순화하는 멱 등성을 의미합니다. 


Actor: Actor는 상태 저장 계산을 나타냅니다. 각 액터는 원격으로 호출 할 수 있고 직렬로 실행되는 메서드를 노출합니다. 메서드 실행은 원격으로 실행되고 future를 반환한다는 점에서 작업과 비슷하지만 상태 저장 작업자에서 실행된다는 점에서 다릅니다. 액터에 대한 핸들은 다른 액터 나 작업에 전달 될 수 있으므로 해당 Actor에서 메서드를 호출 할 수 있습니다.

표2: Task vs Actor 트레이드오프

표 2는 Task과 Actor의 속성을 요약 한 것입니다.


작업은 작업 세분성, 입력 데이터 지역성에서로드 인식 스케줄링을 활용하여 세분화 된로드 밸런싱을 지원합니다. 각 작업은 입력을 저장하는 노드에서 예약 할 수 있으며, 중간 상태를 검사하고 복구 할 필요가 없으므로 복구 오버 헤드가 낮습니다. 반대로, Actor는 일반적으로 직렬화 및 역 직렬화가 필요한 외부 상태가 아닌 내부 상태에서 수행되므로 훨씬 더 효율적인 세분화 된 업데이트를 제공합니다. 예를 들어, Actor는 매개 변수 서버 [32] 및 GPU 기반 반복 계산 (예 : 훈련)을 구현하는 데 사용할 수 있습니다. 또한 액터를 사용하여 직렬화하기 어려운 타사 시뮬레이터 및 기타 불투명 핸들을 래핑 할 수 있습니다. 이질성 및 유연성에 대한 요구 사항을 충족하기 위해 가능성 (섹션 2), API를 세 가지 방식으로 확장합니다. 먼저, 이기종 기간의 동시 작업을 처리하기 위해 ray.get ()과 같은 모든 결과를 기다리는 대신 처음 k 개의 사용 가능한 결과를 기다리는 ray.wait ()를 도입합니다. 둘째, 리소스가 다른 작업을 처리하기 위해 개발자가 리소스 요구 사항을 지정하여 Ray 스케줄러가 리소스를 효율적으로 관리 할 수 있도록합니다. 셋째, 유연성을 높이기 위해 중첩 된 원격 기능을 활성화합니다. 즉, 원격 기능이 다른 원격 기능을 호출 할 수 있습니다. 이는 또한 여러 프로세스가 분산 된 방식으로 원격 기능을 호출 할 수 있도록하므로 높은 확장 성 (섹션 4)을 달성하는 데 중요합니다.


3.2 계산 모델
(Computation Model)


Ray는 동적 작업 그래프 계산 모델 [21]을 사용합니다. 여기서 원격 기능과 Actor 방법의 실행은 입력이 사용 가능 해지면 시스템에 의해 자동으로 트리거됩니다. 이 섹션에서는 사용자 프로그램 (그림 3)에서 계산 그래프 (그림 4)를 구성하는 방법을 설명합니다. 이 프로그램은 표 1의 API를 사용하여 그림 2의 의사 코드를 구현합니다. 먼저 Actor를 무시하면 두 가지 유형의 노드가 있습니다.


계산 그래프 : 데이터 개체 및 원격 함수 호출 또는 작업. 또한 두 가지 유형의 간선, 데이터 간선 및 제어 간선이 있습니다. 데이터 에지는 데이터 개체와 작업 간의 종속성을 캡처합니다. 보다 정확하게는 데이터 객체 D가 작업 T의 출력이면 T에서 D까지 데이터 에지를 추가합니다. 마찬가지로 D가 T에 대한 입력이면 D에서 T까지 데이터 에지를 추가합니다. 제어 에지는 계산 종속성을 캡처합니다. 중첩 된 원격 기능의 결과 (3.1 절) : 작업 T1이 작업 T2를 호출하면 T1에서 T2로 제어 에지를 추가합니다. 액터 메서드 호출도 노드로 표시됩니다.


계산 그래프에서. 한 가지 중요한 차이점이있는 작업과 동일합니다. 동일한 액터에 대한 후속 메서드 호출에서 상태 종속성을 캡처하기 위해 세 번째 유형의 에지 인 상태 저장 에지를 추가합니다. 동일한 액터에서 메서드 Mi 바로 다음에 메서드 Mj가 호출되면 Mi에서 Mj로 상태 저장 에지를 추가합니다. 따라서 동일한 액터 객체에서 호출 된 모든 메서드는 상태 저장 에지로 연결된 체인을 형성합니다 (그림 4). 이 체인은 이러한 메서드가 호출 된 순서를 캡처합니다. 상태 저장 에지는 액터의 내부 상태를 공유하는 연속적인 메서드 호출 간의 암시 적 데이터 종속성을 캡처하므로 상태 비 저장 작업 그래프에 액터를 포함하는 데 도움이됩니다. Stateful Edge는 또한 우리가 계보를 유지할 수 있도록합니다. 다른 데이터 흐름 시스템 [64]과 마찬가지로 데이터 계보를 추적하여 재구성을 가능하게합니다. 계보 그래프에 상태 저장 에지를 명시 적으로 포함하면 원격 함수 또는 Actor 메서드 (섹션 4.2.3)에 의해 생성 된 손실 된 데이터를 쉽게 재구성 할 수 있습니다.


4 아키텍쳐
(Architecture)


Ray의 아키텍처는 (1) API를 구현하는 애플리케이션 계층과 (2) 높은 확장 성과 내결함성을 제공하는 시스템 계층으로 구성됩니다.


4.1 어플리케에션 레이어
(Application Layer)


Ray의 아키텍처는 (1) API를 구현하는 애플리케이션 계층과 

(2) 높은 확장 성과 내결함성을 제공하는 시스템 계층으로 구성됩니다.


애플리케이션 레이어는 세 가지 유형의 프로세스로 구성됩니다.


• Driver : 사용자 프로그램을 실행하는 프로세스.


• Worker : 드라이버 또는 다른 작업자가 호출 한 작업 (원격 기능)을 실행하는 상태 비 저장 프로세스입니다. 작업자는 자동으로 시작되고 시스템 계층에서 작업을 할당합니다. 원격 함수가 선언되면 함수가 모든 작업자에게 자동으로 게시됩니다. 작업자는 작업 전체에 로컬 상태가 유지되지 않고 작업을 순차적으로 실행합니다.


• Actor : 호출 될 때 노출 된 메서드 만 실행하는 상태 저장 프로세스입니다. 작업자와 달리 액터는 작업자 또는 드라이버에 의해 명시 적으로 인스턴스화됩니다. 작업자와 마찬가지로 액터는 각 메서드가 이전 메서드 실행으로 인한 상태에 의존한다는 점을 제외하면 메서드를 직렬로 실행합니다.


4.2 시스템 레이어
(System Layer)


4.2.1 글로벌 컨트롤 스토어
(Global Control Store, GCS)

그림5: Ray의 아키텍처는 애플리케이션 레이어와 시스템 레이어의 두 부분으로 구성됩니다.


GCS (Global Control Store)는 시스템의 전체 제어 상태를 유지하며 본 시스템 설계의 고유 한 기능입니다. 핵심에서 GCS는 pub-sub 기능이있는 키-값 저장소(Key-Value Store)입니다. 확장을 위해 샤딩을 사용하고 내결함성을 제공하기 위해 샤드 당 복제(Replication)를 사용합니다. GCS와 그 설계의 주된 이유는 초당 수백만 개의 작업을 동적으로 생성 할 수있는 시스템의 내결함성과 낮은 대기 시간을 유지하는 것입니다. 노드 장애시 내결함성은 계보 정보를 유지하는 솔루션이 필요합니다. 기존 계보 기반 솔루션은 대략적인 병렬 처리에 초점을 맞추고 있으므로 단일 노드 (예 : 마스터, 드라이버)를 사용하여 성능에 영향을주지 않고 계보를 저장할 수 있습니다. 그러나이 디자인은 시뮬레이션과 같은 세분화되고 동적 워크로드에 맞게 확장 할 수 없습니다. 따라서 내구성있는 계보 저장소를 다른 시스템 구성 요소와 분리하여 각각 독립적으로 확장 할 수 있습니다. 낮은 대기 시간을 유지하려면 실행 위치를 선택하고 다른 노드에서 원격 입력을 검색하는 작업 디스패치를 포함하는 작업 스케줄링의 오버 헤드를 최소화해야합니다. 기존의 많은 데이터 흐름 시스템은 개체 위치와 크기를 중앙 집중식 스케줄러에 저장하여이를 결합합니다. 이는 스케줄러가 병목 현상이 아닌 경우 자연스러운 디자인입니다. 그러나 Ray가 목표로하는 규모와 세분성은 중앙 집중식 스케줄러를 중요 경로에서 벗어나도록 유지해야합니다. 각 객체 전송에 스케줄러를 포함하는 것은 통신 집약적이고 지연 시간에 민감한 all reduce와 같이 분산 학습에 중요한 기본 요소에 대해 엄청나게 많은 비용이 듭니다. 따라서 스케줄러가 아닌 GCS에 객체 메타 데이터를 저장하여 작업 예약에서 작업 디스 커플 링을 완전히 분리합니다. 


요약하면 GCS는 Ray의 시스템의 모든 구성 요소가 상태 비 저장이 될 수 있기 때문에 전체적인 설계가 가능합니다. 이는 내결함성에 대한 지원을 단순화 할뿐만 아니라 (예 : 장애 발생시 구성 요소가 단순히 다시 시작되고 GCS에서 계보를 읽음) 모든 구성 요소가 다음을 통해 필요한 상태를 공유하므로 분산 된 개체 저장소 및 스케줄러를 독립적으로 확장 할 수 있습니다. GCS. 추가적인 이점은 디버깅, 프로파일 링 및 시각화 도구를 쉽게 개발할 수 있다는 것입니다.


4.2.2 Bottom-Up 분산 스케쥴러
(Bottom-Up Distributed Scheduler)

그림 6: 상향식 분산 스케줄러. 작업은 드라이버와 작업자에서 로컬 스케줄러로 상향식으로 제출되고 필요한 경우에만 글로벌 스케줄러로 전달됩니다.

섹션 2에서 설명했듯이 Ray는 초당 수백만 개의 작업을 동적으로 예약해야합니다. 작업은 몇 밀리 초 정도 걸릴 수 있습니다. 우리가 알고있는 클러스터 스케줄러는 이러한 요구 사항을 충족하지 않습니다. Spark [64], CIEL [40], Dryad [28]와 같은 대부분의 클러스터 컴퓨팅 프레임 워크는 집중식 스케줄러를 구현합니다.이 스케줄러는 지역성을 제공 할 수 있지만 대기 시간은 수십 ms입니다. 작업 도용 [12], Sparrow [45] 및 Canary [47]와 같은 분산 스케줄러는 높은 규모를 달성 할 수 있지만 데이터 지역성을 고려하지 않거나 [12] 작업이 독립적 인 작업에 속한다고 가정하거나 계산 그래프는 알려져있다 [47]. 위의 요구 사항을 충족하기 위해 두 개의

글로벌 스케줄러 및 노드 별 로컬 스케줄러로 구성된 레벨 계층 적 스케줄러. 글로벌 스케줄러의 과부하를 방지하기 위해 노드에서 생성 된 작업은 먼저 노드의 로컬 스케줄러에 제출됩니다. 로컬 스케줄러는 노드가 오버로드되거나 (예 : 로컬 작업 대기열이 사전 정의 된 임계 값을 초과하는 경우) 작업의 요구 사항을 충족 할 수없는 경우 (예 : GPU 부족)가 아니면 로컬로 작업을 예약합니다. 로컬 스케줄러가 작업을 로컬로 예약하지 않기로 결정하면 작업을 글로벌 스케줄러로 전달합니다. 이 스케줄러는 먼저 로컬에서 (즉, 스케줄링 계층 구조의 잎에서) 작업을 예약하려고하기 때문에 상향식 스케줄러라고합니다.


글로벌 스케줄러는 결정을 내리기 위해 각 노드의 로드와 task의 제약을 고려합니다. 보다 정확하게는 글로벌 스케줄러는 작업에서 요청한 유형의 리소스가 충분한 노드 집합을 식별하고 이러한 노드 중 가장 낮은 예상 대기 시간을 제공하는 노드를 선택합니다. 주어진 노드에서이 시간은 (i) 해당 노드에서 작업이 대기열에 추가 될 것으로 예상되는 시간 (즉, 작업 대기열 크기에 평균 작업 실행을 곱한 값) 및 (ii) 작업 원격의 예상 전송 시간의 합계입니다. 입력 (즉, 원격 입력의 총 크기를 평균 대역폭으로 나눈 값). 글로벌 스케줄러는 각 노드의 대기열 크기와 하트 비트를 통해 노드 리소스 가용성, 작업 입력 위치 및 GCS의 크기를 가져옵니다. 또한 글로벌 스케줄러는 간단한 지수 평균을 사용하여 평균 작업 실행과 평균 전송 대역폭을 계산합니다. 글로벌 스케줄러가 병목 상태가되면 GCS를 통해 동일한 정보를 공유하는 더 많은 복제본을 인스턴스화 할 수 있습니다. 이것은 우리의 스케줄러 아키텍처를 매우 확장 가능하게 만듭니다.


4.2.3 인메모리 분산 오브젝트 스토어
(In-Memory Distributed Object Store)


작업 대기 시간을 최소화하기 위해 모든 작업의 입력 및 출력 또는 상태 비 저장 계산을 저장하는 인 메모리 분산 스토리지 시스템을 구현합니다. 각 노드에서 공유 메모리를 통해 객체 저장소를 구현합니다. 이를 통해 동일한 노드에서 실행되는 작업간에 제로 복사 데이터 공유가 가능합니다. 데이터 형식으로 Apache Arrow [2]를 사용합니다. 작업의 입력이 로컬이 아닌 경우 입력은 실행 전에 로컬 객체 저장소에 복제됩니다. 또한 태스크는 로컬 오브젝트 저장소에 출력을 기록합니다. 복제는 핫 데이터 개체로 인한 잠재적 병목 현상을 제거하고 작업이 로컬 메모리에서 데이터를 읽고 쓰기 만하므로 작업 실행 시간을 최소화합니다. 이렇게하면 많은 AI 애플리케이션에서 공유하는 프로필 인 계산 바운드 워크로드의 처리량이 증가합니다. 짧은 대기 시간을 위해 우리는 객체를 메모리에 전적으로 보관하고 LRU 정책을 사용하여 필요에 따라 디스크로 제거합니다. Spark [64] 및 Dryad [28]와 같은 기존 클러스터 컴퓨팅 프레임 워크와 마찬가지로 객체 저장소는 변경 불가능한 데이터로 제한됩니다. 이렇게하면 개체가 업데이트되지 않으므로 복잡한 일관성 프로토콜이 필요하지 않고 내결함성 지원이 간소화됩니다. 노드 장애가 발생한 경우 Ray는 계보 재실행을 통해 필요한 모든 개체를 복구합니다. GCS에 저장된 계보는 초기 실행 중에 상태 비 저장 작업과 상태 저장 Actor를 모두 추적합니다. 전자를 사용하여 상점의 개체를 재구성합니다. 단순성을 위해 우리의 객체 저장소는 분산 객체를 지원하지 않습니다. 즉, 각 객체는 단일 노드에 맞습니다. 대형 행렬이나 트리와 같은 분산 된 객체는 미래의 컬렉션으로 애플리케이션 수준에서 구현 될 수 있습니다.


4.2.4 구현
(Implementation)


Ray는 University of California, Berkeley에서 개발 한 활성 오픈 소스 프로젝트 †입니다. Ray는 Python 환경과 완전히 통합되며 pip install ray를 실행하여 쉽게 설치할 수 있습니다. 구현은 ≈ 40K 라인의 코드 (LoC), 시스템 계층의 경우 C ++에서 72 %, 애플리케이션 계층의 경우 Python에서 28 %로 구성됩니다. GCS는 샤드 당 하나의 Redis [50] 키-값 저장소를 사용하며 완전히 단일 키 작업을 수행합니다. GCS 테이블은 확장을 위해 개체 및 작업 ID별로 분할되며 모든 분할은 내결함성을 위해 체인 복제됩니다 [61]. 로컬 및 글로벌 스케줄러를 이벤트 중심의 단일 스레드 프로세스로 구현합니다. 내부적으로 로컬 스케줄러는 로컬 개체 메타 데이터, 입력 대기중인 작업 및 작업자에게 발송할 준비가 된 작업에 대해 캐시 된 상태를 유지합니다. 서로 다른 개체 저장소간에 큰 개체를 전송하기 위해 여러 TCP 연결에 개체를 스트라이프합니다.


4.3 모든 것을 하나로 합치기
(Putting Everything Together)


그림 7. 


그림 7은 스칼라 또는 행렬 일 수있는 두 개의 객체 a와 b를 추가하고 결과 c를 반환하는 간단한 예제를 통해 Ray가 종단 간 작동하는 방식을 보여줍니다. 


그림 7a는 add.remote (a, b)를 호출하는 드라이버에 의해 트리거되는 단계별 작업을 보여줍니다.

단계 0) 원격 함수 add ()는 초기화시 GCS에 자동으로 등록되고 시스템의 모든 작업자에게 배포됩니다 (그림 7a의 단계 0). 

단계 1,2) 여기서 a와 b는 각각 노드 N1과 N2에 저장됩니다. 드라이버는 add (a, b)를 로컬 스케줄러 (1 단계)에 제출하여 글로벌 스케줄러로 전달합니다 (2 단계). 

단계 3,4) 다음으로 글로벌 스케줄러는 add (a, b)의 인수 위치를 조회합니다. GCS (3 단계)에서 인수 b를 저장하는 노드 N2에서 작업을 예약하기로 결정합니다 (4 단계). 

단계 5, 6) 노드 N2의 로컬 스케줄러는 로컬 객체 저장소에 add (a, b)의 인수가 포함되어 있는지 확인합니다 (5 단계). 지역 상점에는 객체 a가 없으므로 GCS에서 a의 위치를 조회합니다 (6 단계). 

단계 7) a가 N1에 저장되었음을 알게되면 N2의 객체 저장소는이를 로컬로 복제합니다 (7 단계). 

단계 8,9) 이제 add ()의 모든 인수가 로컬에 저장되므로 로컬 스케줄러는 공유 메모리 (9 단계)를 통해 인수에 액세스하는 로컬 작업자 (8 단계)에서 add ()를 호출합니다. 


그림 7b는 N1에서 ray.get ()을 실행하고 N2에서 add ()를 실행하여 트리거되는 단계별 작업을 각각 보여줍니다. 

단계 1) ray.get (idc)가 호출되면 드라이버는 add ()에서 반환 된 미래의 idc를 사용하여 값 c에 대해 로컬 객체 저장소를 확인합니다 (1 단계). 

단계 2) 로컬 객체 저장소는 c를 저장하지 않으므로 GCS에서 해당 위치를 찾습니다. 이때 c가 아직 생성되지 않았으므로 c에 대한 항목이 없습니다. 결과적으로 N1의 객체 저장소는 c의 항목이 생성 될 때 트리거 될 객체 테이블에 콜백을 등록합니다 (2 단계). 

단계 3) 한편, N2에서 add ()는 실행을 완료하고 결과 c를 로컬 객체 저장소에 저장합니다 (3 단계). 

단계 4) 그러면 c의 항목이 GCS에 추가됩니다 (4 단계). 

단계 5) 결과적으로 GCS는 c의 항목을 사용하여 N1의 객체 저장소에 대한 콜백을 트리거합니다 (5 단계). 

단계 6,7) 다음으로 N1은 N2에서 c를 복제하고 (6 단계), c를 ray.get () (7 단계)으로 반환하여 마지막으로 작업을 완료합니다.


이 예제는 많은 수의 RPC를 포함하지만 대부분의 작업이 로컬로 예약되고 GCS 응답이 글로벌 및 로컬 스케줄러에 의해 캐시되므로 많은 경우에 10-1 개가 훨씬 더 적습니다.



5 평가(Evaluation)


평가에서 우리는 다음 질문을 연구합니다.

1. Ray는 섹션 2에 나열된 지연 시간, 확장 성 및 내결함성 요구 사항을 얼마나 잘 충족합니까? (섹션 5.1)

2. Ray의 API를 사용하여 작성된 분산 프리미티브 (예 : 모두 감소)에 어떤 오버 헤드가 부과됩니까? (섹션 5.1)

3. RL 워크로드의 맥락에서 Ray는 학습, 서빙 및 시뮬레이션을 위한 특수 시스템과 어떻게 비교됩니까? (섹션 5.2)

4. 사용자 지정 시스템과 비교하여 Ray가 RL 응용 프로그램에 제공하는 이점은 무엇입니까? (섹션 5.3) 


모든 실험은 Amazon Web Services에서 실행되었습니다.

달리 명시되지 않는 한 m4.16xlarge CPU 인스턴스 및 p3.16xlarge GPU 인스턴스를 사용합니다.


5.1 Microbenchmarks


지역 인식 작업 배치(Locality-aware task placement): 세밀한로드 밸런싱 및 지역성 인식 배치는 Ray 작업의 주요 이점입니다. 일단 배치 된 액터는 자신의 계산을 큰 원격 오브젝트로 이동할 수 없지만 태스크는 할 수 있습니다. 그림 8a에서 데이터 지역성 인식없이 배치 된 작업 (액터 메서드의 경우와 마찬가지로)은 10-100MB 입력 데이터 크기에서 지연 시간이 1-2 배 증가합니다. Ray는 공유 객체 저장소를 통해 작업과 Actor를 통합하여 개발자가 시뮬레이션 Actor가 생성 한 출력에 대해 값 비싼 후 처리 작업을 사용할 수 있도록합니다. 


종단 간 확장 성(End-to-end scalability): GCS (Global Control Store) 및 상향식 분산 스케줄러의 주요 이점 중 하나는 내결함성과 지연 시간이 짧은 작업을 유지하면서 세분화 된 작업의 높은 처리량을 지원하도록 시스템을 수평 적으로 확장 할 수 있다는 것입니다. 일정. 그림 8b에서 우리는 빈 작업의 당황 스러울 정도로 병렬 작업 부하에서이 기능을 평가하여 x 축에서 클러스터 크기를 증가시킵니다. 점진적으로 증가하는 작업 처리량에서 거의 완벽한 선형성을 관찰합니다. Ray는 60 개의 노드에서 초당 1 백만 개의 작업 처리량을 초과하고 100 개의 노드에서 초당 180 만 개의 작업을 초과하여 선형 적으로 계속 확장됩니다. 가장 오른쪽의 데이터 포인트는 Ray가 최소 변동성으로 1 분 (54 초) 이내에 1 억 개의 작업을 처리 할 수 있음을 보여줍니다. 예상대로 작업 기간을 늘리면 평균 작업 기간에 비례하여 처리량이 줄어들지 만 전체적인 확장 성은 선형으로 유지됩니다. 많은 실제 워크로드는 개체 종속성과 응용 프로그램 병렬 처리에 대한 고유 한 제한으로 인해 확장 성이 더 제한 될 수 있지만 이는 높은 부하에서 전체 아키텍처의 확장 성을 보여줍니다.


개체 저장소 성능(Object store performance): 성능을 평가하려면 개체 저장소 (4.2.3 챕터)의 두 가지 메트릭 인 IOPS (작은 개체의 경우)와 쓰기 처리량 (대형 개체의 경우)을 추적합니다. 그림 9에서 단일 클라이언트의 쓰기 처리량은 개체 크기가 증가함에 따라 15GB / s를 초과합니다. 더 큰 객체의 경우 memcpy가 객체 생성 시간을 지배합니다. 작은 개체의 경우 주요 오버 헤드는 클라이언트와 개체 저장소     사이의 서비스 및 IPC에 있습니다.


GCS 내결함성(GCS fault tolerance): 낮은 대기 시간을 유지하려면 강력한 일관성과 내결함성을 제공하여 Redis 위에 경량 체인 복제 [61] 계층을 구축합니다. 그림 10a는 Ray 작업을 GCS에 기록하고 GCS에서 작업을 읽는 것을 시뮬레이션합니다. 여기서 키는 25 바이트이고 값은 512 바이트입니다. 클라이언트는 한 번에 최대 하나의 진행중인 요청을 가지고 최대한 빨리 요청을 보냅니다. 실패는 클라이언트 (명시 적 오류 수신 또는 재 시도에도 불구하고 시간 초과) 또는 체인의 모든 서버 (명시 적 오류 수신)에서 체인 마스터에보고됩니다. 전반적으로 재구성으로 인해 클라이언트가 관찰 한 최대 지연 시간은 30ms 미만이었습니다 (여기에는 오류 감지 및 복구 지연 모두 포함).


GCS 플러싱(GCS flushing): 레이는 주기적으로 플러시하도록 장비됩니다. GCS의 내용을 디스크에 저장합니다. 그림 10b에서는 5 천만 개의 빈 작업을 순차적으로 제출하고 GCS 메모리 소비를 모니터링합니다. 예상대로 추적되는 작업 수에 따라 선형 적으로 증가하고 결국 시스템의 메모리 용량에 도달합니다. 이 시점에서 시스템이 중단되고 워크로드가 합리적인 시간 내에 완료되지 않습니다. 주기적인 GCS 플러싱을 통해 두 가지 목표를 달성합니다. 첫째, 메모리 풋 프린트는 사용자가 구성 할 수있는 수준으로 제한됩니다 (마이크로 벤치 마크에서는 소비 된 메모리를 가능한 한 낮게 유지하는 공격적인 전략을 사용합니다). 둘째, 플러싱 메커니즘은 장기간 실행되는 Ray 애플리케이션을 위해 디스크에 대한 계보를 스냅 샷하는 자연스러운 방법을 제공합니다.


작업 실패에서 복구(Recovering from task failures): 그림 11a에서는 내구성있는 GCS 계보 스토리지를 사용하여 작업자 노드 장애로부터 투명하게 복구하고 탄력적으로 확장 할 수있는 Ray의 능력을 보여줍니다. m4.xlarge 인스턴스에서 실행되는 워크로드는 드라이버가 제출 한 100ms 작업의 선형 체인으로 구성됩니다. 노드가 제거되면 (25 초, 50 초, 100 초) 로컬 스케줄러는 실행을 계속하기 위해 체인에서 이전 결과를 재구성합니다. 전체 노드 당 처리량은 전체적으로 안정적입니다. 


그림 11 : Ray 결함 허용. (a) Ray는 노드가 제거됨에 따라 손실 된 작업 종속성을 재구성합니다. (b) 액터는 마지막 체크 포인트에서 재구성됩니다.


액터 실패에서 복구(Recovering from actor failures): 액터 메서드 호출을 종속성 그래프에서 직접 상태 저장 에지로 인코딩함으로써 그림 11a에서와 동일한 객체 재구성 메커니즘을 재사용하여 상태 저장 계산을위한 투명한 내결함성을 제공 할 수 있습니다. Ray는 추가적으로 사용자 정의 체크 포인트 기능을 활용하여 액터의 재구성 시간을 제한합니다 (그림 11b). 최소한의 오버 헤드로 체크 포인트를 사용하면 500 개의 메소드 만 재실행 할 수 있지만 체크 포인트없이 10k 재실행 할 수 있습니다. 향후에는 사용자가 상태를 변경하지 않는 메소드에 주석을 달 수 있도록하는 등 Actor 재구성 시간을 더욱 단축 할 수 있기를 바랍니다.


그림12: (a) 16m4.16xl 노드에서 allreduce의 평균 실행 시간 (b) Ray의 저 지연 스케줄링은 allreduce에 매우 중요합니다.


올리듀스(All Reduce): Allreduce는 많은 기계 학습 워크로드에 중요한 분산 통신 기본 요소입니다. 여기서 우리는 Ray가 기존 구현과 일치 할만큼 충분히 낮은 오버 헤드로 ring allreduce [57] 구현을 기본적으로 지원할 수 있는지 평가합니다 [53]. Ray는 100MB의 16 개 노드에서 ~ 200ms에서 1GB에서 ~ 1200ms에서 모두 감소를 완료하여 널리 사용되는 MPI 구현 인 OpenMPI (v1.10)보다 각각 1.5 배 및 2 배 뛰어난 성능을 보입니다 (그림 12a). 우리는 Ray의 성능을 네트워크 전송을 위해 다중 스레드를 사용하여 AWS에서 노드 간 25Gbps 연결을 최대한 활용하는 반면 OpenMPI는 단일 스레드에서 데이터를 순차적으로 송수신합니다 [22]. 더 작은 개체의 경우 OpenMPI는 향후 구현할 최적화 인 더 낮은 오버 헤드 알고리즘으로 전환하여 Ray를 능가합니다. Ray의 스케줄러 성능은 allreduce와 같은 기본 요소를 구현하는 데 매우 중요합니다. 그림 12b에서는 인위적인 작업 실행 지연을 주입하고 몇 ms의 추가 지연 시간으로 성능이 거의 2 배 감소하는 것을 보여줍니다. Spark 및 CIEL과 같은 중앙 집중식 스케줄러가있는 시스템은 일반적으로 수십 밀리 초 [62, 38]의 스케줄러 오버 헤드를 가지므로 이러한 워크로드는 비실용적입니다. 링에 필요한 작업 수가 참가자 수에 따라 2 차적으로 축소되기 때문에 스케줄러 처리량도 병목 현상이됩니다.


5.2 빌딩 블록

그림13: ResNet-101 TensorFlow 모델 학습 배포시 도달 한 초당 이미지

엔드-투-엔드 애플리케이션 (예 : AlphaGo [54])에는 훈련, 서빙 및 시뮬레이션의 긴밀한 결합이 필요합니다. 이 섹션에서는 이러한 각 워크로드를 일반적인 RL 애플리케이션의 요구 사항을 보여주는 설정으로 격리합니다. RL을 대상으로하는 유연한 프로그래밍 모델과이 프로그래밍 모델을 지원하도록 설계된 시스템으로 인해 Ray는 이러한 개별 워크로드에 대해 전용 시스템의 성능과 일치하며 때로는이를 능가합니다.


5.2.1 분산 학습 (Distributed Learning)


모델 복제본을 표현하기 위해 Ray Actor 추상화를 활용하는 데이터 병렬 동기 SGD를 구현합니다. 모델 가중치는 allreduce (5.1) 또는 매개 변수 서버를 통해 동기화되며 둘 다 Ray API 위에 구현됩니다. 그림 13에서 우리는 각 실험에 대해 동일한 TensorFlow 모델과 합성 데이터 생성기를 사용하는 최첨단 구현에 대한 Ray (동기) 매개 변수-서버 SGD 구현 [53]. 우리는 딥 러닝 프레임 워크 자체의 차이보다는 Ray가 부과하는 오버 헤드를 정확하게 측정하기 위해 TensorFlow 기반 시스템과 만 비교합니다. 각 반복에서 모델 복제 액터는 그라디언트를 병렬로 계산하고, 그라디언트를 분할 된 매개 변수 서버로 보낸 다음, 다음 반복을 위해 매개 변수 서버에서 합산 된 그라디언트를 읽습니다. 그림 13은 Ray가 Horovod이며 분산 형 TensorFlow의 10 % 이내입니다 (분산 복제 모드에서). 이는 Ray의 범용 API에서 이러한 특수 시스템에서 볼 수있는 것과 동일한 애플리케이션 수준 최적화를 표현할 수있는 능력 때문입니다. 핵심 최적화는 단일 반복 내에서 점진적 계산, 전송 및 합산을 파이프 라이닝하는 것입니다. GPU 계산을 네트워크 전송과 겹치기 위해 커스텀 TensorFlow 연산자를 사용하여 Ray의 객체 저장소에 직접 텐서를 작성합니다.


5.2.2 서빙 (Serving)


모델 제공은 종단 간 애플리케이션의 중요한 구성 요소입니다. Ray는 주로 동일한 동적 작업 그래프 (예 : Ray의 RL 애플리케이션 내)에서 실행되는 시뮬레이터에 모델을 내장하는 데 중점을 둡니다. 대조적으로, Clipper [19]와 같은 시스템은 외부 클라이언트에게 예측을 제공하는 데 중점을 둡니다. 이 설정에서 낮은 대기 시간은 높은 활용도를 달성하는 데 중요합니다. 이를 보여주기 위해 표 3에서 Ray 액터를 사용하여 정책을 제공하는 것과 REST를 통한 오픈 소스 Clipper 시스템을 사용하여 달성 한 서버 처리량을 비교합니다. 여기서 클라이언트와 서버 프로세스는 모두 동일한 시스템 (p3.8xlarge 인스턴스)에 함께 있습니다. 이것은 종종 RL 애플리케이션의 경우이지만 Clipper와 같은 시스템에서 처리하는 일반적인 웹 서비스 워크로드에는 해당되지 않습니다. 낮은 오버 헤드 직렬화 및 공유 메모리 추상화로 인해 Ray는 큰 입력을 받아들이고 사용 된 것과 유사한 더 비싼 잔여 네트워크 정책 모델에서 더 빠른 소규모 완전 연결 정책 모델에 대해 훨씬 더 높은 처리량을 달성합니다. AlphaGo Zero에서는 더 작은 입력이 필요합니다.


5.2.3 시뮬레이션 (Simulation)


RL에서 사용되는 시뮬레이터는 훈련이 포함 된 타이트한 루프로 인해 가능한 한 빨리 사용해야하는 가변 길이 ( "시간 단계")의 결과를 생성합니다. 작업 이질성 및 적시성 요구 사항으로 인해 BSP 스타일 시스템에서 시뮬레이션을 효율적으로 지원하기가 어렵습니다. 시연하기 위해 (1) 라운드 사이의 글로벌 장벽을 사용하여 3 라운드의 n 코어에서 3n 병렬 시뮬레이션 실행을 제출하는 MPI 구현을 (2) 동시에 수집하면서 동일한 3n 작업을 실행하는 Ray 프로그램과 비교합니다. 시뮬레이션 결과를 운전자에게 다시 보냅니다. 표 4는 두 시스템 모두 잘 확장되지만 Ray는 최대 1.8 배의 처리량을 달성합니다. 이는 세분화 된 시뮬레이션 작업의 결과를 동적으로 생성하고 수집 할 수있는 프로그래밍 모델에 동기를 부여합니다.


5.3 RL 애플리케이션
(RL Application)


훈련, 시뮬레이션 및 서빙 단계를 긴밀하게 결합 할 수있는 시스템이 없으면 오늘날 강화 학습 알고리즘은 예를 들어 다른 계산 구조를 필요로하는 최적화를 통합하기 어렵게 만드는 일회성 솔루션으로 구현됩니다. 또는 다른 아키텍처를 활용합니다. 결과적으로 Ray에서 두 가지 대표적인 강화 학습 응용 프로그램을 구현하면 이러한 알고리즘을 위해 특별히 구축 된 사용자 지정 시스템을 일치시키고 성능을 능가 할 수 있습니다. 주된 이유는 맞춤형 시스템으로 이식하는 데 상당한 엔지니어링 노력이 필요하지만 Ray의 동적 작업 그래프 실행 엔진에서 투명하게 지원되는 애플리케이션 수준의 최적화를 표현할 수있는 Ray의 프로그래밍 모델의 유연성 때문입니다.


5.3.1 진화 전략
(Evoluationary Strategy)


대규모 RL 워크로드에서 Ray를 평가하기 위해 우리는 진화 전략 (ES) 알고리즘을 구현하고 참조 구현 [49]과 비교합니다.이 알고리즘을 위해 특별히 구축 된 시스템은 메시징을 위해 Redis를 사용하고 데이터를위한 저수준 다중 처리 라이브러리를 사용합니다. - 나누는. 알고리즘은 주기적으로 새 정책을 작업자 풀에 브로드 캐스트하고 대략 10000 개의 작업 (각각 10 ~ 1000 개의 시뮬레이션 단계 수행)의 결과를 집계합니다. 그림 14a에서 볼 수 있듯이 Ray의 구현은 8192 개의 코어로 확장됩니다. 사용 가능한 코어를 두 배로 늘리면 평균 완료 시간이 1.6 배 빨라집니다. 반대로 특수 목적 시스템은 시스템의 작업이 애플리케이션 드라이버의 처리 용량을 초과하는 2048 개 코어에서 완료되지 않습니다. 이 문제를 방지하기 위해 Ray 구현은 액터의 집계 트리를 사용하여 중앙값 3.7 분에 도달합니다. 이는 가장 잘 게시 된 결과 (10 분)보다 두 배 이상 빠릅니다. Ray를 사용한 직렬 구현의 초기 병렬화는 코드 7 줄만 수정하면됩니다. 계층 적 집계를 통한 성능 향상은 중첩 된 작업 및 Actor에 대한 Ray의 지원을 통해 쉽게 실현할 수있었습니다. 대조적으로 참조 구현에는 작업자 간의 작업 및 데이터 통신을위한 프로토콜 전용 코드 수백 줄이 있었으며 계층 적 집계와 같은 최적화를 지원하려면 추가 엔지니어링이 필요했습니다.


5.3.2 Proximal Policy Optimization


우리는 Ray에서 Proximal Policy Optimization (PPO) [51]을 구현하고 OpenMPI 통신 프리미티브를 사용하는 고도로 최적화 된 참조 구현 [5]과 비교합니다. 이 알고리즘은 비동기 스 캐터 수집으로, 드라이버에게 롤아웃을 반환 할 때 시뮬레이션 액터에 새 작업이 할당됩니다. 작업은 320000 개의 시뮬레이션 단계가 수집 될 때까지 제출됩니다 (각 작업은 10 ~ 1000 개의 단계를 생성 함). 정책 업데이트는 배치 크기가 32768 인 SGD의 20 단계를 수행합니다.이 예의 모델 매개 변수는 약 350KB입니다. 이 실험은 p2.16xlarge (GPU) 및 m4.16xlarge (높은 CPU) 인스턴스를 사용하여 실행되었습니다. 그림 14b에서 볼 수 있듯이 Ray 구현은 GPU의 일부를 사용하면서 모든 실험에서 최적화 된 MPI 구현을 능가합니다. 그 이유는 Ray가 이질성을 인식하고 사용자가 작업 또는 Actor의 단위로 리소스 요구 사항을 표현하여 비대칭 아키텍처를 활용할 수 있도록하기 때문입니다. 그런 다음 Ray 구현은 TensorFlow의 단일 프로세스 다중 GPU 지원을 활용하고 가능한 경우 GPU 메모리에 개체를 고정 할 수 있습니다. 이 최적화는 단일 GPU 프로세스에 대한 롤아웃을 비동기 적으로 수집해야하기 때문에 MPI로 쉽게 이식 할 수 없습니다. 실제로 [5]에는 대규모 클러스터 용 MPI를 사용하는 것과 GPU에 최적화되었지만 단일 노드로 제한되는 두 가지 PPO 사용자 지정 구현이 포함되어 있습니다. Ray는 두 시나리오 모두에 적합한 구현을 허용합니다. 리소스 이질성을 처리 할 수있는 Ray의 기능은 CPU 전용 작업을 저렴한 고성능 CPU 인스턴스에서 예약 할 수 있기 때문에 PPO 비용을 4.5 배 감소 시켰습니다 [4]. 반대로 MPI 응용 프로그램은 모든 프로세스가 동일한 코드를 실행하고 동일한 리소스를 필요로하는 대칭 아키텍처를 종종 보여줍니다.이 경우 확장을 위해 CPU 전용 시스템을 사용할 수 없습니다. 또한 MPI 구현에는 실패를 투명하게 처리하지 않기 때문에 주문형 인스턴스가 필요합니다. 4 배 더 저렴한 스팟 인스턴스를 가정 할 때 Ray의 내결함성 및 리소스 인식 스케줄링이 함께 비용을 18 배 절감했습니다.


그림14: Humanoid- v1 과제 [13]에서 6000 점에 도달하는 시간.


6. 관련 프로젝트
(Related Works)


동적 작업 그래프(Dynamic task graphs): Ray는 CIEL [40] 및 Dask [48]와 밀접한 관련이 있습니다. 세 가지 모두 중첩 작업이있는 동적 작업 그래프를 지원하고 미래 추상화를 구현합니다. CIEL은 또한 계보 기반 내결함성을 제공하는 반면 Dask는 Ray와 마찬가지로 Python과 완전히 통합됩니다. 그러나 Ray는 성능에 중요한 영향을 미치는 두 가지 측면에서 다릅니다. 첫째, Ray는 Actor 추상화를 통해 작업 모델을 확장합니다. 이는 분산 학습 및 제공에서 효율적인 상태 저장 계산에 필요하며 모델 데이터를 계산과 함께 배치합니다. 둘째, Ray는 모든 메타 데이터를 저장하는 단일 마스터에 의존하는 대신 완전히 분산되고 분리 된 컨트롤 플레인 및 스케줄러를 사용합니다. 이는 시스템 수정없이 allreduce와 같은 기본 요소를 효율적으로 지원하는 데 중요합니다. 16 개 노드에서 100MB의 최고 성능에서 allreduce on Ray (섹션 5.1)는 200ms 동안 32 라운드의 16 개 작업을 제출합니다. 한편 Dask는 512 개 코어에서 초당 3k 작업의 최대 스케줄러 처리량을보고합니다 [3]. 중앙 집중식 스케줄러를 사용하면 allreduce의 각 라운드에서 최소 ~ 5ms의 스케줄링 지연이 발생하여 완료 시간이 최대 2 배까지 저하됩니다 (그림 12b). 분산 형 스케줄러를 사용하더라도 제어 플레인 정보를 스케줄러와 결합하면 후자가 데이터 전송을위한 중요한 경로에 남겨져 모든 감소의 모든 라운드에 추가 왕복이 추가됩니다.


데이터 플로우 시스템(Dataflow System): 인기있는 데이터 플로우 시스템 MapReduce [20], Spark [65], Dryad [28]는 분석 및 ML 워크로드에 널리 채택되었지만 계산 모델은 세분화되고 동적 시뮬레이션 워크로드에 비해 너무 제한적입니다. Spark 및 MapReduce는 동일한 단계 내의 작업이 동일한 계산을 수행하고 대략 동일한 시간이 걸린다고 가정하는 BSP 실행 모델을 구현합니다. Dryad는이 제한을 완화하지만 동적 작업 그래프를 지원하지 않습니다. 또한 이러한 시스템 중 어떤 것도 Actor 추상화를 제공하지 않으며 확장 가능한 분산 제어 평면 및 스케줄러를 구현하지도 않습니다. 마지막으로 Naiad [39]는 일부 워크로드에 대해 향상된 확장 성을 제공하지만 정적 작업 그래프 만 지원하는 데이터 흐름 시스템입니다.


기계 학습 프레임 워크(Machine Learning Framework): TensorFlow [7] 및 MXNet [18]은 딥 러닝 워크로드를 목표로하고 CPU와 GPU를 모두 효율적으로 활용합니다. 선형 대수 연산의 정적 DAG로 구성된 훈련 워크로드에 대해 뛰어난 성능을 달성하지만 시뮬레이션 및 내장 된 서비스와 훈련을 긴밀하게 결합하는 데 필요한보다 일반적인 계산은 제한적으로 지원합니다. TensorFlow Fold [33]는 내부 C ++ API를 통해 MXNet뿐만 아니라 동적 작업 그래프에 대한 일부 지원을 제공하지만 작업 진행, 작업 완료 시간 또는 작업 완료 시간에 대한 응답으로 실행 중에 DAG를 수정하는 기능을 완전히 지원하지는 않습니다. 결함. TensorFlow 및 MXNet은 원칙적으로 프로그램을 허용하여 일반성을 달성합니다.


mer는 저수준 메시지 전달 및 동기화 기본 요소를 시뮬레이션하지만이 경우 함정과 사용자 경험은 MPI와 유사합니다. OpenMPI [22]는 고성능을 달성 할 수 있지만, 이기종 및 동적 작업 그래프를 처리하기 위해 명시적인 조정이 필요하기 때문에 상대적으로 프로그래밍하기가 어렵습니다. 또한 프로그래머가 내결함성을 명시 적으로 처리하도록합니다. 배우 시스템. Orleans [14]와 Akka [1]은 고 가용성 동시 분산 시스템을 개발하는 데 적합한 프레임 워크입니다. 그러나 Ray에 비해 데이터 손실 복구에 대한 지원이 적습니다. Stateful Actor를 복구하기 위해 Orleans 개발자는 Actor 상태와 중간 응답을 명시 적으로 체크 포인트해야합니다. Orleans의 Stateless 액터는 스케일 아웃을 위해 복제 될 수 있으므로 작업으로 작동 할 수 있지만 Ray와 달리 계보가 없습니다. 마찬가지로, Akka는 장애에 걸쳐 Actor 상태를 유지하는 것을 명시 적으로 지원하지만 상태 비 저장 컴퓨팅 (즉, 작업)에 대해 효율적인 내결함성을 제공하지 않습니다. 메시지 전달을 위해 Orleans는 최소 1 회를 제공하고 Akka는 최대 1 회 시맨틱을 제공합니다. 반대로 Ray는 각 메서드 호출이 GCS에 기록되고 인수와 결과가 모두 변경되지 않기 때문에 투명한 내결함성과 정확히 한 번 의미 체계를 제공합니다. 실제로 이러한 제한은 애플리케이션의 성능에 영향을주지 않습니다. 두 개의 다른 Actor 기반 시스템 인 Erlang [10] 및 C ++ Actor Framework [17]도 마찬가지로 내결함성에 대한 지원을 제한했습니다. 글로벌 제어 저장소 및 스케줄링. 개념 제어 평면을 논리적으로 중앙 집중화하는 방법은 소프트웨어 정의 네트워크 (SDN) [16], 분산 파일 시스템 (예 : GFS [23]), 리소스 관리 (예 : Omega [52]) 및 분산 프레임에서 제안되었습니다. 작동합니다 (예 : MapReduce [20], BOOM [9]). Ray는 이러한 선구적인 노력에서 영감을 얻었지만 상당한 개선을 제공합니다. SDN, BOOM 및 GFS와 달리 Ray는 제어 플레인 정보 (예 : GCS)의 저장소를 논리 구현 (예 : 스케줄러)에서 분리합니다. 이를 통해 스토리지 및 계산 계층 모두 독립적으로 확장 할 수 있으며 이는 확장 성 목표를 달성하는 데 중요합니다. Omega는 스케줄러가 전역 공유 상태를 통해 조정하는 분산 아키텍처를 사용합니다. 이 아키텍처에 Ray는 전역 스케줄러를 추가하여 로컬 스케줄러간에로드 균형을 조정하고 2 단계가 아닌 ms 수준의 작업 예약을 목표로합니다. Ray는 고유 한 분산 상향식 계획을 구현합니다.


수평 확장이 가능하며 동적으로 구성된 작업 그래프를 처리 할 수 있습니다. Ray와 달리 대부분의 기존 클러스터 컴퓨팅 시스템 [20, 64, 40]은 중앙 집중식 스케줄러 아키텍처를 사용합니다. Sparrow [45]는 분산되어 있지만 스케줄러는 독립적 인 결정을 내리고 가능한 스케줄링 정책을 제한하며 작업의 모든 작업은 동일한 글로벌 스케줄러에 의해 처리됩니다. Mesos [26]는 2 단계 계층 적 스케줄러를 구현하지만 최상위 스케줄러는 개별 작업이 아닌 프레임 워크를 관리합니다.


Canary [47]는 각 스케줄러 인스턴스가 작업 그래프의 일부를 처리하도록함으로써 인상적인 성능을 달성하지만 동적 계산 그래프는 처리하지 않습니다. Cilk [12]는 작업 도용 스케줄러가 동적 작업 그래프에 대해 입증 가능한 효율적인로드 밸런싱을 달성하는 병렬 프로그래밍 언어입니다. 그러나 Ray의 글로벌 스케줄러와 같은 중앙 코디네이터가 없기 때문에이 완전 병렬 설계는 분산 설정에서 데이터 지역 성과 리소스 이질성을 지원하도록 확장하기도 어렵습니다.


7 토론 및 경험


Ray를 구축하는 것은 긴 여정이었습니다. 분산 학습 및 시뮬레이션을 수행하기 위해 2 년 전에 Spark 라이브러리로 시작되었습니다. 그러나 BSP 모델의 상대적인 비 유연성, 높은 작업 당 오버 헤드, Actor 추상화 부족으로 인해 새로운 시스템을 개발하게되었습니다. 약 1 년 전에 Ray를 출시 한 이후로 수백 명의 사람들이 사용했으며 여러 회사에서 이를 상용화하고 있습니다. 여기에서는 Ray 개발 및 사용 경험과 초기 사용자 피드백에 대해 설명합니다. API. API를 디자인 할 때 미니멀리즘을 강조했습니다. 처음에는 기본 작업 추상화로 시작했습니다. 나중에 이기종 기간의 롤아웃을 수용하고 제 3 자 시뮬레이터를 수용하고 값 비싼 초기화의 오버 헤드를 상각하기 위해 액터 추상화를 수용하기 위해 wait () 프리미티브를 추가했습니다. 결과 API는 상대적으로 낮은 수준이지만 강력하고 사용하기 쉬운 것으로 입증되었습니다. 우리는 이미이 API를 사용하여 A3C [36], PPO [51], DQN [37], ES [49], DDPG [55], 그리고 A3C [36], PPO [51], DQN [37], 그리고 Ray 위에 많은 최첨단 RL 알고리즘을 구현했습니다. Ape-X [27]. 대부분의 경우 이러한 알고리즘을 Ray로 이식하는 데 수십 줄의 코드가 필요했습니다. 초기 사용자 피드백을 기반으로, 일정 결정에 영향을 줄 수있는 상위 수준의 기본 요소와 라이브러리를 포함하도록 API를 개선하는 것을 고려하고 있습니다.


API: API를 디자인 할 때 미니멀리즘을 강조했습니다. 처음에는 기본 작업 추상화로 시작했습니다. 나중에 이기종 기간이있는 롤아웃을 수용하기 위해 wait () 프리미티브를 추가하고 제 3 자 시뮬레이터를 수용하고 값 비싼 초기화의 오버 헤드를 상각하기 위해 액터 abstraction을 추가했습니다. 결과 API는 상대적으로 낮은 수준이지만 강력하고 사용하기 쉬운 것으로 입증되었습니다. 우리는 이미이 API를 사용하여 A3C [36], PPO [51], DQN [37], ES [49], DDPG [55], 그리고 A3C [36], PPO [51], DQN [37], 그리고 Ray 위에 많은 최첨단 RL 알고리즘을 구현했습니다. Ape-X [27]. 대부분의 경우 이러한 알고리즘을 Ray로 이식하는 데 수십 줄의 코드가 필요했습니다. 초기 사용자 피드백을 기반으로, 일정 결정에 영향을 줄 수있는 상위 수준의 기본 요소와 라이브러리를 포함하도록 API를 개선하는 것을 고려하고 있습니다.


한계(Limitation): 워크로드의 일반성을 감안할 때 특수 최적화는 어렵습니다. 예를 들어, 계산 그래프에 대한 완전한 지식없이 스케줄링 결정을 내려야합니다. Ray에서 최적화를 예약하려면 더 복잡한 런타임 프로파일 링이 필요할 수 있습니다. 또한 각 작업에 대한 계보를 저장하려면 가비지 수집 정책을 구현하여 GCS에서 스토리지 비용을 제한해야합니다.이 기능은 우리가 적극적으로 개발하고 있습니다.


결함 허용(Fault-tolerance): 우리는 종종 내결함성을 묻는 질문을받습니다.

AI 애플리케이션에 정말 필요합니다. 결국, 많은 AI 알고리즘의 통계적 특성으로 인해 실패한 롤아웃을 간단히 무시할 수 있습니다. 우리의 경험을 바탕으로 우리의 대답은“예”입니다. 첫째, 실패를 무시하는 기능은 애플리케이션을 훨씬 쉽게 작성하고 추론 할 수 있도록합니다. 둘째, 결정 론적 재생을 통한 내결함성의 특정 구현은 대부분의 오류를 쉽게 재현 할 수 있으므로 디버깅을 크게 단순화합니다. 확률 성으로 인해 AI 알고리즘은 디버깅하기가 매우 어렵 기 때문에 이것은 특히 중요합니다. 셋째, 내결함성은 AWS의 스팟 인스턴스와 같은 저렴한 리소스에서 실행할 수 있으므로 비용을 절약하는 데 도움이됩니다. 물론 이것은 약간의 간접비를 지불해야합니다. 그러나이 오버 헤드는 대상 워크로드에 대해 최소라는 것을 알았습니다.


GCS 및 수평 확장 성(GCS and Horizontal Scalability):

GCS는 Ray 개발 및 디버깅을 크게 단순화했습니다. 이를 통해 내부 구성 요소 상태를 수동으로 노출 할 필요없이 Ray 자체를 디버깅하면서 전체 시스템 상태를 쿼리 할 수있었습니다. 또한 GCS는 애플리케이션 수준 디버깅에 사용되는 타임 라인 시각화 도구의 백엔드이기도합니다.


GCS는 또한 Ray의 수평 적 확장성에 중요한 역할을했습니다. 섹션 5에서는 GCS가 병목 상태가 될 때마다 더 많은 샤드를 추가하여 확장 할 수있었습니다. GCS는 또한 단순히 더 많은 복제본을 추가하여 글로벌 스케줄러를 확장 할 수 있도록했습니다. 이러한 장점으로 인해 중앙 집중식 제어 상태가 향후 분산 시스템의 핵심 설계 구성 요소가 될 것이라고 믿습니다.


8 Conclusion

오늘날 범용 시스템은 훈련, 제공 및 시뮬레이션의 긴밀한 루프를 효율적으로 지원할 수 없습니다. 이러한 핵심 빌딩 블록을 표현하고 새로운 AI 애플리케이션의 요구를 충족하기 위해 Ray는 단일 동적 작업 그래프에서 작업 병렬 및 Actor 프로그래밍 모델을 통합하고 글로벌 제어 저장소 및 상향식 분산 스케줄러를 통해 지원되는 확장 가능한 아키텍처를 사용합니다. 이 아키텍처에서 동시에 달성되는 프로그래밍 유연성, 높은 처리량 및 낮은 대기 시간은 리소스 요구 사항, 기간 및 기능이 다양한 작업을 생성하는 새로운 인공 지능 워크로드에 특히 중요합니다. 우리의 평가는 초당 최대 180 만 작업까지의 선형 확장 성, 투명한 내결함성 및 여러 최신 RL 워크로드에 대한 상당한 성능 향상을 보여줍니다. 따라서 Ray는 미래의 AI 애플리케이션 개발을 위해 유연성, 성능 및 사용 편의성의 강력한 조합을 제공합니다.

브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari