[AWS/Inf1]Neuron Coreの使用率のみをカスタムメトリクスとして送信する
AWS Neuron
Neuron Coreの使用率だけを監視したい
対象読者
ECSでInf1インスタンスを使っている人。
Inferentiaチップのメトリクスを監視したい人。
不要なコストを少しでも減らしたい人。
はじめに
これまでInferentiaチップのメトリクスに関して過去2回記事を書いてきました。
取得方法とECSでの運用方法についてです。
第1回
第2回
初回から読んでいくとスムーズに理解が出来ると思います。
3回目となる今回はコスト最適化に関する記事です。
💸必要なカスタムメトリクスのみCloudWatchに送信したい
aws-neuron-toolsについてくるスクリプトを使って、Inferentiaチップに関するメトリクスをCloud Watchに送信すると、デフォルトでは約25個のカスタムメトリクスができます。
1メトリクスごとに0.3USD/月[1]で計算すると全てCloudWatchに送ると,
です。
インスタンスIDをディメンション[2]として設定すると
です。
Inf1インスタンスの価格[3]に比べたら遥かに小さな額ではありますが、無駄な費用は払いたくありません。
必要なメトリクスのみ送信してコストを削減します。
📝設定ファイルを読み解く
neuron-monitorコマンドは--config-fileオプションで設定ファイルを指定できます。
neuron-monitor --config-file monitor.conf
設定ファイルはJSON形式のファイルです。
出力したい指標を記述するという書き方です。
その他にも、
- メトリクスグループごとの出力間隔調整
- 環境変数
NEURON_PROCESS_TAG
による出力調整- メトリクスを取得するプロセスのフィルター
- タグの値ごとのメトリクスの出力
ができます。
詳細はドキュメントを御覧ください。
ドキュメントにあるサンプルは次のような設定になります。
{
"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": ""
}
{
"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のクラスタごとにメトリクスを取得出来るようにしたいなと思っています。
-
カスタムメトリクスの費用。詳しくは https://aws.amazon.com/jp/cloudwatch/pricing/ ↩︎
-
ディメンションとは特定のメトリクスをより詳細に分割するような情報のことです。例えば、CPU使用率と一口に言ってもインスタンスAのCPU使用率、インスタンスBのCPU使用率があります。ディメンションを使うと別の情報として認識できるようになります。 詳しくは https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/monitoring/cloudwatch_concepts.html#Dimension ↩︎
-
東京リージョンのオンデマンドで約0.3USD/時間 ↩︎
-
1プロセスのプログラムを実行 ↩︎
Discussion