MLlib 线性代数加速指南

介绍

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

Spark MLlib 将向量和矩阵定义为机器学习算法的基本数据类型。在此基础上, BLAS LAPACK 操作被实现并由 dev.ludovic.netlib 支持(算法也可能调用 Breeze )。 dev.ludovic.netlib 可以使用优化的本机线性代数库(以下将其称为“本机库”或“BLAS库”)以实现更快的数值处理。 Intel MKL OpenBLAS 是两个流行的选项。

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

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

安装本地线性代数库

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

英特尔 MKL

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@... 。否则应该打印警告:

警告 InstanceBuilder: 无法从:dev.ludovic.netlib.blas.JNIBLAS 加载实现
...
java.lang.RuntimeException: 无法加载本地实现
  在 dev.ludovic.netlib.blas.InstanceBuilder.nativeBlas(InstanceBuilder.java:59)
  在 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 的线程数:

  1. 请参考以下资源,以了解如何配置这些 BLAS 实现的线程数: Intel MKL Intel oneMKL ,以及 OpenBLAS