MLlib 线性代数加速指南

介绍

本指南提供了启用 Spark MLlib 加速线性代数处理的必要信息。

Spark MLlib 将 Vector 和 Matrix 定义为机器学习算法的基本数据类型。 在它们之上,BLASLAPACK 操作由 dev.ludovic.netlib 实现和支持(算法也可能调用 Breeze)。 dev.ludovic.netlib 可以使用优化的本地线性代数库(以下简称“本地库”或“BLAS 库”)来实现更快的数值处理。 Intel MKLOpenBLAS 是两个流行的库。

官方发布的 Spark 二进制文件不包含这些本地库。

以下部分描述了如何安装本地库,如何正确配置它们,以及如何将 dev.ludovic.netlib 指向这些本地库。

安装本地线性代数库

Intel MKL 和 OpenBLAS 是两个流行的本地线性代数库。 您可以根据自己的喜好选择其中一个。 我们提供以下基本说明。

Intel MKL

OpenBLAS

安装应在群集的所有节点上完成。 大多数发行版都提供了 OpenBLAS 的通用版本。 您可以使用发行版包管理器(如 aptyum)进行安装。

对于 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 的数量相匹配,默认情况下 spark.task.cpus1,通常保留为 1

您可以使用 config/spark-env.sh 中的选项来设置 Intel MKL 或 OpenBLAS 的线程数

  1. 请参考以下资源来了解如何为这些 BLAS 实现配置线程数: Intel MKLIntel oneMKLOpenBLAS