MLlib 선형대수 가속 가이드
MLlib 선형대수 가속 가이드 (MLlib Linear Algebra Acceleration Guide)
Apache Spark의 MLlib에서 선형대수 연산을 더 빠르게 처리하기 위해 네이티브(native) 선형대수 라이브러리를 활성화하고 설정하는 방법을 안내하는 가이드예요. MLlib이 기본으로 쓰는 BLAS/LAPACK 구현을 인텔 MKL이나 OpenBLAS 같은 고성능 네이티브 라이브러리로 바꿔 끼우는 과정을 차근차근 설명해 드릴게요.
출처: 문서
본문
소개 (Introduction)
이 가이드는 Spark MLlib의 선형대수 처리를 가속화하기 위해 필요한 정보를 제공해요.
Spark MLlib은 머신러닝 알고리즘을 위한 기본 데이터 타입으로 Vector와 Matrix를 정의합니다. 그 위에 BLAS와 LAPACK 연산이 구현되어 있고, dev.ludovic.netlib이 이를 지원해요 (알고리즘에 따라 Breeze를 호출하기도 합니다). dev.ludovic.netlib은 더 빠른 수치 처리를 위해 최적화된 네이티브 선형대수 라이브러리(이하 '네이티브 라이브러리' 또는 'BLAS 라이브러리')를 사용할 수 있어요. Intel MKL과 OpenBLAS가 대표적인 두 라이브러리입니다.
공식으로 배포되는 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의 일반 버전이 제공돼요. apt나 yum 같은 배포판 패키지 관리자로 설치할 수 있습니다.
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)
- MLlib 기본 데이터 타입:
Vector와Matrix의 개념을 다시 살펴보세요. - RDD 기반 MLlib API: MLlib의 전체 구조를 이해하면 가속 설정이 왜 중요한지 더 와닿아요.
- Spark 설정 가이드:
spark.task.cpus등 관련 설정을 알아보세요.