🦖

[AWS/Inf1]Neuron Coreの使用率のみをカスタムメトリクスとして送信する

2023/02/02に公開


AWS Neuron


Neuron Coreの使用率だけを監視したい

対象読者

ECSでInf1インスタンスを使っている人。
Inferentiaチップのメトリクスを監視したい人。
不要なコストを少しでも減らしたい人。

はじめに

これまでInferentiaチップのメトリクスに関して過去2回記事を書いてきました。
取得方法とECSでの運用方法についてです。

第1回
https://zenn.dev/optfit_tech/articles/b36d20eaf2b015

第2回
https://zenn.dev/optfit_tech/articles/3db26ec98011f3

初回から読んでいくとスムーズに理解が出来ると思います。

3回目となる今回はコスト最適化に関する記事です。

💸必要なカスタムメトリクスのみCloudWatchに送信したい

aws-neuron-toolsについてくるスクリプトを使って、Inferentiaチップに関するメトリクスをCloud Watchに送信すると、デフォルトでは約25個のカスタムメトリクスができます。

1メトリクスごとに0.3USD/月[1]で計算すると全てCloudWatchに送ると,

0.3 * 25 = 7.5\ ({\rm USD/月})

です。

インスタンスIDをディメンション[2]として設定すると

インスタンス数 * 7.5 \ ({\rm USD/月})

です。

Inf1インスタンスの価格[3]に比べたら遥かに小さな額ではありますが、無駄な費用は払いたくありません。

必要なメトリクスのみ送信してコストを削減します。

📝設定ファイルを読み解く

neuron-monitorコマンドは--config-fileオプションで設定ファイルを指定できます。

neuron-monitor --config-file monitor.conf

設定ファイルはJSON形式のファイルです。

出力したい指標を記述するという書き方です。

その他にも、

  • メトリクスグループごとの出力間隔調整
  • 環境変数NEURON_PROCESS_TAGによる出力調整
    • メトリクスを取得するプロセスのフィルター
    • タグの値ごとのメトリクスの出力

ができます。

詳細はドキュメントを御覧ください。

https://awsdocs-neuron.readthedocs-hosted.com/en/latest/tools/neuron-sys-tools/neuron-monitor-user-guide.html#using-neuron-monitor

ドキュメントにあるサンプルは次のような設定になります。

example-monitor.conf
{
  "period": "1s", # グローバルに出力間隔を1秒にする(デフォルトは5秒)
  "neuron_runtimes": [
    {
      "tag_filter": ".*", # 正規表現 .* にマッチする環境変数NEURON_PROCESS_TAGの値を持つプロセスのメトリクスのみ出力(この場合全て)
      "metrics": [
        {
          "type": "neuroncore_counters" # 出力したいメトリクスグループ
        },
        {
          "type": "memory_used" # 出力したいメトリクスグループ
        },
        {
          "type": "neuron_runtime_vcpu_usage" # 出力したいメトリクスグループ
        },
        {
          "type": "execution_stats" # 出力したいメトリクスグループ
        }
      ]
    }
  ],
  "system_metrics": [
    {
      "type": "vcpu_usage" # 出力したいメトリクスグループ
    },
    {
      "type": "memory_info" # 出力したいメトリクスグループ
    },
    {
       "period": "2s", # メトリクスグループneuron_hw_countersは2秒おきに出力(グローバルより優先される)
       "type": "neuron_hw_counters" # 出力したいメトリクスグループ
    }
  ]
}


KAZYColorfulSaurus

⚡️設定ファイルで必要な指標のみ出力する

今回はNeuron coreごとの使用率がほしいので、neuroncore_counters以下のみ出力する設定ファイルを書きます。

参考:neuroncore_countersの詳細
ほしい指標
// https://awsdocs-neuron.readthedocs-hosted.com/en/latest/tools/neuron-sys-tools/neuron-monitor-user-guide.html#neuron-application-level-metric-groups
"neuroncore_counters": {
  "period": 1.000113182,
  "neuroncores_in_use": {
    "0": { # Neuron core 0"neuroncore_utilization": 42.01, # 使用率
    },
    "1": { # Neuron core 1"neuroncore_utilization": 42.02, # 使用率
    },
    "2": { # Neuron core 2"neuroncore_utilization": 42.03, # 使用率
    },
    "3": { # Neuron core 3"neuroncore_utilization": 42.04, # 使用率
    }
  },
  "error": ""
}
monitor.conf
{
  "neuron_runtimes": [
    {
      "tag_filter": ".*", # 必須。全部通す設定
      "metrics": [
        {
          "type": "neuroncore_counters" # Neuron Coreの使用率が取得できるメトリクスグループ
        }
      ]
    }
  ]
}

この設定ファイルを使って実際に動かしてみます[4]

