0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

cuBLASってなんだ?―― 行列演算を爆速にする縁の下の力持ち

Last updated at Posted at 2025-11-27

GPU計算の三銃士シリーズ 第2回

「行列の掛け算なんて、自分で書けるでしょ?」

プログラマーなら誰でもそう思う。実際、二重ループで書けば動く。でも、それでは遅すぎる。ディープラーニングの世界では、毎秒何億回もの行列演算が必要になる。

今回は、GPU上で行列演算を「異次元のスピード」で実行するライブラリ「cuBLAS」を解説する。その前に、まず「BLAS」という50年の歴史を持つ偉大な標準について知っておこう。


TL;DR(忙しい人向けまとめ)

  • BLAS = Basic Linear Algebra Subprograms(1979年〜)
  • 線形代数の基本操作を標準化した「仕様」
  • cuBLAS = NVIDIAがGPU向けに最適化したBLAS実装
  • 自作コードより数十倍〜数百倍速い
  • ディープラーニングの「縁の下の力持ち」

1. BLASとは何か

1970年代の英知

cuBLASを理解するには、まず「BLAS」を知る必要がある。

BLASは「Basic Linear Algebra Subprograms」の略で、線形代数の基本操作を標準化した仕様だ。

"Basic Linear Algebra Subprograms (BLAS) is a specification that prescribes a set of low-level routines for performing common linear algebra operations such as vector addition, scalar multiplication, dot products, linear combinations, and matrix multiplication."

「BLAS(Basic Linear Algebra Subprograms)は、ベクトル加算、スカラー倍、内積、線形結合、行列乗算などの一般的な線形代数演算を行うための低レベルルーチン群を規定した仕様である。」

