Multi-threaded R

최근 데이터와 인공지능에 대한 관심이 증가하면서, 국내에도 Enterprise레벨에서 R을 사용하여 머신러닝 기법을 적용하려는 시도가 늘고 있습니다.  연구 분야에서는 말할 것도 없고 '데이터 사이언스' 분야에서는 이미 가장 중요한 툴이 된 R이지만, 수 많은 마이닝과 머신러닝 관련 프로젝트에서 지금까지의 SAS나 Matlab의 위상을 고려하면 이런 전폭적인 관심이 조금 갑작스러운 듯 싶은 게 솔직한 심정입니다 :)  어쨌든, 무료이면서 확장성이 뛰어난 R은 Academy와 Research 분야에서 이미 구축된 커뮤니티의 수많은 노력들을 바탕으로, 빠르게 데이터 분석 분야에서 가장 인기있는 도구가 되었습니다.

R을 활용한 통계 분석 기법에 대해서는 참조할 만한 훌륭한 문서들이 많으므로, 여기서는 개인적으로 R을 사용하며 고민했던 부분과 그 활용성을 다뤄보려고 합니다.

1

R은 S-PLUS statistics package를 바탕으로, 기본적으로는 in-house 레벨의 분석을 위한 공개 툴로 디자인 되었기 때문에 초기 구조와 디자인이 병렬처리나 HPC를 염두에 둔 구조는 아니었습니다. 현재까지도 R이 가지고 있는 많은 제약 중 하나는 대부분의 논리/산술 연산이 여전히 메모리 기반의 single-thread로 처리된다는 점인데, 이것은 물론 R의 구조만이 아닌 통계 연산 과정 자체의 문제이기도 합니다.  현재 최신버전의 R에는 이를 극복하기 위한 여러 병렬 연산 지원 함수를 기본으로 포함하고 있습니다.1)

이러한 R을 multi-thread/multi-core환경에서 손쉽게 사용하기 위해서는 다음과 같이 크게 두 가지 방법을 이용할 수 있습니다. (물론 두 방법을 동시에 사용하는 것도 가능합니다)

첫째는 single-core/single-thread만 사용하는 기본 algebra library를 multi-thread 지원 library로 대체하는 방법입니다.  시스템 관리자 레벨에서 library를 변경하기만 하면 되므로 각각의 사용자는 자신의 코드를 변경할 필요가 없는 장점이 있습니다만, 특정 연산이외에는 별다른 향상을 체감할 수 없다는 단점도 있습니다.  병렬처리 algebra library를 직접 컴파일하는 것이 번거롭게 느껴진다면 Microsoft R Open (기존의 RevolutionR)과 같이 parallel library를 내포하고 있는 R을 사용하시면 됩니다.  여기에 대해서는 다음 장에서 다시 설명하겠습니다.

둘째는 parallel / distributed 관련 패키지를 설치하고, 해당 함수를 이용하는 방법입니다.  multi-core부터  Hadoop cluster의 map/reduce까지 수많은 플랫폼을 지원하는 back-end 패키지들뿐만이 아니라 foreach나 doParallel과 같은 front-end 작업을 구현하 는 여러 함수들도 준비되어있습니다.  기존에 사용하던 스크립트가 있다면 연산 과정을 전부 다시 작성해야하거나 새롭게 구현 해야하겠지만, PC나 single-node에서도 embarrassingly paralleled problem계산에 있어서 훨씬 나은 성능을 기대할 수 있습니다.

2

R에서 multi-thread를 지원하기위해서는 MRO (Microsoft R Open)을 설치하는 것이 가장 간단한 해결책입니다.  (이름에 'OPEN'이라는 키워드를 명시했듯이, 저를 포함한 :) 대부분의 사람이 가지고 있는 선입견과는 달리 Microsoft는 근래들어 더욱 더 노골적으로 오픈소스와 리눅스진영에 호의를 표현하고 있습니다.)  이 분야에서 비교적 새로운 이름인 MRO는 R의 병렬화에서는 이미 널리 알려져 있던 RevolutionR의 발전된 버전입니다.

Microsoft Loves Linux

지금은 Love하지만 2001년도엔  Cancer라고 했던 건 함정
사진 출처: Softpedia, CEO Satya Nadella: Microsoft Loves Linux, 2014.10.21

