optimize-for-gpu について
このスキルは、数値計算、データ処理、機械学習、画像処理、シミュレーション向けにNVIDIA GPUライブラリを選び、Pythonコードを適応させる開発者を支援します。タスク別にCuPy、Numba CUDA、Warp、cuDFなどを選ぶための指針を示します。
主な機能
- 01処理内容に応じたGPUライブラリ選定
- 02NumPyとSciPyの高速化ガイド
- 03カスタムCUDAカーネルへの対応
- 04DataFrameと機械学習の支援
- 05グラフ、画像、ベクトル処理の対象
- 06GPU I/Oとシミュレーションの選択肢
活用シーン
- 01NumPy中心の数値コードの高速化
- 02pandasまたはscikit-learn処理の移行
- 03GPUグラフ分析用ツールの選定
- 04シミュレーションコードのNVIDIA GPU対応
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ crazymsn/ academic-skills --skill optimize-for-gpuインストール後、Claude Code で/optimize-for-gpuを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/cucim.mdcudf.mdcugraph.mdcuml.mdcupy.mdcuspatial.mdcuvs.mdcuxfilter.mdkvikio.mdnumba.mdraft.mdwarp.md詳細
NVIDIA GPU 向け Python の最適化
あなたは GPU 最適化の専門エンジニアです。ユーザーが新しい GPU アクセラレーションコードを作成したり、既存の CPU 処理が中心の Python コードを NVIDIA GPU 上で実行できるよう変換したりして、適切なワークロードで多くの場合 10 倍から 1000 倍の大幅な高速化を実現できるよう支援します。
このスキルが適用される場面
- ユーザーが数値計算や科学技術計算向けの Python コードを高速化したい
- ユーザーが大規模な配列、行列、またはデータフレームを扱っている
- ユーザーが CUDA、GPU、NVIDIA、または並列コンピューティングに言及している
- ユーザーが大規模なデータセットを処理する NumPy、pandas、SciPy、scikit-learn、NetworkX、または scipy.sparse.linalg のコードを使用している
- ユーザーが低レベルの GPU プリミティブ(疎行列固有値ソルバー、デバイスメモリ管理、マルチ GPU 通信)を必要としている
- ユーザーが機械学習(トレーニング、推論、ハイパーパラメータ調整、前処理)を行っている
- ユーザーがグラフ分析(中心性、コミュニティ検出、最短経路、PageRank など)を行っている
- ユーザーがベクトル検索、最近傍検索、類似性検索、または RAG パイプラインの構築を行っている
- GPU で高速化できる可能性のある Faiss、Annoy、ScaNN、または sklearn NearestNeighbors のコードを使用している
- ユーザーが大規模なデータセットを対象に、GPU アクセラレーション対応のインタラクティブなダッシュボード、クロスフィルタリング、または探索的データ分析を行いたい
- ユーザーが GeoPandas または shapely を使って地理空間分析(点のポリゴン内判定、空間結合、軌跡分析、距離計算)を行っている
- ユーザーが scikit-image または OpenCV を使って画像処理、コンピュータビジョン、または医用画像処理(フィルタリング、セグメンテーション、モルフォロジー、特徴検出)を行っている
- ユーザーが全スライド画像(WSI)、デジタル病理学、顕微鏡画像、またはリモートセンシング画像を扱っている
- ユーザーが大規模なバイナリデータファイルを GPU メモリに読み込んでいる(numpy.fromfile → cupy、または Python open() → GPU 配列)
- ユーザーが S3、HTTP、または WebHDFS からファイルを直接 GPU メモリに読み込む必要がある
- ユーザーが GPUDirect Storage(GDS)に言及している、またはファイル I/O で CPU メモリへの一時格納を回避したい
- ユーザーが物理シミュレーション(粒子、布、流体、剛体)または微分可能シミュレーションを行っている
- ユーザーが GPU 上でメッシュ演算(レイキャスティング、最近点クエリ、符号付き距離場)またはジオメトリ処理を必要としている
- ユーザーが変換行列やクォータニオンを使ったロボティクス(運動学、動力学、制御)を行っている
- ユーザーが GPU カーネルに JIT コンパイルできる Python のシミュレーションループを持っている
- ユーザーが NVIDIA Warp に言及している、または PyTorch/JAX と統合された微分可能な GPU シミュレーションを必要としている
- ユーザーがシミュレーション、信号処理、金融モデリング、バイオインフォマティクス、物理学、またはその他の計算負荷の高い処理を行っている
- 既存のコードを最適化したいユーザーにとって、GPU アクセラレーションが適切な解決策である
判断の枠組み:使用するライブラリの選択
ユーザーのコードが実際に何を行うかに応じて、適切なツールを選んでください。GPU コードを書く前に、該当するリファレンスファイルを読んでください。
CuPy — 配列/行列演算向け(NumPy の代替)
参照: references/cupy.md
ユーザーのコードの主な処理が以下の場合は CuPy を使用してください。
- NumPy の配列演算(要素ごとの数学演算、線形代数、FFT、ソート、リダクション)
- SciPy の演算(疎行列、信号処理、画像フィルタリング、特殊関数)
- NumPy の呼び出しを連結するあらゆるコード — CuPy はそのまま置き換えられます
CuPy は NVIDIA の最適化済みライブラリ(cuBLAS、cuFFT、cuSOLVER、cuSPARSE、cuRAND)をラップしているため、標準的な演算はすでに最適化されています。ほとんどの NumPy コードは、import numpy as np を import cupy as cp に変更するだけで動作します。
最適な用途: 線形代数、FFT、配列演算、画像処理、信号処理、配列演算を使ったモンテカルロ法、NumPy を多用するあらゆるワークフロー。
Numba CUDA — カスタム GPU カーネル向け
参照: references/numba.md
ユーザーに次のニーズがある場合は、Numba を使用します。
- 標準的な配列操作では表現できないカスタムアルゴリズム
- GPU スレッド、ブロック、共有メモリのきめ細かな制御
- 複雑なロジックを含む要素単位の操作(
@vectorize(target='cuda')を使用) - カスタムロジックを使ったリダクション操作
- ステンシル計算や近傍に依存する計算
- CUDA プログラミングモデルを直接使う必要がある処理
Numba は Python を CUDA カーネルに直接コンパイルします。GPU のスレッド階層、共有メモリ、同期を完全に制御できるため、配列操作では表現できないアルゴリズムに不可欠です。
最適な用途: カスタムカーネル、粒子シミュレーション、ステンシルコード、カスタムリダクション、共有メモリを必要とするアルゴリズム、要素ごとに複雑なロジックを含むコード。
Warp — シミュレーション、空間コンピューティング、微分可能プログラミング向け
参照: references/warp.md
ユーザーのコードが主に次の用途である場合は、Warp を使用します。
- 物理シミュレーション(粒子、布、流体、剛体、DEM、SPH)
- ジオメトリ処理(メッシュ操作、レイキャスティング、符号付き距離場、マーチングキューブ)
- ロボティクス(変換やクォータニオンを使用した運動学、動力学、制御)
- ML トレーニング向けの微分可能シミュレーション(PyTorch/JAX の autograd と統合)
- GPU 向けに JIT コンパイルする必要がある Python のシミュレーションループ
- メッシュ、ボリューム(NanoVDB)、ハッシュグリッド、BVH クエリを使う空間コンピューティング
Warp は @wp.kernel Python 関数を CUDA に JIT コンパイルします。空間コンピューティング用の組み込み型(vec3、mat33、quat、transform)と、ジオメトリクエリ用のプリミティブ(Mesh、Volume、HashGrid、BVH)を備えています。すべてのカーネルは自動的に微分可能です。
最適な用途: 物理シミュレーション、メッシュのレイキャスティング、粒子システム、微分可能レンダリング、ロボティクスの運動学、SDF 操作、空間データ構造と GPU 計算を組み合わせるあらゆるワークロード。
Warp と Numba の比較: どちらも Python を CUDA にコンパイルしますが、Warp は高水準の空間型(vec3、quat、Mesh、Volume)と自動微分を提供する一方、Numba は生の CUDA を直接制御できます(共有メモリ、ブロック/スレッド管理、アトミック操作)。シミュレーションやジオメトリには Warp、汎用のカスタムカーネルには Numba を使用します。
cuDF — DataFrame 操作向け(pandas の置き換え)
参照: references/cudf.md
ユーザーのコードが主に次の用途である場合は、cuDF を使用します。
- pandas の DataFrame 操作(フィルタリング、groupby、結合、集計)
- CSV/Parquet/JSON の読み込みと処理
- 大規模データセットに対する ETL パイプラインやデータ加工
- GPU メモリに収まるデータセットを扱う、pandas 中心のワークフロー
cuDF の cudf.pandas アクセラレータモードを使うと、コードを変更せずに既存の pandas コードを高速化できます。最高のパフォーマンスを得るには、ネイティブの cuDF API を使用してください。
最適な用途: データ加工、ETL、groupby/集計、結合、DataFrame の文字列処理、表形式データの時系列処理。
cuML — 機械学習向け(scikit-learn の置き換え)
参照: references/cuml.md
ユーザーのコードが主に次の用途である場合は、cuML を使用します。
- scikit-learn の推定器(分類、回帰、クラスタリング、次元削減)
- ML の前処理(スケーリング、エンコーディング、欠損値補完、特徴抽出)
- ハイパーパラメーターの調整や交差検証
- 決定木モデルの推論(XGBoost、LightGBM、FIL 経由の sklearn Random Forest)
- 大規模データセットに対する UMAP、t-SNE、HDBSCAN、KNN
cuML の cuml.accel アクセラレータモードを使うと、コードを変更せずに既存の sklearn コードを高速化できます。最高のパフォーマンスを得るには、ネイティブの cuML API を使用してください。高速化の倍率は、単純な線形モデルでは 2~10 倍、HDBSCAN や KNN などの複雑なアルゴリズムでは 60~600 倍です。
最適な用途: 分類、回帰、クラスタリング、次元削減、前処理パイプライン、モデル推論、scikit-learn 中心のあらゆるワークフロー。
cuGraph — グラフ分析向け(NetworkX の置き換え)
参照: references/cugraph.md
ユーザーのコードが主に次の内容を扱う場合は、cuGraph を使用します。
- NetworkX のグラフアルゴリズム(中心性、コミュニティ検出、最短経路、PageRank)
- 大規模ネットワークのグラフ構築と分析
- ソーシャルネットワーク分析、ナレッジグラフ、推薦システム
- 1 万以上のエッジを持つネットワーク上のグラフアルゴリズム全般
cuGraph の nx-cugraph バックエンドは、環境変数を使うことで、コードを一切変更せずに既存の NetworkX コードを高速化できます。最大限のパフォーマンスを得るには、cuDF DataFrame とネイティブの cuGraph API を使用してください。高速化の度合いは、小規模なグラフで 10 倍、大規模なグラフ(数百万のエッジ)で 500 倍以上です。
最適な用途: PageRank、媒介中心性、コミュニティ検出(Louvain、Leiden)、BFS/SSSP、連結成分、リンク予測、グラフニューラルネットワークのサンプリング、NetworkX を多用するあらゆるワークフロー。
KvikIO — 高性能な GPU ファイル I/O 向け
参照: references/kvikio.md
ユーザーのコードが主に次の内容を扱う場合は、KvikIO を使用します。
- 大容量のバイナリデータファイルを GPU メモリに直接読み込む
- GPU 配列をホストにコピーせずにディスクへ書き込む
- リモートストレージ(S3、HTTP、WebHDFS)から GPU メモリへデータを読み込む
- GPU 上で Zarr 配列を扱う(GDSStore バックエンド)
- ストレージと GPU の間のファイル I/O がボトルネックとなるあらゆるパイプライン
KvikIO は NVIDIA cuFile の Python バインディングを提供し、GPUDirect Storage(GDS)を利用できるようにします。これにより、CPU メモリを完全に迂回して、NVMe ストレージと GPU メモリの間でデータを直接転送できます。GDS を利用できない場合は、透過的に POSIX I/O にフォールバックします。ホストデータとデバイスデータの両方をシームレスに扱えます。
最適な用途: バイナリデータの GPU への読み込み、GPU 配列のディスクへの保存、S3/HTTP から GPU への直接読み込み、GPU 上の Zarr 配列、numpy.fromfile() → cupy パターンの置き換え、CPU メモリを介したデータ転送がボトルネックとなる、I/O 負荷の高いあらゆる GPU パイプライン。
注: CSV、Parquet、JSON などの表形式データには、cuDF の組み込みリーダーを使用してください。これらの形式に最適化されています。KvikIO は、生のバイナリデータとリモートファイルへのアクセス向けです。
cuxfilter — GPU 高速化によるインタラクティブなダッシュボード向け
参照: references/cuxfilter.md
ユーザーが次のことを必要としている場合は、cuxfilter を使用します。
- 大規模なデータセット(数百万行)を対象とした、インタラクティブなクロスフィルタリングダッシュボード
- 相互に絞り込みを行う連携チャートを使った探索的データ分析
- 散布図、棒グラフ、ヒートマップ、コロプレスマップ、グラフ可視化による GPU 高速化ビジュアライゼーション
- 最小限のコードで Jupyter ノートブックからダッシュボードを試作する
- cuDF、cuML、cuGraph のパイプラインの結果を可視化する
cuxfilter は、GPU 上のすべてのデータ操作に cuDF を活用します。フィルタリング、groupby、集計はすべて GPU 上で行われ、ブラウザーへ送信されるのは描画結果のみです。Bokeh、Datashader(数百万のデータポイント向け)、Deck.gl(地図向け)、Panel ウィジェットと統合できます。
最適な用途: インタラクティブなデータ探索ダッシュボード、複数チャートのクロスフィルタリング、地理空間データの可視化、グラフの可視化、RAPIDS パイプラインの結果の可視化、大規模な GPU メモリ常駐データセットをインタラクティブに探索・絞り込みする必要があるあらゆるシナリオ。
cuCIM — 画像処理向け(scikit-image の代替)
参照: references/cucim.md
ユーザーのコードが主に以下を行う場合は、cuCIM を使用してください。
- scikit-image の操作(フィルタリング、モルフォロジー、セグメンテーション、特徴検出、色変換)
- ディープラーニング向けの画像前処理パイプライン(リサイズ、正規化、データ拡張)
- デジタル病理学(大規模スライド画像の読み込み、H&E 染色の正規化、細胞数のカウント)
- 顕微鏡、リモートセンシング、医用画像処理のワークフロー
- 512x512 以上の画像を処理する、scikit-image を多用するパイプライン
cuCIM の cucim.skimage モジュールは、scikit-image の API を反映した、GPU で高速化された 200 以上の関数を備えています。また、OpenSlide より 5-6x 高速な高性能 WSI リーダー(CuImage)も提供します。すべての関数は CuPy 配列に対応しており、ゼロコピーですべての処理を GPU 上で行います。
最適な用途: フィルタリング(Gaussian、Sobel、Frangi)、モルフォロジー、しきい値処理、連結成分のラベリング、領域特性、色空間変換、画像レジストレーション、ノイズ除去、大規模スライド画像処理、DL 前処理パイプライン。
cuVS — ベクトル検索向け(Faiss/Annoy の代替)
参照: references/cuvs.md
ユーザーのコードが主に以下を行う場合は、cuVS を使用してください。
- 高次元ベクトルに対する近似最近傍(ANN)検索
- RAG、レコメンダーシステム、セマンティック検索のための類似性検索
- クラスタリングや可視化向けの k-NN グラフ構築
- 大規模な埋め込みデータセットに対する Faiss、Annoy、ScaNN、または sklearn NearestNeighbors のワークロード
cuVS は、GPU で高速化された ANN インデックスの種類(CAGRA、IVF-Flat、IVF-PQ、ブルートフォース)に加え、GPU で構築したインデックスを CPU でサービングするための HNSW を提供します。Faiss、Milvus、Lucene の GPU バックエンドを支えています。ほとんどのユースケースでは CAGRA から始めてください。GPU ネイティブアルゴリズムの中で最速です。
最適な用途: 埋め込み検索、RAG 検索、レコメンダーシステム、画像/テキスト/音声の類似性検索、k-NN グラフ構築、10K+ 個のベクトルに対する最近傍検索のワークロード。
cuSpatial — 地理空間分析向け(GeoPandas の代替)
参照: references/cuspatial.md
ユーザーのコードが主に以下を行う場合は、cuSpatial を使用してください。
- GeoPandas の空間操作(ポイント・イン・ポリゴン、空間結合、距離計算)
- 軌跡分析(GPS の軌跡のグループ化、速度/距離の計算)
- 大規模な空間結合向けの空間インデックス(クアッドツリー)
- 緯度/経度座標に対するハバーサイン距離の計算
- 大規模な地理空間データセットに対する、GeoPandas/shapely を多用するワークフロー
cuSpatial は、GeoPandas と互換性のある GPU 高速化 GeoSeries と GeoDataFrame の型に加え、空間結合、距離、軌跡の各関数を提供します。cuspatial.from_geopandas() で GeoPandas から変換できます。
最適な用途: ポイント・イン・ポリゴンテスト、数百万のポイント/ポリゴンを対象とする空間結合、ハバーサイン距離とユークリッド距離の計算、軌跡の再構築と分析、GeoPandas を多用する地理空間ワークフロー。
RAFT(pylibraft)— 低レベルの GPU プリミティブとマルチ GPU 向け
参照: references/raft.md
ユーザーが以下を必要とする場合は、RAFT を使用してください。
- GPU で高速化されたスパース固有値問題(
scipy.sparse.linalg.eigshの代替) - 低レベルの GPU デバイスメモリ管理(
device_ndarray) - ランダムグラフ生成(ベンチマーク用 R-MAT モデル)
- マルチノード・マルチ GPU 通信基盤(
raft-dask経由) - 高レベルの RAPIDS ライブラリを支える構成要素
RAFT は、cuML と cuGraph の基盤となるプリミティブを提供します。ほとんどのユーザーは、まずこれらの高レベルライブラリを利用してください。RAFT が提供する特定のプリミティブ(スパース固有値ソルバー、デバイスメモリ、グラフ生成)や、Dask 経由のマルチ GPU 通信が必要な場合に、RAFT を直接使用してください。
最適な用途: スパース固有値分解(スペクトル法、グラフ分割)、R-MAT グラフ生成、低レベルのデバイスメモリ管理、マルチ GPU オーケストレーション。
注: ベクトル検索アルゴリズム(k-NN、IVFPQ、CAGRA)は cuVS に移行しました。ベクトル検索に RAFT を使用しないでください。
ライブラリの組み合わせ
多くの実際のワークロードでは、複数のライブラリを組み合わせると効果的です。CUDA Array Interface を介して相互運用でき、CuPy、Numba、Warp、cuDF、cuML、cuGraph、cuVS、cuCIM、cuSpatial、KvikIO、PyTorch、JAX、その他の GPU ライブラリ間でデータをゼロコピーで共有できます。
一般的な組み合わせ:
- cuDF + cuML:cuDF でデータを読み込み、前処理を行い、cuML で学習・予測します。RAPIDS のパイプライン全体を構成できます。
- cuDF + cuGraph:cuDF のエッジリストからグラフを構築し、cuGraph でグラフ分析を実行します。
- cuGraph + cuML:cuGraph でグラフの特徴量を抽出し、cuML に渡して機械学習を行います。
- cuML + cuVS:cuML で埋め込みモデルを学習し、cuVS で埋め込みのインデックス作成と検索を行います。
- cuDF + CuPy:cuDF でデータを読み込み、フィルタリングした後、CuPy で数値解析を行います。
- CuPy + cuVS:CuPy の演算で埋め込みを生成し、cuVS の検索インデックスを構築します。ゼロコピーで連携できます。
- Warp + PyTorch:Warp で微分可能なシミュレーションを行い、勾配を PyTorch の学習ループに逆伝播します。
- Warp + CuPy:配列演算には CuPy を、空間クエリ(メッシュ、ボリューム)には Warp を使用します。CUDA Array Interface を介してゼロコピーで連携できます。
- Warp + JAX:JIT コンパイルされた関数内で、Warp カーネルを JAX のプリミティブとして使用します。
- CuPy + Numba:標準的な演算には CuPy を使用し、カスタムカーネルには Numba を使用します。
- cuDF + Numba:cuDF でデータフレームを処理し、Numba の UDF でカスタム GPU 関数を適用します。
- cuML + CuPy:cuML で学習し、CuPy でカスタムの後処理を行います。
- cuDF + cuxfilter:cuDF でデータを読み込み、cuxfilter でインタラクティブなクロスフィルタリングダッシュボードを構築します。
- cuML + cuxfilter:cuML で機械学習(UMAP、クラスタリングなど)を実行し、cuxfilter で結果をインタラクティブに可視化します。
- cuGraph + cuxfilter:cuGraph でグラフ分析を実行し、cuxfilter の datashader グラフチャートでグラフ構造を可視化します。
- cuCIM + CuPy:cuCIM は CuPy 配列をネイティブに処理できます。画像処理と配列演算を連続して実行できます。
- cuCIM + PyTorch:cuCIM で画像を前処理し、DLPack を介して PyTorch に直接渡します。ゼロコピーで連携できます。
- cuCIM + cuML:cuCIM(regionprops)で画像の特徴量を抽出し、cuML で分類器を学習します。
- KvikIO + CuPy:GDS を介して生のバイナリデータを CuPy 配列に直接読み込み、CPU メモリを介さずに処理します。
- KvikIO + Numba:KvikIO で GPU にデータを直接読み込み、カスタムの Numba CUDA カーネルで処理します。
- KvikIO + Zarr:GDSStore バックエンドを使用して、チャンク化された N 次元配列を GPU 上で直接読み書きします。
- cuSpatial + cuDF:cuDF で地理空間データを読み込み、cuSpatial で空間結合・分析を行います。
- cuSpatial + cuML:cuSpatial で空間特徴量を抽出し、cuML で機械学習モデルを学習します。
- RAFT + CuPy:CuPy/cupyx.scipy.sparse で構築した疎行列に対して、RAFT の eigsh() を使用します。
- RAFT + raft-dask:Dask を介して、複数の GPU/ノードにわたり GPU ワークロードをスケールします。
インストール
重要:パッケージのインストールには、必ず uv add を使用してください。pip install や conda install は使用しないでください。このルールは、コードコメント、docstring、エラーメッセージ、その他に生成するあらゆる出力のインストール手順に適用されます。ユーザーのプロジェクトが別のパッケージマネージャーを使用している場合は、それに従ってください。特に指定がなければ、uv add を使用してください。
# CuPy (choose the right CUDA version)
uv add cupy-cuda12x # For CUDA 12.x (most common)
# Numba with CUDA support
uv add numba numba-cuda # numba-cuda is the actively maintained NVIDIA package
# Warp (simulation, spatial computing, differentiable programming)
uv add warp-lang # CUDA 12 runtime included
# cuDF (RAPIDS)
uv add --extra-index-url=https://pypi.nvidia.com cudf-cu12 # For CUDA 12.x
# For cudf.pandas accelerator mode, that's all you need
# Load it with: python -m cudf.pandas your_script.py
# cuML (RAPIDS machine learning)
uv add --extra-index-url=https://pypi.nvidia.com cuml-cu12 # For CUDA 12.x
# For cuml.accel accelerator mode (zero-change sklearn acceleration):
# Load it with: python -m cuml.accel your_script.py
# cuGraph (RAPIDS graph analytics)
uv add --extra-index-url=https://pypi.nvidia.com cugraph-cu12 # Core cuGraph
uv add --extra-index-url=https://pypi.nvidia.com nx-cugraph-cu12 # NetworkX backend
# For nx-cugraph zero-change NetworkX acceleration:
# NX_CUGRAPH_AUTOCONFIG=True python your_script.py
# KvikIO (high-performance GPU file IO)
uv add kvikio-cu12 # For CUDA 12.x
# Optional: uv add zarr # For Zarr GPU backend support
# cuxfilter (GPU-accelerated interactive dashboards)
uv add --extra-index-url=https://pypi.nvidia.com cuxfilter-cu12 # For CUDA 12.x
# Depends on cuDF — installs it automatically
# cuCIM (RAPIDS image processing — scikit-image on GPU)
uv add --extra-index-url=https://pypi.nvidia.com cucim-cu12 # For CUDA 12.x
# cuVS (RAPIDS vector search)
uv add --extra-index-url=https://pypi.nvidia.com cuvs-cu12 # For CUDA 12.x
# cuSpatial (RAPIDS geospatial)
uv add --extra-index-url=https://pypi.nvidia.com cuspatial-cu12 # For CUDA 12.x
# RAFT (low-level GPU primitives)
uv add --extra-index-url=https://pypi.nvidia.com pylibraft-cu12 # Core primitives
uv add --extra-index-url=https://pypi.nvidia.com raft-dask-cu12 # Multi-GPU support (optional)
インストール後に CUDA が利用可能か確認するには、次のようにします。
# CuPy
import cupy as cp
print(cp.cuda.runtime.getDeviceCount()) # Should be >= 1
# Numba
from numba import cuda
print(cuda.is_available()) # Should be True
print(cuda.detect()) # Shows GPU details
# cuDF
import cudf
print(cudf.Series([1, 2, 3])) # Should print a GPU series
# cuML
import cuml
print(cuml.__version__) # Should print version
# cuGraph
import cugraph
print(cugraph.__version__) # Should print version
# Warp
import warp as wp
wp.init() # Should print device info
# KvikIO
import kvikio
import kvikio.cufile_driver
print(kvikio.cufile_driver.get("is_gds_available")) # True if GDS is set up
# cuxfilter
import cuxfilter
print(cuxfilter.__version__) # Should print version
# cuVS
from cuvs.neighbors import cagra
import cupy as cp
dataset = cp.random.rand(1000, 128, dtype=cp.float32)
index = cagra.build(cagra.IndexParams(), dataset)
print("cuVS working") # Should print confirmation
# cuSpatial
import cuspatial
from shapely.geometry import Point
gs = cuspatial.GeoSeries([Point(0, 0)])
print("cuSpatial working") # Should print confirmation
# RAFT (pylibraft)
from pylibraft.common import DeviceResources
handle = DeviceResources()
handle.sync()
print("pylibraft is working")
最適化ワークフロー
ユーザーのコード最適化を支援する際は、次の手順に従ってください。
1. まずプロファイリングする
最適化の前に、実際にどこで時間がかかっているかを把握します。
import time
# or use cProfile, line_profiler, or py-spy for detailed profiling
推測せず、測定してください。ボトルネックは、ユーザーが考えている箇所とは限りません。
2. GPU に適しているか評価する
すべてのコードが GPU アクセラレーションの恩恵を受けるわけではありません。GPU が優れているのは、次のような場合です。
- データ並列性が高い:数千から数百万の要素に同じ演算を適用する
- 計算密度が高い:アクセスするメモリ 1 バイトあたりの FLOP 数が多い
- データが十分に大きい:GPU のオーバーヘッドにより、小さな配列(< ~10K 要素)では GPU のほうが遅くなる場合がある
- メモリに収まる:データが GPU メモリに収まる必要がある(通常 8-80 GB)
GPU に適さないのは、次のような場合です。
- データが非常に小さい(< 10K 要素)
- アルゴリズムが本質的に逐次処理で、各ステップ間にデータ依存関係がある
- コードが計算ではなく、ディスクやネットワークなどの I/O に制約されている。ただし、GPU 計算にデータを供給する際は、GPUDirect Storage を使用した KvikIO が役立つ場合があります
- 小規模で異種の演算が多数ある(カーネル起動のオーバーヘッドが支配的になる)
3. まずはシンプルに始め、その後最適化する
- まずはドロップイン置換を試してください。 NumPy には CuPy、pandas には cudf.pandas、sklearn には cuml.accel、NetworkX には nx-cugraph を使います。これだけで 5-50 倍の高速化が得られることもよくあります。
- ホストとデバイス間の転送を最小限に抑えてください。 データは GPU 上に保持します。PCI-e 経由の転送は、GPU メモリ帯域幅(~900 GB/s 以上)に比べて、毎回コストがかかります(~12 GB/s)。
- 演算をバッチ処理してください。 小さな GPU 演算を多数行うより、大きな演算を少数行うほうが高速です。
- 必要な場合にのみカスタムカーネルを書いてください。 CuPy と cuDF は、NVIDIA の調整済みライブラリを使用します。カスタム Numba カーネルは、ライブラリに同等の機能がない演算に限って使用してください。
- GPU 版のプロファイルを取得してください。
nvprof、nsys、または CuPy に組み込まれているベンチマーク機能を使用します。
4. メモリ管理の原則
これらはすべてのライブラリに共通して適用されます。
- ループ内で新しい配列を作成するのではなく、出力配列を事前に確保する
- GPU メモリを再利用する — メモリプールを使用する(CuPy には標準で組み込まれています)
- CPU-GPU 間の転送を高速化するため、ピン留めされた(ページロックされた)ホストメモリを使用する
- 不要なコピーを避ける — 可能な場合はインプレース演算を使用する
- 計算とデータ転送を重ね合わせるため、ストリーム演算を使用する
5. 注意すべきよくある落とし穴
- 暗黙的な CPU フォールバック:一部の演算は、気付かないうちに CPU にフォールバックします。警告に注意してください。
- 同期のオーバーヘッド:GPU 演算は非同期です。
.get()やcp.asnumpy()を呼び出すと同期が強制されます。 - dtype の不一致:精度が許容される場合は、
float64ではなくfloat32を使用してください。GPU の float32 スループットは 2x-32x 高くなります。 - 小規模なカーネル起動:カーネルの起動ごとに ~5-20us のオーバーヘッドが発生します。可能な場合は演算を融合してください。
コード変換パターン
既存の CPU コードを変換する場合は、次のパターンを適用してください。
NumPy から CuPy へ
# Before (CPU)
import numpy as np
a = np.random.rand(10_000_000)
b = np.fft.fft(a)
c = np.sort(b.real)
# After (GPU) — often just change the import
import cupy as cp
a = cp.random.rand(10_000_000)
b = cp.fft.fft(a)
c = cp.sort(b.real)
pandas から cuDF へ
# Before (CPU)
import pandas as pd
df = pd.read_parquet("large_data.parquet")
result = df.groupby("category")["value"].mean()
# After (GPU) — change the import
import cudf
df = cudf.read_parquet("large_data.parquet")
result = df.groupby("category")["value"].mean()
# Or zero-code-change: python -m cudf.pandas your_script.py
カスタムループから Numba CUDA カーネルへ
# Before (CPU) — slow Python loop
def process(data, out):
for i in range(len(data)):
out[i] = math.sin(data[i]) * math.exp(-data[i])
# After (GPU) — Numba kernel
from numba import cuda
import math
@cuda.jit
def process(data, out):
i = cuda.grid(1)
if i < data.size:
out[i] = math.sin(data[i]) * math.exp(-data[i])
threads = 256
blocks = (len(data) + threads - 1) // threads
process[blocks, threads](d_data, d_out)
NetworkX から cuGraph へ
# Before (CPU)
import networkx as nx
G = nx.read_edgelist("edges.csv", delimiter=",", nodetype=int)
pr = nx.pagerank(G)
bc = nx.betweenness_centrality(G)
# After (GPU) — direct cuGraph API
import cugraph
import cudf
edges = cudf.read_csv("edges.csv", names=["src", "dst"], dtype=["int32", "int32"])
G = cugraph.Graph()
G.from_cudf_edgelist(edges, source="src", destination="dst")
pr = cugraph.pagerank(G)
bc = cugraph.betweenness_centrality(G)
# Or zero-code-change: NX_CUGRAPH_AUTOCONFIG=True python your_script.py
scikit-learn から cuML へ
# Before (CPU)
from sklearn.ensemble import RandomForestClassifier
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)
scaler = StandardScaler()
X_train = scaler.fit_transform(X_train)
model = RandomForestClassifier(n_estimators=100)
model.fit(X_train, y_train)
# After (GPU) — change the imports
from cuml.ensemble import RandomForestClassifier
from cuml.preprocessing import StandardScaler
from cuml.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)
scaler = StandardScaler()
X_train = scaler.fit_transform(X_train)
model = RandomForestClassifier(n_estimators=100)
model.fit(X_train, y_train)
# Or zero-code-change: python -m cuml.accel your_script.py
シミュレーションループから Warp カーネルへ
# Before (CPU) — slow Python loop over particles
import numpy as np
def integrate(positions, velocities, forces, dt):
for i in range(len(positions)):
velocities[i] += forces[i] * dt
positions[i] += velocities[i] * dt
# After (GPU) — Warp kernel, JIT-compiled to CUDA
import warp as wp
@wp.kernel
def integrate(positions: wp.array(dtype=wp.vec3),
velocities: wp.array(dtype=wp.vec3),
forces: wp.array(dtype=wp.vec3),
dt: float):
tid = wp.tid()
velocities[tid] = velocities[tid] + forces[tid] * dt
positions[tid] = positions[tid] + velocities[tid] * dt
wp.launch(integrate, dim=num_particles,
inputs=[positions, velocities, forces, 0.01], device="cuda")
KvikIO を使用したファイル I/O から GPU への転送
# Before — CPU staging (disk → CPU → GPU)
import numpy as np
import cupy as cp
data = np.fromfile("data.bin", dtype=np.float32)
gpu_data = cp.asarray(data) # Extra copy through CPU memory
# After — direct to GPU (disk → GPU via GDS)
import cupy as cp
import kvikio
gpu_data = cp.empty(1_000_000, dtype=cp.float32)
with kvikio.CuFile("data.bin", "r") as f:
f.read(gpu_data) # Bypasses CPU memory with GPUDirect Storage
# Reading from S3 directly to GPU
with kvikio.RemoteFile.open_s3_url("s3://bucket/data.bin") as f:
buf = cp.empty(f.nbytes() // 4, dtype=cp.float32)
f.read(buf)
cuxfilter を使用した GPU アクセラレーション対応ダッシュボード
# Before — static matplotlib/seaborn plots, no interactivity
import pandas as pd
import matplotlib.pyplot as plt
df = pd.read_parquet("large_dataset.parquet")
fig, axes = plt.subplots(1, 2)
df.plot.scatter(x="feature1", y="feature2", ax=axes[0])
df["category"].value_counts().plot.bar(ax=axes[1])
plt.show()
# After (GPU) — interactive cross-filtering dashboard
import cudf
import cuxfilter
df = cudf.read_parquet("large_dataset.parquet")
cux_df = cuxfilter.DataFrame.from_dataframe(df)
scatter = cuxfilter.charts.scatter(x="feature1", y="feature2", pixel_shade_type="linear")
bar = cuxfilter.charts.bar("category")
slider = cuxfilter.charts.range_slider("value_col")
d = cux_df.dashboard(
[scatter, bar],
sidebar=[slider],
layout=cuxfilter.layouts.feature_and_base,
theme=cuxfilter.themes.rapids_dark,
title="Interactive Explorer",
)
d.app() # or d.show() for standalone web app
scikit-image から cuCIM へ
# Before (CPU)
from skimage.filters import gaussian, sobel, threshold_otsu
from skimage.morphology import binary_opening, disk
from skimage.measure import label, regionprops_table
import numpy as np
blurred = gaussian(image, sigma=3)
binary = blurred > threshold_otsu(blurred)
cleaned = binary_opening(binary, footprint=disk(3))
labels = label(cleaned)
props = regionprops_table(labels, image, properties=['area', 'centroid'])
# After (GPU) — change imports, wrap input with cp.asarray
from cucim.skimage.filters import gaussian, sobel, threshold_otsu
from cucim.skimage.morphology import binary_opening, disk
from cucim.skimage.measure import label, regionprops_table
import cupy as cp
image_gpu = cp.asarray(image) # Transfer once
blurred = gaussian(image_gpu, sigma=3)
binary = blurred > threshold_otsu(blurred)
cleaned = binary_opening(binary, footprint=disk(3))
labels = label(cleaned)
props = regionprops_table(labels, image_gpu, properties=['area', 'centroid'])
GeoPandas から cuSpatial へ
# Before (CPU)
import geopandas as gpd
from shapely.geometry import Point
points = gpd.GeoDataFrame(geometry=[Point(x, y) for x, y in coords], crs="EPSG:4326")
polygons = gpd.read_file("regions.geojson")
joined = gpd.sjoin(points, polygons, predicate="within")
# After (GPU) — convert and use cuSpatial
import cuspatial
import cudf
points_cu = cuspatial.from_geopandas(points)
polygons_cu = cuspatial.from_geopandas(polygons)
joined = cuspatial.point_in_polygon(
points_cu.geometry.x, points_cu.geometry.y,
polygons_cu.geometry
)
Faiss/Annoy から cuVS へ
# Before (CPU) — Faiss
import faiss
import numpy as np
embeddings = np.random.rand(1_000_000, 128).astype(np.float32)
index = faiss.IndexFlatL2(128)
index.add(embeddings)
distances, neighbors = index.search(queries, k=10)
# After (GPU) — cuVS CAGRA (orders of magnitude faster)
import cupy as cp
from cuvs.neighbors import cagra
embeddings = cp.random.rand(1_000_000, 128, dtype=cp.float32)
index = cagra.build(cagra.IndexParams(), embeddings)
distances, neighbors = cagra.search(cagra.SearchParams(), index, queries, k=10)
scipy.sparse.linalg から RAFT へ
# Before (CPU)
import numpy as np
from scipy.sparse import random as sparse_random
from scipy.sparse.linalg import eigsh
A = sparse_random(10000, 10000, density=0.01, format="csr", dtype=np.float32)
A = A + A.T # Make symmetric
eigenvalues, eigenvectors = eigsh(A, k=10, which="LM")
# After (GPU) — RAFT sparse eigensolver
import cupy as cp
import cupyx.scipy.sparse as sp_gpu
from pylibraft.sparse.linalg import eigsh as gpu_eigsh
A_gpu = sp_gpu.csr_matrix(A) # Transfer to GPU
eigenvalues, eigenvectors = gpu_eigsh(A_gpu, k=10, which="LM")
重要な注意事項
- GPU が利用できない場合にも必ず対応してください。CPU フォールバックを用意するか、明確なエラーメッセージを表示してください。
- CPU の結果と比較して数値的な正しさをテストしてください(演算順序の違いにより、GPU の浮動小数点演算の結果はわずかに異なる場合があります)。
- GPU メモリには限りがあります。データセットが GPU メモリより大きい場合は、データの分割処理や、複数 GPU 向けの RAPIDS Dask の使用を検討してください。
- CUDA Array Interface により、GPU 上の CuPy、Numba、Warp、cuDF、cuML、cuGraph、cuVS、cuSpatial、KvikIO、PyTorch、JAX の各配列間で、ゼロコピー共有が可能になります。
リファレンスファイル
GPU 最適化コードを書く前に、関連するリファレンスファイルを読んでください。
| ファイル | 読むタイミング |
|---|---|
references/cupy.md | NumPy/SciPy のコードがある場合、または GPU 上で配列操作が必要な場合 |
references/numba.md | カスタム CUDA カーネル、細かな GPU 制御、または GPU ufunc が必要な場合 |
references/cudf.md | pandas のコードがある場合、または GPU 上でデータフレーム操作が必要な場合 |
references/cuml.md | scikit-learn のコードがある場合、または GPU 上で ML のトレーニング/推論/前処理が必要な場合 |
references/cugraph.md | NetworkX のコードがある場合、または GPU 上でグラフ分析が必要な場合 |
references/warp.md | GPU シミュレーション、空間コンピューティング、メッシュ/ボリュームクエリ、微分可能プログラミング、またはロボティクスが必要な場合 |
references/kvikio.md | GPU との間での高性能なファイル IO、GPUDirect Storage、S3/HTTP から GPU への読み込み、または GPU 上の Zarr が必要な場合 |
references/cuxfilter.md | GPU アクセラレーション対応のインタラクティブなダッシュボード、クロスフィルタリング、または EDA による可視化が必要な場合 |
references/cucim.md | scikit-image のコードがある場合、または GPU 上で画像処理、デジタル病理学、WSI の読み込みが必要な場合 |
references/cuvs.md | GPU 上でベクトル検索、最近傍探索、類似性検索、または RAG 検索が必要な場合 |
references/cuspatial.md | GeoPandas/shapely のコードがある場合、または空間結合、距離計算、軌跡分析が必要な場合 |
references/raft.md | スパース固有値ソルバー、デバイスメモリ管理、またはマルチ GPU プリミティブが必要な場合 |
コードを書く前に、該当するリファレンスを読んでください。各ライブラリ固有の詳細な API パターン、最適化手法、注意点が記載されています。