Snowflake ML のCUDA-Xライブラリ

Snowflake Container Runtimeの CUDA-X 統合を使用して、コードを変更せずに GPUs でデータ変換と ML をシームレスにスケールします。Snowflakeは NVIDIA の cuML および cuDF ライブラリをランタイム環境に統合しました。 この統合により、scikit-learn、umap-learn、hdbscanなどのライブラリを、 GPUs で使用することができます。新しいフレームワークを学習したり、複雑な依存関係を処理したりする必要はありません。

データサイズやアルゴリズムの複雑さを妥協することなく、トピックモデリング、ゲノミクス、パターン認識などの複雑な処理を実行できます。処理時間を短縮することで、モデルでさらに反復する機会が得られます。

CUDA-Xライブラリとの統合により、Snowflake ML Container Runtimeにおける大規模なデータセットの処理を GPU で高速化できます。 Container Runtimeのみを使用するよりも桁違いに処理速度が速くなる可能性があります。

データサイエンス用の NVIDIA CUDA-Xライブラリ

cuML や cuDF のようなオープンソースライブラリは、 GPUs を利用して効率的でスケーラブルなデータワークフローを実現します。これらのライブラリを使用して、数十億の行と数百万のディメンションを持つデータを処理できます。これらのライブラリの詳細については、 NVIDIACUDA-Xデータサイエンス をご覧ください。

../../_images/cuda-x-libraries.png

CUDA-X DS ライブラリは、 GPUs のパワーと、データアナリティクス、機械学習、グラフ分析に一般的に使用されるPythonライブラリを組み合わせ、チームがコードを書き換えることなく、大幅なスピードアップを実現します。CUDA-X DS を使用すると、 GPU の速度向上により、単一の GPU で最大でテラバイトのデータセットを処理できます。

NVIDIA cuML は CPU ワークフローで以下のパフォーマンス向上を実現できます。

  • scikit-learnの場合、最大50倍

  • UMAP の場合、最大60倍

  • HDBSCAN の場合、最大175倍

ユースケース

Snowflake ML Container Runtimeにおける CUDA-Xライブラリの統合は、以下のユースケースに GPUs とScikit-learnとpandasを使用します。

大規模なトピックモデリング

大規模で特徴量が豊富なデータセットのトピックモデリングには、次が必要です。

  • 埋め込みモデルの使用

  • 大規模な次元削減の適用

  • クラスタリングと視覚化を使用した、正確かつ関連性のあるトピックの抽出

GPU 並列処理により、前述のワークフローをより効率的に達成することができます。cuML で処理を加速させることで、数百万件の製品レビューをrawテキストから明確に定義されたトピッククラスターに変換することができ、既存のPythonコードを変更することなく、 CPU の数時間を GPU での数分に削減できます。これは、 UMAP および HDBSCAN ライブラリのシームレスなドロップインアクセラレーションを強調しています。

Snowflakeの GPUs でのトピックモデリング実行に関する詳細は、 https://quickstarts.snowflake.com/guide/accelerate-topic-modeling-with-gpus-in-snowflake-ml/#0 をご参照ください。

計算ゲノミクスワークフロー

Snowflakeの CUDA-X統合を使用して、生物学的な配列の処理を大幅に高速化します。DNA 配列を、遺伝子ファミリーの予測など、スケーラブルな分類タスクの特徴ベクトルに変換できます。

cuDF および cuML を使用してpandasとscikit-learnのコードを GPUs で直接実行すると、データのロード、前処理、アンサンブルモデルトレーニングを高速化できます。コードを変更することなく、既存のワークフローを GPU で高速化することで、研究者は下位レベルの GPU プログラミングよりも生物学的な洞察と設計を優先することができます。

Snowflakeでの開発

CUDA-Xライブラリを使用して、Snowflake ML Container Runtime内で GPU で加速させた機械学習モデルを開発しデプロイします。このセクションでは、これらのツールをPythonワークフローに統合するための手順ガイドを提供します。

開始するには、以下の手順を実行します。

  1. Snowflake Notebookまたは ML ジョブでPythonスクリプトを定義する

  2. Notebookまたは ML ジョブ用の GPU ランタイムと GPU コンピューティングプールを選択する

前述の手順を実行したら、次のコードを実行して環境内で CUDA-Xアクセラレーターを構成します。

#Install cuDF and cuML accelerators for zero code change acceleration

import cuml
cuml.accel.install()
import cudf.pandas
cudf.pandas.install()
Copy

これで GPUs でpandas操作を直接実行できるようになりました。または、scikit-learn、umap、hdbscanモデルを適合させることができます( GPUs で実行するためにコードを変更する必要はありません)。この例は、大規模なデータセットで hdbscan を使用する方法を示しています。

import hdbscan
from sklearn.datasets import make_blobs

# Generate some sample data with multiple clusters
data, _ = make_blobs(n_samples=500, centers=4, cluster_std=0.8, random_state=42)

# Initialize and fit HDBSCAN
# min_cluster_size: The minimum size of clusters; smaller clusters will be considered noise.
# min_samples: The number of samples in a neighborhood for a point to be considered as a core point.
hdbscan_model = hdbscan.HDBSCAN(min_cluster_size=15, min_samples=5, cluster_selection_epsilon=0.5)
hdbscan_model.fit(data)
Copy