작년 1월 RevolutionR을 인수 했던 Microsoft는, 정확히 1년이 지난 올해 1월, 자사의 SQL Server 혹은 Hadoop cluster와의 연동까지 염두에 둔 Microsoft R Open(MRO)을 조용히 선보였습니다.  많은 이들의 우려에도 불구하고 MRO는 지금까지는 안정된 성능과 지속적인 오픈소스 진영에 대한 지원을 이어가며 기반을 다지고 있는 듯 한 인상입니다.  또한 MRO의 성능을 최대로 끌어낼 수 있도록 CRAN을 mirroring하여 기존 패키지들의 알려진 버그를 수정하고  최적화한 repository인 MRAN도 동시에 오픈했습니다.

MRO의 전신인 Revolution R은 완성도 높은 RevoScaleR2)라는 병렬화 연산 패키지를 지원해왔고, 지금까지의 algebra library 중 가장 효율적이라고 할 수 있는 Intel Math Kernel Library를 기본으로 탑재하고 있으면서도 Vanila R 및 그 패키지들과 완벽한 호환을 유지합니다.

단점으로는 현재 64bit만 지원한다는 점, MKL이 Intel compatible processor만 지원하는 점 그리고 MKL은 바이너리로만 제공되는 점을 들 수 있겠습니다만, 병렬처리가 필요한 분석에서 (메모리 제약때문에라도) 굳이 32bit OS를 고집할 이유가 없고, 대부분의 PC와 서버의 processor가 Intel 호환인 것을 감안하면 실질적으로 이렇다할 불만?거리를 찾기 힘듭니다.  (MKL은 설치여부가 선택사항이기 때문에 MRO의 문제라고 말하기 어렵습니다.)

커뮤니티 기반 프로젝트의 고질적인 문제인 복잡하고 파편화된 소스를 Microsoft라는 거대 기업에서 어떻게 활용하고, 다시 어떤 방식으로 커뮤니티에 기여할 수 있을지는 조금 더 시간을 두고 지켜볼 흥미로운 관전 포인트입니다.

MRO
M사 관련 오픈소스 프로젝트들에서 유독 원숭이가 눈에 띄는 건... 그냥 기분 탓 일겁니다.

3

아무래도 M사의 꿍꿍이가 부담스럽거나 I사의 독점적지위를 악용?하는 행태가 거북하다면  :) 오픈소스버전의 library를 사용할 수도 있습니다.  굳이 MRO를 사용하지 않고도 multi-thread 지원 algebra library를 컴파일해서 사용하면 유사한 성능향상을 기대할 수 있습니다.  직접 컴파일한다는 말이 어렵게 들리지만 막상 따라 해보면 그다지 복잡하지 않기 때문에, MRO 등장 이전에는 가장 일반적인 R 최적화 방법으로 추천되던 방법입니다.  

대부분의 *NIX 환경에서 시스템 레벨의 algebra library로 사용하고 있는 BLAS(Basic Linear Algebra Subprogram)는 기본적으로 multi-thread를 지원하지 않는 버전이므로  그 외에도 많은 개량된 library가 개발되어 왔습니다.  이미 다양한 리눅스 배포판이나 OS들이 이러한 개량된 버전이나 자신의 시스템에 특화된 버전의 library를 쓰는 경우가 적지 않으므로3)  이를 이용하도록 R을 재컴파일하기만 해도 — 혹은 R의 library를 교체하기만 해도 — 성능이 향상될 수 있습니다.

여기서는 오픈소스 BLAS library중 OpenBLAS를 사용하는 예를 보여드리려고 합니다.  OpenBLAS 는 고토 카즈히게 박사가 2002 년 개발한 GotoBLAS를 기반으로 만들어진 library로4) 단순히 multi-thread만을 지원하는 것이 아니라 single-thread에서도 기본 BLAS보다 뛰어난 성능을 보여줍니다.5)

이미지 출처: OpenBLAS FAQ

아래는 조금 오랜 자료이기는 하지만(2012), MKL과 GotoBLAS, OpenBLAS의 성능을 비교한 자료입니다.

OpenBLAS를 R에서 사용하기 위해서는 다음과 같은 단계를 거쳐야 합니다.  별다른 컴파일 파라미터 최적화를 추가하지 않았기 때문에 단순히 컴파일과정을 따라하는 것 만으로도 문제없이 간단하게 설치 할 수 있습니다. 각 로컬 파일 경로 부분은 (/home/mittens/usr) 사용자의 환경에 따라 원하시는 장소로 변경해 주시기 바랍니다.

1.최신버전의 OpenBLAS를 다운받아 압축을 풉니다.

1
2
wget http://github.com/xianyi/OpenBLAS/tarball/v0.2.18 --no-check-certificate -O OpenBLAS-0.2.18.tar.gz
tar xvf OpenBLAS-0.2.18.tar.gz