— Wikipedia "Basic Linear Algebra Subprograms" (https://en.wikipedia.org/wiki/Basic_Linear_Algebra_Subprograms)

この仕様が生まれたのは1970年代。当時、科学計算プログラムでは同じような行列演算コードが何度も書かれていた。

"A specification for these kernel operations using scalars and vectors, the level-1 Basic Linear Algebra Subroutines (BLAS), was published in 1979. BLAS was used to implement the linear algebra subroutine library LINPACK."

「スカラーとベクトルを使ったこれらのカーネル操作の仕様、Level-1 BLAS(Basic Linear Algebra Subroutines)は1979年に公開された。BLASは線形代数サブルーチンライブラリLINPACKの実装に使用された。」

— Wikipedia "Basic Linear Algebra Subprograms" (https://en.wikipedia.org/wiki/Basic_Linear_Algebra_Subprograms)

3つのレベル

BLASは操作の種類によって3つのレベルに分かれている:

レベル 操作の種類 計算量
Level 1 ベクトル-ベクトル 内積、ベクトル加算 O(n)
Level 2 行列-ベクトル 行列とベクトルの積 O(n²)
Level 3 行列-行列 行列積(GEMM) O(n³)

"The BLAS (Basic Linear Algebra Subprograms) are routines that provide standard building blocks for performing basic vector and matrix operations. The Level 1 BLAS perform scalar, vector and vector-vector operations, the Level 2 BLAS perform matrix-vector operations, and the Level 3 BLAS perform matrix-matrix operations."

「BLAS(Basic Linear Algebra Subprograms)は、基本的なベクトルおよび行列操作を行うための標準的なビルディングブロックを提供するルーチンである。Level 1 BLASはスカラー、ベクトル、ベクトル-ベクトル演算を、Level 2 BLASは行列-ベクトル演算を、Level 3 BLASは行列-行列演算を行う。」

— Netlib BLAS (https://www.netlib.org/blas/)

「仕様」と「実装」の分離

BLASの賢いところは、「仕様」と「実装」を分離したこと。同じAPIを使いながら、ハードウェアに最適化された実装に差し替えることができる。

実装 ベンダー 対象ハードウェア
MKL Intel Intel CPU
AOCL AMD AMD CPU
OpenBLAS オープンソース 汎用CPU
cuBLAS NVIDIA NVIDIA GPU
rocBLAS AMD AMD GPU

つまり、同じコードでも実装を変えるだけで劇的に速くなる可能性がある。


2. cuBLASとは何か

GPU向けに最適化されたBLAS

cuBLASは、NVIDIAがGPU向けに最適化して実装したBLASライブラリだ。

"The cuBLAS library is an implementation of BLAS (Basic Linear Algebra Subprograms) on top of the NVIDIA® CUDA™ runtime. It allows the user to access the computational resources of NVIDIA Graphics Processing Unit (GPU)."

「cuBLASライブラリは、NVIDIA CUDA ランタイム上に構築されたBLAS(Basic Linear Algebra Subprograms)の実装である。ユーザーはこれを通じてNVIDIA GPUの計算リソースにアクセスできる。」

— cuBLAS Documentation (https://docs.nvidia.com/cuda/cublas/)

CUDA Toolkitに同梱されているので、CUDAをインストールすれば自動的に使えるようになる。

Tensor Coreの活用

最近のNVIDIA GPU(Volta世代以降)には、行列演算専用のハードウェア「Tensor Core」が搭載されている。cuBLASはこれを自動的に活用する。

"The cuBLAS library is highly optimized for performance on NVIDIA GPUs, and leverages tensor cores for acceleration of low- and mixed-precision matrix multiplication."

「cuBLASライブラリはNVIDIA GPU上でのパフォーマンスに高度に最適化されており、低精度および混合精度の行列乗算を加速するためにTensor Coreを活用する。」

— NVIDIA cuBLAS (https://developer.nvidia.com/cublas)


3. GEMM:最も重要な操作

GEMMとは

cuBLASで最も重要な操作は「GEMM」(General Matrix Multiply)だ。これは以下の計算を行う:

C = α × A × B + β × C

ここで:

  • A, B, C は行列
  • α, β はスカラー

単純な行列積 C = A × B は、α = 1, β = 0 の特殊ケースとなる。

なぜGEMMが重要か

ディープラーニングの計算の大部分は、実は行列積に帰着する:

  • 全結合層(Dense Layer): 入力ベクトルと重み行列の積
  • 畳み込み層(Convolution): im2colで行列に変換してGEMM
  • アテンション(Attention): Q, K, Vの行列積
  • バッチ処理: 複数サンプルを行列としてまとめて処理

つまり、GEMMが速ければ、ディープラーニング全体が速くなる。

"Two CUDA libraries that use Tensor Cores are cuBLAS and cuDNN. cuBLAS uses Tensor Cores to speed up GEMM computations (GEMM is the BLAS term for a matrix-matrix multiplication)."

「Tensor Coreを使用する2つのCUDAライブラリがcuBLASとcuDNNだ。cuBLASはTensor Coreを使ってGEMM計算(GEMMはBLAS用語で行列-行列乗算)を高速化する。」

— NVIDIA Developer Blog (https://developer.nvidia.com/blog/programming-tensor-cores-cuda-9/)


4. cuBLASのバリエーション

cuBLASには用途に応じたいくつかのバリエーションがある。

cuBLAS(基本版)

標準的なBLAS APIを提供。Level 1〜3のすべての操作に対応。

cuBLASLt

「Lt」は「Lightweight」の略...ではなく、より柔軟な「Lightweight」APIという意味だ。

"cuBLASLt Host APIs are multi-stage GEMM APIs that are highly expressive, allowing applications to leverage the latest NVIDIA architecture features for the best performance with support for fusions and performance tuning options."

「cuBLASLt ホストAPIは、マルチステージのGEMM APIであり、高い表現力を持ち、アプリケーションが最新のNVIDIAアーキテクチャ機能を活用してフュージョンやパフォーマンスチューニングオプションをサポートしながら最高の性能を達成できる。」

— NVIDIA cuBLAS (https://developer.nvidia.com/cublas)

特徴:

  • Tensor Coreの詳細な制御
  • アルゴリズムの選択(ヒューリスティクス or 手動指定)
  • エピローグ(後処理)のフュージョン

cuBLASXt

複数GPUでの分散処理に対応。

cuBLASMp(Preview)

マルチノード・マルチGPU環境向け。HPCクラスタで使う。

cuBLASDx(Preview)

CUDAカーネル内で直接呼び出せる「デバイスサイド」版。

"cuBLASDx (Preview) is a device side API extension to cuBLAS for performing BLAS calculations inside your CUDA kernel. Fusing numerical operations decreases the latency and improves the performance of your application."

「cuBLASDx(プレビュー)は、CUDAカーネル内でBLAS計算を行うためのcuBLASのデバイスサイドAPI拡張である。数値演算のフュージョンにより、レイテンシが低下しアプリケーションのパフォーマンスが向上する。」

— NVIDIA cuBLAS (https://developer.nvidia.com/cublas)


5. なぜ自作せずにcuBLASを使うべきか

「書けるけど、書くべきではない」

Stack Overflowでよく見る質問に「行列積くらい自分で書けるのでは?」というものがある。

答えは明確だ: 書けるが、書くべきではない

"It will be optimised. NVIDIA supported libraries such as cuBLAS are likely to be optimised for all current GPU generations, and later releases will be optimised for later generations. While most BLAS operations may seem fairly simple to implement, to get peak performance you have to optimise for hardware (this is not unique to GPUs). A simple implementation of SGEMM, for example, may be many times slower than an optimised version."

「最適化されている。cuBLASのようなNVIDIAサポートのライブラリは、現行のすべてのGPU世代に最適化されている可能性が高く、将来のリリースは将来の世代に最適化されるだろう。ほとんどのBLAS操作は実装が簡単に見えるかもしれないが、ピークパフォーマンスを得るにはハードウェアに最適化する必要がある(これはGPUに限った話ではない)。例えば、SGEMMの単純な実装は、最適化されたバージョンより何倍も遅くなりうる。」

— Stack Overflow (https://stackoverflow.com/questions/25836003/normal-cuda-vs-cublas)

cuBLASを使うべき理由

  1. 最適化の深さ
    NVIDIAのエンジニアは、自社GPUのハードウェア詳細を完全に把握している。メモリアクセスパターン、キャッシュの挙動、Tensor Coreの活用法など、ドキュメントに書かれていないレベルの最適化が施されている。

  2. 世代間の対応
    新しいGPUアーキテクチャが出るたびに、cuBLASも自動的に最適化される。自作コードでは、新GPUごとにチューニングが必要になる。

  3. 信頼性

"They tend to work. There's probably less chance you'll run up against a bug in a library then you'll create a bug in your own implementation which bites you when you change some parameter or other in the future."

「ちゃんと動く。ライブラリにバグがある確率より、自作実装で何かのパラメータを変えたときにバグを踏む確率の方が高いだろう。」

— Stack Overflow (https://stackoverflow.com/questions/25836003/normal-cuda-vs-cublas)

  1. 開発時間の節約
    車輪の再発明をせず、本来解決すべき問題に集中できる。

6. cuBLASの使い方(基本)

初期化と終了

#include <cublas_v2.h>

cublasHandle_t handle;
cublasCreate(&handle);

// ... cuBLAS操作 ...

cublasDestroy(handle);

SGEMM(単精度行列積)の例

// C = α * A * B + β * C
float alpha = 1.0f;
float beta = 0.0f;

cublasSgemm(handle,
    CUBLAS_OP_N, CUBLAS_OP_N,  // 転置なし
    m, n, k,                     // 行列サイズ
    &alpha,
    d_A, lda,                    // 行列A(デバイスメモリ)
    d_B, ldb,                    // 行列B
    &beta,
    d_C, ldc);                   // 結果C

PyTorchからの利用

PyTorchでは、行列演算が自動的にcuBLASを使う:

import torch

# GPU上で行列積を計算(内部でcuBLASが呼ばれる)
A = torch.randn(1000, 1000, device='cuda')
B = torch.randn(1000, 1000, device='cuda')
C = torch.mm(A, B)  # cuBLASのGEMMが使われる

7. パフォーマンス最適化のヒント

行列サイズは8の倍数に

Tensor Coreを効率的に使うには、行列の次元が8の倍数である必要がある。

"We recommend ensuring all such parameters are multiples of 8 when training with FP16 and multiples of 16 when training with INT8."

「FP16で訓練する場合は、これらのパラメータがすべて8の倍数であることを、INT8で訓練する場合は16の倍数であることを推奨する。」

— NVIDIA Developer Blog (https://developer.nvidia.com/blog/optimizing-gpu-performance-tensor-cores/)

混合精度の活用

FP16(半精度)を使うと:

  • Tensor Coreが効率的に動作
  • メモリ使用量が半減
  • 帯域幅ネックが緩和
# PyTorchでの混合精度
with torch.cuda.amp.autocast():
    output = model(input)

バッチ処理

小さな行列を多数処理する場合は、「バッチGEMM」を使う。1回の呼び出しで複数の行列積を同時に実行でき、オーバーヘッドが削減される。


8. 決定論性と再現性

科学計算や一部のAIアプリケーションでは、「同じ入力に対して常に同じ結果」が求められる。

"By design, all cuBLAS API routines from a given toolkit version, generate the same bit-wise results at every run when executed on GPUs with the same architecture and the same number of SMs. However, bit-wise reproducibility is not guaranteed across toolkit versions because the implementation might differ due to some implementation changes."

「設計上、特定のToolkitバージョンのcuBLAS APIルーチンは、同じアーキテクチャで同じ数のSMを持つGPU上で実行される場合、毎回同じビット単位の結果を生成する。ただし、Toolkitバージョン間ではビット単位の再現性は保証されない。実装の変更により実装が異なる可能性があるためだ。」

— cuBLAS Documentation (https://docs.nvidia.com/cuda/cublas/)

注意点:

  • 同じToolkitバージョン・同じGPUなら再現可能
  • Toolkitバージョンをまたぐと結果が変わる可能性あり
  • 複数ストリームを使うと非決定的になりうる

9. よくあるエラーと対処法

CUBLAS_STATUS_EXECUTION_FAILED

cuBLAS error: CUBLAS_STATUS_EXECUTION_FAILED

原因:

  • メモリ不足
  • 不正なポインタ
  • CUDAバージョンとcuBLASの不整合

対処:

# GPUメモリの確認
nvidia-smi

# CUDAバージョンの確認
nvcc --version

CUBLAS_STATUS_NOT_INITIALIZED

ハンドルが初期化されていない。cublasCreate()を呼んでいるか確認。

CUBLAS_STATUS_INVALID_VALUE

引数が不正。行列サイズ、ストライド、ポインタを確認。


10. まとめ

cuBLASは、50年の歴史を持つBLAS仕様をGPU向けに最適化した、行列演算の「縁の下の力持ち」だ。

  • BLAS: 1979年から続く線形代数演算の標準仕様
  • cuBLAS: NVIDIAがGPU向けに最適化した実装
  • GEMM: 最も重要な操作。ディープラーニングの核心
  • Tensor Core対応: 混合精度で劇的な高速化
  • 使うべき理由: 最適化の深さ、信頼性、開発効率

PyTorchやTensorFlowを使っていれば、cuBLASは自動的に呼ばれる。しかし、その存在を知っていることで、パフォーマンス問題の診断やチューニングがずっと楽になる。

次回は、ディープラーニング専用の最適化ライブラリ「cuDNN」を解説する。cuBLASが「汎用的な行列演算」を担当するのに対し、cuDNNは「ニューラルネットワーク固有の操作」を高速化する。


参考資料

公式ドキュメント

BLAS関連

パフォーマンス最適化


シリーズ記事

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?