Splunk DLTK + GPU の効果を検証してみた


# はじめに

以前、[Pytorch + CUDA を使ったコードの実行](https://qiita.com/maroon/items/d6bb13fd58c4d4127855)について記事を書きましたが、GPU環境がなかったため CPU環境での実行で我慢してました。

今回 GPU環境を使う機会ができたため、前回のコードを epoch数(学習回数)を変更して CPUとGPUでどのくらい学習時間に違いがでてくるか検証をしてみました。


# 環境について

今回、検証のため利用したスペックは以下の通りです。

| CPU環境 | 1 instance |
|:-:|:-:|
| インスタンス名  | t2.xlarge  |
| vCPU  | 4  |
| RAM  | 16GB  |
|費用|0.1856USD/時間|

| GPU環境 | 1 instance |
|:-:|:-:|
|インスタンス名|g4dn.xlarge|
|GPU | NVIDIA T4 Tensor Core|
|vCPU | 4|
|RAM|16 GB|
|費用|0.526USD/時間|

NVIDIA T4 Tensor Core のスペックは[こちら](https://www.nvidia.com/ja-jp/data-center/tesla-t4/)

GPU環境はご覧のとおりコストも跳ね上がりますので、こまめに止めておきましょう！

# セットアップ

さて、DLTKでGPU環境を利用する場合ですが、こちらのブログに詳細な設定方法がありますのでご覧ください。
https://www.splunk.com/en_us/blog/tips-and-tricks/splunk-with-the-power-of-deep-learning-analytics-and-gpu-acceleration.html

インスタンスが用意されているので、意外と簡単にできます。


# 検証内容

DLTKの[サンプルコード](https://qiita.com/maroon/items/d6bb13fd58c4d4127855)を利用します。


**コードの概要です。**
今回はシンプルな 9(input) x 100(hidden) x 2(output) の3層レイヤーの全結合を行うニューラルネットワークになります。
データ数は 100,000 件になります。 (DGAのデータを利用します）

```
    # Simple neural network model
    model['model'] = torch.nn.Sequential(
        torch.nn.Linear(model['input_size'], model['hidden_layers']),
        torch.nn.ReLU(),
        torch.nn.Linear(model['hidden_layers'], model['num_classes']),
    ).to(model['device'])
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/392303/645d026b-1617-3134-a1ec-75c94905132a.png)


Splunk側では以下のSPLを epochs　数を変更しながら実行結果を確認します。
CPU環境とGPU環境でどのくらいの学習時間に差が出るかを検証したいと思います。
今回は Epoch数を 10,100,1000,10000 の４パターンを用意しました。

```
| inputlookup dga_domains_features.csv 
| fit MLTKContainer algo=pytorch_nn epochs=10 batch_size=100 hidden_layers=100 class from PC_1 PC_2 PC_3 ut_consonant_ratio ut_digit_ratio ut_domain_length ut_meaning_ratio ut_shannon ut_vowel_ratio into app:dga_nn_classifier
| rename predicted_class as class_predicted
| table class* * |  multireport 
    [| score accuracy_score class against class_predicted ] 
    [| score precision_recall_fscore_support class against class_predicted average=weighted]
| stats avg(accuracy_score) as accuracy avg(precision) as precision avg(recall) as recall avg(fbeta_score) as f1
```


# 検証結果

それぞれ Epoch数を増やした時の実行時間の比較表になります。f1 Scoreとはモデルの精度を表す指標で正解率みたいなものです。1.0に近いほど正解率が高いといえます。どちらの環境でも結果はほぼ同じになるため、比較するのは実行時間のみとします。

|         | Epoch数 | 10 | 100 | 1000 | 10000 |
|:-:|:-:|:-:|:-:|:-:|:-:|
|         |f1 Score | 0.33  | 0.65  | 0.84| 0.92  |
| CPU環境  |学習時間 (sec) | 26.6  | 37.6   |153.9 | 1202.9  |
| GPU環境  |学習時間 (sec) | 25.7  | 25.7  |30.0 | 76.2  |

ご覧の通り、Epoch数を増やすほど、正解率はよくなりますが、その分学習時間が飛躍的に長くなってしまいます。しかしGPUを利用するとその時間をかなり短縮することができました。 10000回実行した場合、CPU環境だと約20分かかったのに対して、GPUだと1分ちょっとと 18倍近い差がでました。


# おまけ

CPU環境において、10000で実行すると、デフォルトの 600秒の制限に引っかかってしまいタイムアウトとなってしまいました。そのため fitの実行タイムアウトを伸ばす必要があります。今回は max_fit_time を 6000 (100min) と１０倍に増やしました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/392303/cb343486-5ece-c2ba-9495-4789c5032075.png)



# まとめ

いかがだったでしょうか？　GPU環境のパワーをみた感じがします。これならコストが多少高くても学習時間が縮まることで作業の効率があがりますし、より複雑なモデルも学習させることが可能です。　また他のブログでは NVIDIAが提供しているライブラリを使った機械学習も紹介しておりますので、機会があればGPU+Splunkを試してみてはいかがでしょうか？