neuron-monitor --config-file monitor.conf
出力結果
{
    "neuron_runtime_data": [
        {
            "pid": 2499,
            "neuron_runtime_tag": "11", # メトリクスを取得したプロセスID
            "error": "",
            "report": {
                "neuroncore_counters": {
                    "period": 5.004039167, # 取得間隔はデフォルトの5"neuroncores_in_use": {
                        "0": {
                            "neuroncore_utilization": 0
                        },
                        "1": {
                            "neuroncore_utilization": 0
                        },
                        "2": {
                            "neuroncore_utilization": 0
                        },
                        "3": {
                            "neuroncore_utilization": 0
                        }
                    },
                    "error": ""
                }
            }
        }
    ],
    "system_data": null,
    "instance_info": { # ハードウェア情報 
        "instance_name": "KAZY-dev",
        "instance_id": "i-XXXXXXXXXXX",
        "instance_type": "inf1.xlarge",
        "instance_availability_zone": "ap-northeast-1a",
        "instance_availability_zone_id": "apne1-az4",
        "instance_region": "ap-northeast-1",
        "ami_id": "ami-09faa8f301ae9469c",
        "subnet_id": "subnet-XXXXXXXXXXX",
        "error": ""
    },
    "neuron_hardware_info": {  # ハードウェア情報
        "neuron_device_count": 1,
        "neuroncore_per_device_count": 4,
        "error": ""
    }
}

Neuron coreの情報のみがレポートとして出力されました。
インスタンスとハードウェアに関する情報は、設定ファイルに書かなくても基本情報として出力されるようです。

参考として設定ファイルなしの実行結果を載せておきます。

neuron-monitor
参考:設定ファイルなしの出力結果
{
    "neuron_runtime_data": [
        {
            "pid": 2499,
            "neuron_runtime_tag": "11",
            "error": "",
            "report": {
                "execution_stats": {
                    "period": 5.003829968,
                    "error_summary": {
                        "generic": 0,
                        "numerical": 0,
                        "transient": 0,
                        "model": 0,
                        "runtime": 0,
                        "hardware": 0
                    },
                    "execution_summary": {
                        "completed": 300,
                        "completed_with_err": 0,
                        "completed_with_num_err": 0,
                        "timed_out": 0,
                        "incorrect_input": 0,
                        "failed_to_queue": 0
                    },
                    "latency_stats": {
                        "total_latency": {
                            "p0": 0.009135246276855469,
                            "p1": 0.009232044219970703,
                            "p100": 0.0653836727142334,
                            "p25": 0.01674795150756836,
                            "p50": 0.024577856063842773,
                            "p75": 0.030786991119384766,
                            "p99": 0.05307817459106445
                        },
                        "device_latency": {
                            "p0": 0.00764155387878418,
                            "p1": 0.007683277130126953,
                            "p100": 0.035587310791015625,
                            "p25": 0.013979196548461914,
                            "p50": 0.02166128158569336,
                            "p75": 0.028336286544799805,
                            "p99": 0.033701419830322266
                        }
                    },
                    "error": ""
                },
                "memory_used": {
                    "period": 5.003854865,
                    "neuron_runtime_used_bytes": {
                        "host": 4527943680,
                        "neuron_device": 0,
                        "usage_breakdown": {
                            "host": {
                                "application_memory": 4527943680,
                                "constants": 0,
                                "dma_buffers": 0,
                                "tensors": 0
                            },
                            "neuroncore_memory_usage": {
                                "0": {
                                    "constants": 0,
                                    "model_code": 0,
                                    "model_shared_scratchpad": 0,
                                    "runtime_memory": 0,
                                    "tensors": 0
                                },
                                "1": {
                                    "constants": 0,
                                    "model_code": 0,
                                    "model_shared_scratchpad": 0,
                                    "runtime_memory": 0,
                                    "tensors": 0
                                },
                                "2": {
                                    "constants": 0,
                                    "model_code": 0,
                                    "model_shared_scratchpad": 0,
                                    "runtime_memory": 0,
                                    "tensors": 0
                                },
                                "3": {
                                    "constants": 0,
                                    "model_code": 0,
                                    "model_shared_scratchpad": 0,
                                    "runtime_memory": 0,
                                    "tensors": 0
                                }
                            }
                        }
                    },
                    "loaded_models": [
                        {
                            "name": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
                            "uuid": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
                            "model_id": 10001,
                            "is_running": false,
                            "subgraphs": {
                                "sg_00": {
                                    "memory_used_bytes": {
                                        "host": 20416944,
                                        "neuron_device": 17303308,
                                        "usage_breakdown": {
                                            "host": {
                                                "application_memory": 20404608,
                                                "constants": 0,
                                                "dma_buffers": 12336,
                                                "tensors": 0
                                            },
                                            "neuron_device": {
                                                "constants": 121408,
                                                "model_code": 0,
                                                "runtime_memory": 0,
                                                "tensors": 1039040
                                            }
                                        }
                                    },
                                    "neuroncore_index": 0,
                                    "neuron_device_index": 0
                                }
                            }
                        },
                        {
                            "name": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
                            "uuid": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
                            "model_id": 10002,
                            "is_running": false,
                            "subgraphs": {
                                "sg_00": {
                                    "memory_used_bytes": {
                                        "host": 20416944,
                                        "neuron_device": 17303308,
                                        "usage_breakdown": {
                                            "host": {
                                                "application_memory": 20404608,
                                                "constants": 0,
                                                "dma_buffers": 12336,
                                                "tensors": 0
                                            },
                                            "neuron_device": {
                                                "constants": 121408,
                                                "model_code": 0,
                                                "runtime_memory": 0,
                                                "tensors": 1039040
                                            }
                                        }
                                    },
                                    "neuroncore_index": 1,
                                    "neuron_device_index": 0
                                }
                            }
                        }
                    ],
                    "error": ""
                },
                "neuron_runtime_vcpu_usage": {
                    "period": 5.003969176,
                    "vcpu_usage": {
                        "user": 24.8,
                        "system": 3.06
                    },
                    "error": ""
                },
                "neuroncore_counters": {
                    "period": 5.003816202,
                    "neuroncores_in_use": {
                        "0": {
                            "neuroncore_utilization": 27.022940804670643
                        },
                        "1": {
                            "neuroncore_utilization": 19.349312799371454
                        },
                        "2": {
                            "neuroncore_utilization": 0
                        },
                        "3": {
                            "neuroncore_utilization": 0
                        }
                    },
                    "error": ""
                }
            }
        }
    ],
    "system_data": {
        "memory_info": {
            "period": 5.003690715,
            "memory_total_bytes": 8025300992,
            "memory_used_bytes": 7254392832,
            "swap_total_bytes": 0,
            "swap_used_bytes": 0,
            "error": ""
        },
        "neuron_hw_counters": {
            "period": 5.003681818,
            "neuron_devices": [
                {
                    "neuron_device_index": 0,
                    "mem_ecc_corrected": 0,
                    "mem_ecc_uncorrected": 0,
                    "sram_ecc_uncorrected": 0,
                    "sram_ecc_corrected": 0
                }
            ],
            "error": ""
        },
        "vcpu_usage": {
            "period": 5.003687262,
            "average_usage": {
                "user": 28.37,
                "nice": 0,
                "system": 5.05,
                "idle": 66.38,
                "io_wait": 0.1,
                "irq": 0,
                "soft_irq": 0.1
            },
            "usage_data": {
                "0": {
                    "user": 26.86,
                    "nice": 0,
                    "system": 4.96,
                    "idle": 68.18,
                    "io_wait": 0,
                    "irq": 0,
                    "soft_irq": 0
                },
                "1": {
                    "user": 28.46,
                    "nice": 0,
                    "system": 4.88,
                    "idle": 66.46,
                    "io_wait": 0,
                    "irq": 0,
                    "soft_irq": 0.2
                },
                "2": {
                    "user": 29.07,
                    "nice": 0,
                    "system": 5.49,
                    "idle": 65.45,
                    "io_wait": 0,
                    "irq": 0,
                    "soft_irq": 0
                },
                "3": {
                    "user": 29.21,
                    "nice": 0,
                    "system": 5.07,
                    "idle": 65.52,
                    "io_wait": 0,
                    "irq": 0,
                    "soft_irq": 0.2
                }
            },
            "context_switch_count": 190177,
            "error": ""
        }
    },
    "instance_info": {
        "instance_name": "KAZY-dev",
        "instance_id": "i-XXXXXXXXXXXXXX",
        "instance_type": "inf1.xlarge",
        "instance_availability_zone": "ap-northeast-1a",
        "instance_availability_zone_id": "apne1-az4",
        "instance_region": "ap-northeast-1",
        "ami_id": "ami-09faa8f301ae9469c",
        "subnet_id": "subnet-XXXXXXXXXXXXXX",
        "error": ""
    },
    "neuron_hardware_info": {
        "neuron_device_count": 1,
        "neuroncore_per_device_count": 4,
        "error": ""
    }
}

