MLlib 선형대수 가속 가이드

MLlib 선형대수 가속 가이드 (MLlib Linear Algebra Acceleration Guide)

Apache Spark의 MLlib에서 선형대수 연산을 더 빠르게 처리하기 위해 네이티브(native) 선형대수 라이브러리를 활성화하고 설정하는 방법을 안내하는 가이드예요. MLlib이 기본으로 쓰는 BLAS/LAPACK 구현을 인텔 MKL이나 OpenBLAS 같은 고성능 네이티브 라이브러리로 바꿔 끼우는 과정을 차근차근 설명해 드릴게요.

출처: 문서

본문

소개 (Introduction)

이 가이드는 Spark MLlib의 선형대수 처리를 가속화하기 위해 필요한 정보를 제공해요.

Spark MLlib은 머신러닝 알고리즘을 위한 기본 데이터 타입으로 VectorMatrix를 정의합니다. 그 위에 BLASLAPACK 연산이 구현되어 있고, dev.ludovic.netlib이 이를 지원해요 (알고리즘에 따라 Breeze를 호출하기도 합니다). dev.ludovic.netlib은 더 빠른 수치 처리를 위해 최적화된 네이티브 선형대수 라이브러리(이하 '네이티브 라이브러리' 또는 'BLAS 라이브러리')를 사용할 수 있어요. Intel MKLOpenBLAS가 대표적인 두 라이브러리입니다.

공식으로 배포되는 Spark 바이너리에는 이러한 네이티브 라이브러리가 포함되어 있지 않아요.

다음 섹션에서는 네이티브 라이브러리를 설치하고 올바르게 설정하는 방법, 그리고 dev.ludovic.netlib이 이 네이티브 라이브러리를 가리키게 하는 방법을 설명합니다.

네이티브 선형대수 라이브러리 설치하기

Intel MKL과 OpenBLAS가 대표적인 두 네이티브 선형대수 라이브러리예요. 선호에 따라 둘 중 하나를 고르면 됩니다. 기본적인 설치 방법은 아래와 같아요.

Intel MKL

  • Intel MKL을 다운로드하고 설치하세요. 설치 작업은 클러스터의 모든 노드에서 수행해야 합니다. 설치 위치가 $MKLROOT (예: /opt/intel/mkl)라고 가정할게요.
  • 시스템 라이브러리 검색 경로에 libmkl_rt.so를 특정 이름으로 가리키는 소프트 링크를 만드세요. 예를 들어 /usr/local/lib가 시스템 라이브러리 검색 경로에 있는지 확인하고 다음 명령을 실행합니다:
$ ln -sf $MKLROOT/lib/intel64/libmkl_rt.so /usr/local/lib/libblas.so.3
$ ln -sf $MKLROOT/lib/intel64/libmkl_rt.so /usr/local/lib/liblapack.so.3

OpenBLAS

설치 작업은 클러스터의 모든 노드에서 수행해야 합니다. 대부분의 배포판에는 OpenBLAS의 일반 버전이 제공돼요. aptyum 같은 배포판 패키지 관리자로 설치할 수 있습니다.

Debian / Ubuntu:

sudo apt-get install libopenblas-dev

CentOS / RHEL:

sudo yum install openblas

MLlib에서 네이티브 라이브러리가 활성화됐는지 확인하기

네이티브 라이브러리가 제대로 로드되는지 확인하려면 spark-shell을 시작하고 다음 코드를 실행하세요:

scala> import dev.ludovic.netlib.blas.NativeBLAS
scala> NativeBLAS.getInstance()

올바르게 로드되었다면 dev.ludovic.netlib.blas.NativeBLAS = dev.ludovic.netlib.blas.JNIBLAS@...라는 출력이 나와야 해요. 그렇지 않으면 다음과 같은 경고가 출력됩니다:

WARN InstanceBuilder: Failed to load implementation from:dev.ludovic.netlib.blas.JNIBLAS
...
java.lang.RuntimeException: Unable to load native implementation
  at dev.ludovic.netlib.blas.InstanceBuilder.nativeBlas(InstanceBuilder.java:59)
  at dev.ludovic.netlib.blas.NativeBLAS.getInstance(NativeBLAS.java:31)
  ...

dev.ludovic.netlib이 특정 라이브러리 이름과 경로를 가리키게 할 수도 있어요. 예를 들어 Intel MKL의 경우 -Ddev.ludovic.netlib.blas.nativeLib=libmkl_rt.so 또는 -Ddev.ludovic.netlib.blas.nativeLibPath=$MKLROOT/lib/intel64/libmkl_rt.so를 사용할 수 있습니다. LAPACK과 ARPACK에도 비슷한 파라미터가 있어요: -Ddev.ludovic.netlib.lapack.nativeLib=..., -Ddev.ludovic.netlib.lapack.nativeLibPath=..., -Ddev.ludovic.netlib.arpack.nativeLib=..., -Ddev.ludovic.netlib.arpack.nativeLibPath=....

시스템에 네이티브 라이브러리가 제대로 설정되어 있지 않으면 Java 구현(javaBLAS)이 대체(fallback) 옵션으로 사용됩니다.

네이티브 BLAS 라이브러리를 비활성화하고 항상 Java 구현(javaBLAS)을 쓰려면 Java 시스템 속성 -Ddev.ludovic.netlib.blas.allowNative=false를 설정하세요. LAPACK과 ARPACK에도 비슷한 파라미터가 있어요: -Ddev.ludovic.netlib.lapack.allowNative=false, -Ddev.ludovic.netlib.arpack.allowNative=false.

Spark 설정 (Spark Configuration)

Intel MKL이나 OpenBLAS의 기본 멀티스레딩 동작은 Spark의 실행 모델과 잘 맞지 않을 수 있어요 1.

따라서 이 네이티브 라이브러리들이 연산에 단일 스레드를 사용하도록 설정하면 오히려 성능이 향상될 수 있습니다 (SPARK-21305 참고). 보통은 이를 spark.task.cpus 값과 맞추는 것이 최적이며, 기본값은 1이고 보통 1로 두는 편이에요.

config/spark-env.sh에서 다음 옵션을 사용해 Intel MKL이나 OpenBLAS의 스레드 수를 설정할 수 있습니다:

  • Intel MKL:
MKL_NUM_THREADS=1
  • OpenBLAS:
OPENBLAS_NUM_THREADS=1

참고: 이러한 BLAS 구현의 스레드 수를 구성하는 방법에 대한 자세한 내용은 다음 자료를 참고하세요: Intel MKL 또는 Intel oneMKL, 그리고 OpenBLAS. ↩

더 알아보기 (Learn more)