🎉

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

2025/02/20に公開

【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のみ)に対応しています。今後拡張予定です。

2025/02/05時点で、Linux(x86_64, aarch64), MacOS(Apple Sillicon, Intel)に対応しています。

(Windowsは謎のエラーによりGCCでビルドできないため、作業中断中)

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 で公開しています。

https://github.com/veloxml/VeloxML

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

Discussion