2. 압축을 푼 소스파일을 사용자 경로에 컴파일합니다.

1
2
3
4
cd OpenBLAS-0.2.18
make
make PREFIX=/home/mittens/usr/OpenBLAS install
cd ..

3. 이미 설치되어있는 R의 BLAS library를 새롭게 컴파일된 외부 library로 바꿉니다.

1
2
mv ~/usr/R/lib/R/lib/libRblas.so ~/usr/R/lib/R/lib/libRblas.so.org
ln -s ~/usr/OpenBLAS/lib/libopenblas.so ~/usr/R/lib64/R/lib/libRblas.so

4. 설치가 맞게 되었다면 R을 실행한 다음, 다른 터미널 창을 하나 열고 아래의 명령을 실행시켜서 현재 R이 사용하는 thread의 숫자를 확인할 수 있습니다.

1
cat /proc/`ps -ef | grep exec\/R | grep -v grep | awk '{print $2}'`/status | grep Threads

이렇게 컴파일 된 library는 단순히 R뿐만이 아니라 Python이나 Matlab 등 다른 곳에서도 사용 될 수 있으며, Android같은 다른 *NIX 계열 플랫폼에서도 동일한 방법으로 multi-thread로 향상된 성능을 이용할 수 있습니다.

아래는 예제와 같이 R을 컴파일 후 로컬계정에 직접 설치하는 방법입니다. (편의상 R버전은 3.3.1,  mirror는 버클리대학서버를 이용했습니다) 이 때 C는 물론 C++, Fortran 컴파일러가 필요합니다.  이 예제에서 R 실행파일은 /home/mittens/usr/R/bin에 위치하게 됩니다.

1
2
3
4
5
6
wget http://cran.cnr.berkeley.edu/src/base/R-3/R-3.3.1.tar.gz
tar xvf R-3.3.1.tar.gz
cd R-3.3.1
./configure --prefix=/home/mittens/usr/R
make && make install
cd ..

혹시 컴파일 중 오류가 발생한다면 이것은 시스템에서 필요한 헤더파일을 못 찾기 때문이므로 yum이나 apt과 같은 각 시스템 패키지 매니저에서 해당 패키지의 development 버전을 설치하거나 각각의 소스를 다운받아 컴파일해야 합니다 — Gentoo계열 배포판이 아니라면 시스템 패키지 매니저를 이용하는 것이 여러모로 편리합니다.  필요한 라이브러리를 설치 후 다시 R을 컴파일하세요.

아래는 R을 컴파일 할 때 필요한 라이브러리와 그 헤더파일을 포함하고 있는 development 패키지명의 예입니다.  패키지명은 시스템이나 버전에 따라 조금씩 변경될 수 있습니다.

라이브러리 실제 필요 패키지명의 예
readline libreadline-dev
zip libzip-dev
bzip2 libbz2-dev
X11 xorg-dev
lzma liblzma-dev
PCRE libpcre++-dev
CURL libcurl4-gnutls-dev


1)  2.1.4 이후 버전의 R은 parallel package가 코어에 내장되면서 MPI cluster와 같은 병렬 처리를 정식 지원하고 있습니다. 그 외의 High-performance를 위한 R project들은 공식문서에 자세히 정리되어 있습니다.

2) Microsoft 버전의 RevoScaleR에 대한 분산 연산 문서와 예제는 여기에 정리되어 있습니다.

3) BLAS의 개량된 버전으로는 LAPACK (Linear Algebra PACKage), ATLAS (Automatically Tuned Linear Algebra Software)등이 흔히 사용되며, OS별로는 Solaris의 sunperf, IBM의 Linux 라이브러리인 libessl, OS X의 Accelerate등이 있습니다.

4) GotoBLAS는 펜티엄4를 기반으로 디자인되었지만 당시 대부분의 슈퍼컴퓨터에 사용되었을 정도로 훌륭한 성능을 보여주었고, 이후 University of Texas Austin의 HPC센터에서 이를 계승한 GotoBLAS2를 개발했습니다.  아쉽게도 2010년 이후 더이상의 업데이트가 이루어지고 있지 않기 때문에, 현재는 이를 이어받은 OpenBLAS Project가 개발되고 있습니다.  고토박사는 그 후 Microsoft를 거쳐 Intel에 합류하여 계속하여 Optimized library를 연구/개발하고 있다고 합니다.

5) 물론 일반적인 경우 MKL이 OpenBLAS를 압도하는 결과를 보입니다. (출처)


Popit은 페이스북 댓글만 사용하고 있습니다. 페이스북 로그인 후 글을 보시면 댓글이 나타납니다.