9
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Scikit-Learnが遅いので、C++製の超高速機械学習ライブラリを作った話

Posted at

【VeloxML】Scikit-Learnが遅いので、C++製の超高速機械学習ライブラリを作った話

こんにちは!

機械学習の高速化を目指し、C++製の機械学習ライブラリ「VeloxML」(アルファ版) を開発したので紹介したいと思います。

導入(イントロ)

機械学習を実際のプロジェクトで活用しようとすると、計算速度の壁に直面することがあります。特に、数百万件のデータをローカル環境で学習させるようなケースでは、既存のライブラリの限界を感じることがありました。

最初は scikit-learn を使っていましたが、大規模データでの学習が遅く、処理時間がボトルネックになっていました。かといって、ロジスティック回帰をするためだけにPyTorchやTensorFlowを用意するのは大袈裟すぎます。シンプルな機械学習タスクに、数GBものディープラーニングフレームワークをインストールするのは非効率的です。

唯一、LightGBMだけは満足できる速度で処理できました。しかし、LightGBMは主に決定木ベースのアルゴリズムに特化しており、線形回帰やSVM、クラスタリングなどの手法はサポートされていません。

さらに、scikit-learnは公式にGPU対応の予定がない様子だったため、
「それなら自分で作ってしまおう!」
という思いから、C++で高速な機械学習ライブラリ VeloxML を開発しました。

VeloxMLは、C++による高速実装、OpenMP/TBBを活用した並列処理、BLAS/LAPACKを用いた最適化を組み合わせ、scikit-learnの使いやすさを維持しながら、高速な機械学習を実現することを目指しています。
また、Python APIも提供しており、scikit-learnのように簡単に使える設計になっています。

この記事では、VeloxMLの特徴や使い方、今後の展望について紹介します!

VeloxMLとは?

VeloxML は、C++で実装された機械学習ライブラリで、Pythonから手軽に使えます。

BLAS/LAPACKを活用し、高速な計算を実現!

  • 並列処理:OpenMP/TBBで高速化
  • Python API対応:pybind11でラップ
  • 主要アルゴリズム実装済み
    • 線形回帰 / ロジスティック回帰 / 決定木 / ランダムフォレスト / SVM など
  • 将来的にAutoML・GPU対応を視野に開発中!

インストール

執筆時点では、MacOS(Apple Siliconのみ)に対応しています。今後拡張予定です。

pip install veloxml

使い方(例: 線形回帰)

import veloxml as vx

model = vx.LinearRegression()
model.fit(X_train, y_train)
y_pred = model.predict(X_test)

実行速度を計測してみた。

以下のようなコードで、Pythonから実行速度を計測してみました。計測環境は以下のような実験設定で行いました。

  • MacBookPro 2023 (Apple M2 Pro, 16GB)
  • 100万件のレコード
  • 1レコードあたり100個の特徴量
  • ツリーの数が10個
  • ツリーの最大深さを5に制限
  • 5つのツリーを並列処理する
import time
import numpy as np
from sklearn.metrics import accuracy_score
from sklearn.model_selection import train_test_split
import warnings
warnings.simplefilter("ignore")

from veloxml.tree import RandomForestClassification
# from sklearn.ensemble import RandomForestClassifier

fit_time_list = []
pred_time_list = []