適用されるユースケース:大規模なトピックモデリング

計算効率は大規模なテキスト分析とトピックモデリングに不可欠です。 GPUs は並列処理を使用して、処理時間を数時間から数分に短縮します。このセクションでは、 GPU による高速化と CUDA-Xを使用して、200,000件の美容製品のレビューのデータセットに対して ML モデルを高速化する方法を示しています。

CUDA-Xを使用して次を実行できます。

  • 機械学習のために、rawテキストを数値表現(埋め込み)に変換する

  • 次元削減を加速化する

CUDA ライブラリを利用するには、コードの先頭に%load_ext cuml.accelを追加します。これにより、処理時間が数時間から数分に短縮されます。

次のコード例では、 SentenceTransformer クラスを使用して埋め込みを作成しています。

from sentence_transformers import SentenceTransformer
model = SentenceTransformer('all-MiniLM-L6-v2')
embeddings = model.encode(texts, show_progress_bar=True)
Copy

次のコード例では、 HDBSCAN を使用して高次元データを削減しています。クラスタートピックを保持します。

from umap import UMAP
from hdbscan import HDBSCAN
umap_model = UMAP(n_components=15, n_neighbors=15, min_dist=0.0)
hdbscan_model = HDBSCAN(min_cluster_size=100, gen_min_span_tree=True, prediction_data=True)
Copy

適用されるユースケース:複雑なゲノミクスワークフローの実行

パラログとオーサログを含む遺伝子ファミリー組織は、遺伝子の進化、機能、および生物学的プロセスを理解するために重要です。

CUDA-Xライブラリを使用すると、 DNA 配列から遺伝子ファミリーを予測する分類モデルを作成できます。このモデルは、ゲノムアノテーションを加速させ、新しい遺伝子機能を特定し、進化経路に関する洞察を提供することができます。

データセット には、一連のプレーンテキストのヌクレオチド配列と、それに対応する遺伝子ファミリークラスラベルがあります。クラスは、7つの異なるヒトの遺伝子ファミリーに対応します。

次のコードは、Hugging Faceの ヌクレオチドトランスフォーマー を使用して、 DNA 配列をベクトルに変換します。トランスフォーマーは、各遺伝子配列を1280の特徴ベクトルに変換するために、配列をトークン化してバッチ処理します。

%load_ext cudf.pandas
%load_ext cuml.accel

from transformers import AutoTokenizer, AutoModelForMaskedLM
import torch

def get_dna_embeddings(sequences, classes):
    tokens_ids = tokenizer.batch_encode_plus(sequences, return_tensors="pt", padding="longest")["input_ids"].to('cuda:0')

    attention_mask = tokens_ids != tokenizer.pad_token_id
    try:
        torch_outs = model(
            tokens_ids,
            attention_mask=attention_mask,
            encoder_attention_mask=attention_mask,
            output_hidden_states=True
        )
    except:
        return []

    embeddings = torch_outs['hidden_states'][-1].detach()
    attention_mask = torch.unsqueeze(attention_mask, dim=-1)
    mean_sequence_embeddings = torch.sum(attention_mask*embeddings, axis=-2)/torch.sum(attention_mask, axis=1)
    return list(zip(mean_sequence_embeddings.numpy(), classes))

# Load the tokenizer and model
tokenizer = AutoTokenizer.from_pretrained("InstaDeepAI/nucleotide-transformer-500m-human-ref")
model = AutoModelForMaskedLM.from_pretrained("InstaDeepAI/nucleotide-transformer-500m-human-ref")

# Example of obtaining embeddings (simplified)
sequences = ["ATGCCCCAACTAAATACTACCGTATGGCCCACCATAATTACCCCCA", ...]
classes = [0, ...]


genes = []
batch_size=10

emb = get_dna_embeddings(human_genes[i], human_classes[i])
genes += emb
Copy

次のコードを使用して、2つのアンサンブル分類モデルを評価できます。

  • ランダムフォレスト分類子

  • XGBoost 分類子

%load_ext cudf.pandas
%load_ext cuml.accel

import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier

human_dna = pd.read_table(human_url) # This would now run on GPU

genes = []
batch_size=10

human_genes = human_dna['sequence'].tolist()
human_classes = human_dna['class'].tolist()

human_genes = [human_genes[i:i + batch_size] for i in range(0, len(human_genes), batch_size)]
human_classes = [human_classes[i:i + batch_size] for i in range(0, len(human_classes), batch_size)]

# Create the embeddings
for i in tqdm(range(len(human_genes)), desc='Producing embeddings...'):
    emb = get_dna_embeddings(human_genes[i], human_classes[i])
    genes += emb

genes_df = pd.DataFrame(genes, columns=['embeddings', 'class'])
genes_df[[f'emb_{i}' for i in range(1280)]] = pd.DataFrame(genes_df['embeddings'].tolist(), index=genes_df.index) # the embeddings generated above

X, y = genes_df[[f'emb_{i}' for i in range(1280)]], genes_df['class']
X_train, X_test, y_train, y_test = train_test_split(X, y,
                                                   test_size = 0.20,
                                                   random_state=42)

classifier = RandomForestClassifier(n_estimators=200, max_depth=20, max_features=1.0, n_jobs=-1)
classifier.fit(X_train, y_train)
Copy

こちらもご参照ください。