⏱クラウドウォッチに送信する

Neuron Toolsについてくるクラウドウォッチにカスタムメトリクスを送信してくれるスクリプトは、設定ファイル適用後の出力に対応しています。

設定ファイルとともに実行するとクラウドウォッチに所望のカスタムメトリクスのみが送信されます。

neuron-monitor --config-file monitor.conf | neuron-monitor-cloudwatch.py  --region ap-northeast-1

実際にクラウドウォッチを確認してみます。

すべて>Neuron 以下にNeuronCoreUtilizationNC0,NeuronCoreUtilizationNC1,NeuronCoreUtilizationNC2,NeuronCoreUtilizationNC3という名前でNeuron coreの使用率のメトリクスがありました。


完成

おわりに

次回は例のスクリプトを改良して、ECSのクラスタごとにメトリクスを取得出来るようにしたいなと思っています。

脚注
  1. カスタムメトリクスの費用。詳しくは https://aws.amazon.com/jp/cloudwatch/pricing/ ↩︎

  2. ディメンションとは特定のメトリクスをより詳細に分割するような情報のことです。例えば、CPU使用率と一口に言ってもインスタンスAのCPU使用率、インスタンスBのCPU使用率があります。ディメンションを使うと別の情報として認識できるようになります。 詳しくは https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/monitoring/cloudwatch_concepts.html#Dimension ↩︎

  3. 東京リージョンのオンデマンドで約0.3USD/時間 ↩︎

  4. 1プロセスのプログラムを実行 ↩︎

GitHubで編集を提案
Opt Fit テックブログ

Discussion