for i in range(100):
  # ランダムシード
  rng = np.random.default_rng()

  # データ数と特徴量数
  num_samples = 1000000
  num_features = 100

  # 数値特徴量の生成 (ガウス分布)
  X_numeric = rng.normal(0, 1, (num_samples, num_features - 5))
  
  W = rng.normal(0, 1, (num_features - 5))

  # カテゴリカルな特徴量を追加 (0, 1, 2の3カテゴリ)
  X_categorical = rng.integers(0, 3, (num_samples, 5))

  # 全特徴を結合
  X = np.hstack([X_numeric, X_categorical])

  # ターゲット変数の作成(非線形な条件付きで決定)
  Y = ((X_numeric.dot(W) > 1.5) & ((X[:, -1] == 1) | (X[:, -2] == 2))).astype(np.int32)

  X_train, X_test, y_train, y_test = train_test_split(X, Y)

  print()

  # モデルの作成
  model = RandomForestClassification(
    n_trees=10,
    criterion="Gini",
    split_algorithm="Histogram",
    max_depth=5,
    max_leaf_nodes=100,
    random_seed=42,
    n_jobs=5
  )
  
  # # sklearnの場合
  # model = RandomForestClassifier(
  #   n_estimators=10,
  #   criterion="gini",
  #   max_depth=5,
  #   max_leaf_nodes=100,
  #   random_state=42,
  #   n_jobs=5
  # )

  # 学習時間の計測
  start_time = time.time()
  model.fit(X_train, y_train)
  train_time = time.time() - start_time
  
  fit_time_list.append(train_time)
  
  # 推論時間の計測
  start_time = time.time()
  y_pred = model.predict(X_test[[0], :])
  inference_time = (time.time() - start_time)
  
  pred_time_list.append(inference_time)

  # 精度の計測
  accuracy = accuracy_score(y_test[[0]], y_pred[[0]])

  print(f"学習時間: {train_time:.4f}")
  print(f"推論時間: {inference_time:.4e} 秒 / サンプル")
  print(f"精度: {accuracy:.4f}")

print(f"平均学習時間: {np.mean(fit_time_list):.4f}")
print(f"平均推論時間: {np.mean(pred_time_list):.4e} 秒 / サンプル")

最終的に、計測時間は以下のような平均値になりました。

平均学習時間: 1.5178 秒
平均推論時間: 8.5713e-04 秒 / サンプル

また参考までに、同様の実験をScikit-LearnのRandomForestClassifierで行ったところ、以下の結果が出ました。

平均学習時間: 7.1197 秒
平均推論時間: 1.4954e-02 秒 / サンプル

学習時間は4倍、推論時間は17倍程度早くなりました。👏

今後の展望と現状の課題

今後の展望

VeloxMLは、より高速で汎用的な機械学習ライブラリを目指して、今後も開発を続けていきます。具体的には、以下のような方向性を考えています。

  1. 主要なアルゴリズムの実装を継続
  • 現在実装されている線形回帰、ロジスティック回帰、決定木、ランダムフォレスト、SVM、k-means、PCAなどに加えて、さらなるアルゴリズムの追加を予定しています。
  1. CUDA, Metal, VulkanでのGPGPU対応
  • 現在はCPU上での並列処理(OpenMP/TBB)を活用していますが、今後は CUDA(NVIDIA)、Metal(Apple)、Vulkan(クロスプラットフォーム) を利用したGPGPU対応を進めていきます。
  • 特に、大規模なデータセットを処理する際にはGPUの恩恵が大きいため、学習時間の短縮を目指します。
  1. AutoMLの実装
  • 単にアルゴリズムを提供するだけでなく、ハイパーパラメータチューニングや特徴量選択を自動化するAutoML機能を追加する予定です。
  • これにより、エンドユーザーがより簡単に高精度なモデルを作成できるようになります。
  1. さらなる高速化
  • すでにBLAS/LAPACKを活用していますが、さらなる最適化を行い、計算負荷の高い処理を効率化していきます。
  • SIMD(AVX2, AVX-512)を活用した最適化や、メモリアクセスの効率改善にも取り組む予定です。

現状の課題

現時点では、以下のような課題もあります。

  1. SVM分類器が遅い
  • SVM(サポートベクターマシン)の学習に時間がかかるのが大きな問題点です。
  • 特に、大規模データセットでは計算コストが高くなるため、カーネルの計算をより効率化する方法を検討中です。
  • 現在の解決策として、線形SVMの場合はBLASを活用、カーネルSVMは適切な近似アルゴリズムを導入することを考えています。

VeloxMLは、 「手軽に使えるが、高速でスケーラブル」 な機械学習フレームワークを目指して、引き続き開発を進めていきます。
今後のアップデートにもご期待ください!

GitHub

以下のリポジトリにて、MIT License で公開しています。

ぜひスターをお願いします!

9
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?