MLlib 線性代數加速指南
簡介
本指南提供必要的資訊,讓 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-base
sudo update-alternatives --config libblas.so.3
針對 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
指向特定函式庫名稱和路徑。例如,-Ddev.ludovic.netlib.blas.nativeLib=libmkl_rt.so
或 -Ddev.ludovic.netlib.blas.nativeLibPath=$MKLROOT/lib/intel64/libmkl_rt.so
(針對 Intel MKL)。您有類似參數可供 LAPACK 和 ARPACK 使用:-Ddev.ludovic.netlib.lapack.nativeLib=...
、-Ddev.ludovic.netlib.lapack.nativeLibPath=...
、-Ddev.ludovic.netlib.arpack.nativeLib=...
和 -Ddev.ludovic.netlib.arpack.nativeLibPath=...
。
如果系統中未正確設定原生函式庫,Java 實作 (javaBLAS) 將會用作備用選項。
Spark 設定
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。 ↩