yag's blog

Twitter以上Zenn以下なことを書く場所

Telegraf/InfluxDB/GrafanaでGPUサーバのメトリクスを監視する

これまでGPUの監視にはnvitopを使っていた。実行している最中にその様子を確認する分には便利だが、長期的にモニタリングしたり、実行中になにかの理由で落ちたときに後々の解決が難しいということがあり、本格的なメトリクス監視を入れることに。初めに思いついたのはDatadogやMackerelのようなSaaSだが、無料版では1日限定しかモニタリングができないことが分かり却下。そこで以前Raspberry Piを構築したときに触ったTelegraf/InfluxDB/Grafanaを再度引っ張り出してきてきた。Telegralはメトリクス収集、InfluxDBは時系列DB、Grafanaは可視化を担っている。

モニタリングしたいサーバに監視アプリを同居させるとシステムが落ちたときにどうしようもなくなるので、ハードウェア構成としてはRaspberry Pi上に立てたInfluxDBとGrafanaに、サーバからTelegrafでメトリクスを送るという形に。TailscaleによりRaspberry Pi上に立てたGrafanaの3000番ポートにも何も考えずにアクセスできるので、ネットワーク面もストレスなく構築できる。

ダッシュボードはGrafana Dashboardsの中から良さげなものを持ってきてimportするだけで完了する。正直ここが一番面倒臭いので、こうして気軽に人が作ったデザインを利用できるのは便利だ。

これで自作サーバでやりたいことは一通り出来た気がする。あとはガンガンGPUを回して計算させるだけだが、肝心のその部分の進捗は芳しくない。

~/local/を使うのをやめて~/.local/に移行してみた

自分がプログラミングを学び始めた頃から、自身でコンパイルを要したり実行ファイルが出てくるタイプのツールは、ホームディレクトリ以下に~/localを作成して./configure --prefix=$HOME/localとすることで、その配下にbin/lib/が作成されるというスタイルを取ってきた。初心者だったときに教わったことなのでこれが一般的な習慣なのかはわからないが、ホームディレクトリにlocalというディレクトリがあることは至って普通で何の違和感もなかった。

最近のツールを使っていると、~/.local/というディテクトリを使っていることに気付いた。自分が遭遇してパッと出てくるのは以下の2つ。Ubuntuの環境の場合、どちらも~/.local/binに実行ファイルを置いてそこにPATHを通す形になっている。

改めて考えると、実行ファイルを作ってPATHを通すだけなので.local/でも全く問題は無いし、ファイルシステム上で見えておく必要はない。ホームディレクトリでドットから始まるディレクトリを作る/使うのは普通であり、確かにこっちのほうが合理的かもしれないと思うに至った。

せっかくなので新しい環境では~/localではなく~/.localを使うように変えてみようと思う。

マルチコア/スレッドで見栄えの良いようにhtopのレイアウトを変える

さすがに12core24threadもあると、htopのデフォルトの設定では各CPUが詰まってあまり見栄えがしなかったが、レイアウトが変更できることに気付いた。それはそうか。

変更はF2を押してMetersから。Left ColumnとRight Columnがあるので、そこにAvailable Metersから好きなメトリクスをEnterで選択して移動してけば良い。Spaceでデザイン変更、Fn+Shift+Delで削除(これは自分のiTerm環境の場合)。

Tweetしたような時系列グラフの表記も面白いんだけど、時系列はnvitopでも見れるし、結局は見慣れた表記で落ち着いた。実行しているスクリプトが1コア/1スレッドだけ動いていることを視覚的に確認するには一番良いと思う。

EOFError: Ran out of input

Zennやブログでは綺麗に纏めたことや成功したことをアウトプットしがちなので、ここでは駄目だったこともアウトプットしていこうと思う。

とある一連のPythonコードの中で、大量のドキュメントのsentence embeddingを計算して結果をpickleファイルに吐き出し、そのpickleファイルを別のPythonコードで読み込む流れがあったのだが、後者の方でどうしてもpickleファイルが読み込めない。エラーは以下の通り。

EOFError: Ran out of input

pickleファイルはwb/rbで読み書きされているので、ファイルのフォーマットとしては問題ないはず。でも読み込めない。気になる点を挙げるとするならば、pickleファイルは15GBくらいあり、小さいサイズのファイルで試しに書き出すと同一コードでも上手くいくというところ。Pythonが許容するpickleのファイルサイズやLinuxの何らかのulimitあたりに引っかかっているのではと思ったが、ざっくりと調べた限りでは分からなかった。

ちなみに、この1つ目のコードをフルで動かすとGPUマシンで8時間くらい必要で、デバッグイテレーションを回すのがほぼ困難という点も、課題解決の難しさに拍車をかけている。結果的に別のSerializationの方法でデータの受け渡しをすることにしたが、なんかモヤモヤしたものが残る。

ngrok → Tailscale

家のDesktop PCに外部からsshするのに、今まではngrokを使っていたが、Tailscaleに乗り換えた。乗り換え理由は、以下の2つ。

  • ngrokはFree planの場合に実行ごとに接続先のポート番号が変化し、Pro以上の有料プラン($20/month)でなければ固定できない
    • ポート番号が変わるたびに、接続元のsshで毎回ssh -pオプションで指定するか、.ssh/configを書き換える必要がある。前者の場合VSCodeのRemoteが使えない
    • Tailscaleならば、一度端末を設定してしまえばIPアドレスは固定のため、変更する必要がない
  • tensorboardや各種web appを利用するときに、ssh -Lのポートフォワーディングで毎回ポート番号を指定しなければいけない
    • sshが切れると当然ながらアクセスできなくなる
    • Tailscaleならばポートフォワーディングが不要でかつ、Magic DSNで端末名を利用できる

唯一の欠点は、接続元でVPNを利用するため、他のVPNを利用できなくなることだろうか。出先のWifiに繋ぐときは気をつけなければいけない or Exit Nodesを使わなければいけない。

今回の場合、接続する端末が固定という点でTailscaleに利があった。規約改定前のColabなど、接続端末が不定クラウドを利用するときはngrokの方が便利な場合がある。