機械学習をやるのにGPUベースでやりつつもmacOSの画面で作業はしたい
概要
こんにちは。大和です。
機械学習をやる場合にCPUベースではなくてGPUベースでやりたい昨今ですが、現状のApple製品ではNvidiaのGPUを載せていないことや事実上のデファクトスタンダードになっているTensorFlowがMetalに対応してないこと、NvidiaのGPUを載せているMacでもGPU自体が古いなど、いろいろと面倒なことになっています。
なので、機械学習用に別途UbuntuでPCを組む(僕の場合はゲーミングPCみたいなやつを譲ってもらった)ことになるんですが、そうなると画面が別になるとかそういうことがあってまた面倒。
できれば使いたいときにさっと使えるように、画面切り替えとかせずにmacOSで使いたいわけです。
そうなるといくつか選択肢があります。
- リモートデスクトップで使う
- Ubuntuにjupyter notebookを--no-browserをつけて起動して外からブラウザ経由で使う
- 2の状態のところにsshのポートフォワードで接続する
1は、やってみましたがレスポンスが悪いのと外から使うのが面倒なので却下。
2は、ローカルネットワークならこれでいいんですが、外部からアクセスしたい場合にはjupyter notebookをWANにさらしている事になるのでこれも却下。
というわけで3が一番安全そうです。
外部から接続したい場合はsshのポートだけをルーターでマッピングしておくなりサーバを晒していたとしても、ポートの開放はsshだけとかにしておけばいいわけですね。
本当はVPSで適当なサーバを用意して、SoftEthaとかでVPNを組んでしまうとかするとさらに良い感じはしますが、その辺は目的と手段が逆転しそうなあたりなのでとりあえず手を出さない事にします。
やりたい事
Ubuntuで動いてるjupyter notebookに、別のマシン(macOS)のブラウザでアクセスして機械学習を行いたい。
ちなみにローカルネットワークでの接続を前提にしてるのでグローバルから接続するにはそれなりに読み替えたり注意したりする必要があります。
事前準備
Ubuntu側でSSHでログインできる環境を作る
この辺りは割愛します。ポートの変更やルートログインの禁止など当たり前にやることはやっておきましょう。この辺りができない人はこの記事はそっ閉じしてください。
Ubuntu側でJupyter notebook環境(というか機械学習の環境をつくる)
ちょっと記事的には古いのと、インストール対象がmacOSなのですが僕が書いた以下の記事を参考に読み替えたりしていくといいと思います。
今更ながらTensorFlowとKerasのセットアップをしてみる:
https://qiita.com/dropcontrol/items/a469efd94c59007d3f61
もちろん「ubuntu tensorflow jupyter notebook インストール」みたいにしてググってもいいでしょう。
ちなみに、僕の場合は
- anyevnでpyenvの環境を作る
- pyenvでminiconda3-latestをインストールする
- condaで各種環境を管理する
という感じでやっています。
接続方法
上記のような環境が整い、ローカルでjupyter notebookが使えるぞ、というところまで準備が整ったら、
$ conda activate <環境名>
とかで、tensorflowなどをインストールしてあるpythonの実行環境を有効に出来るようになったかと思います。
次にjupyter notebookを以下のように起動します(これらはmacOSからSSHでログインしてTerminalで行ってもubuntu側のローカルで直接行っても同じです)。
$ jupyter notebook --no-browser --port=8080
--no-browserはjupyter notebook起動時にブラウザが起動してこないようにするため、--port=8080はjupyter notebookのポート番号です。
そしたら次にsshでポートフォワードを設定して、macOSのブラウザから起動したjupyter notebookにアクセスできるようにします。
これはアクセスする側のmacOSから行う必要があります。
$ ssh -N -L 8080:localhost:8080 @<SERVER_ADDRESS>
<USERNAME>@<SERVER_ADDRESS>のところはSSHでログインする側のubuntuのユーザー名とサーバー情報です。
もしsshのconfigにエイリアス(?)を設定してある場合はhoge@serverみたいな感じでも大丈夫です。
外部からアクセスする場合はここのサーバー情報が外側からアクセスできるIP Addressやサーバ名になります(僕は.ssh/configの中にserver1.local、server1.globalみたいにして設定を使い分けてます)。
ここまで出来ればあとはブラウザからlocalhost:8080にアクセスすればjupyter notebookをmacOSのブラウザで使うことができます。
超快適。
(Jupyter notebook自体の設定には触れないので、各自ググって探してみてください)
すぐに思いつく課題
- ubuntu起動時によく使うpythonの環境のアクティベートとjupyter notebookの起動はしてしまいたい
- 手動で起動するにしてもターミナルを閉じてもjupyter notebookが終了しないようにしたい
などが使っていると出てくると思います。
前者についてはシェルスクリプトとSupervisorなどを使ってデーモンかすればいいかなと思いますが、その場合jupyter notebookをバックグラウンドで起動する必要があります。
以下のページにjupyter notebookの便利な使い方がまとまっていましたのでそれを参考にします。
Jupyter Notebookをより便利に使うために、色々まとめ:
https://qiita.com/ishizakiiii/items/b98bbf8997f039f40058
上記の中で「バックグラウンドジョブで動かす」というのがありますので、
それを参考にして先ほどのjupyter notebookの起動コマンドを以下のように変えます。
$ nohup jupyter notebook --no-browser --port=8080 >> jupyter.log 2>&1 &
- nohup ... 端末を閉じてもログアウトしても処理を続ける
- >> jupyter.log 2>&1 & ... コマンドからの出力結果をjupyter.logというファイルにバックグラウンドで出力する(この例だとjupyter notebookを実行したディレクトリに出力されます。特定の場所を指定するにはパスを書いてあげれば良いです。というか気がつくとログが肥大するので特に問題が出なければこれをつけなければログは出力されないのでそれでもいいかもしれません)
このコマンドで起動しておけば、いつでもローカルネットワークならポートフォワードした後に http://localhost:8080 にアクセスすればjupyter notebookが使えるようになりました。
あとは上記のコマンドが面倒なのでshellのエイリアスで “jpn_start_bg”などと名前をつけておけばいいのではないでしょうか?(condaで有効にする環境を指定したり、ポートを分けて複数立てたいとかもあるかもなので、その場合はそういう起動用のシェルスクリプトを組むとかになるでしょうが、その辺は自分が必要になったらまたまとめます)。
これでめんどくさいことが一つ減りました!!
追記その1・根気のある人は下記のURLを参考にしてdemonizeしてしまう、という手もあります。
しかし、condaで環境切り替える、とか考えだすとそこまでやるのもな…という気持ちになります。
どっちみち動いてるのはjupyter notebookなので、demonizeするから安定するとかそういうことではきっとないだろうし(調べていませんので確かな話ではありませんが)。
How to Setup Jupyter Notebook Server as a daemon service:
https://towshif.github.io/site/tutorials/Python/setup-Jupyter/
追記その2・sshは時間が経つと接続が切れてしまうので、どうしたらいいのか?という話。
結論から言うと「screenコマンドを使うようにしましょう」だと思います。
screenコマンドというのはsshした先のシェルでさらに仮装シェルを作ってそこで色々とシェルの作業を実行する環境です。
細かい話は書きませんので「screen linux 使い方」とかでググってみると色々と情報が出てきます。
作業の終わりにはちゃんとデタッチしてからTerminalを閉じましょう。
お仕事のご依頼/相談/問い合わせ
シグナル・コンポーズでは音楽制作、Max/Max for Liveデバイス制作など、各種テクニカルなコンサルティングやディレクション、R&D、プロトタイピング、制作などお受けしています。何かあればお気軽にお問い合わせください。お待ちしております!
執筆:大和 比呂志
関連記事
-
Blog
Expressで作ったNode.jsアプリでhttpsを有効にするには?
-
Blog
これからのリベラルな音楽のためのアカデミー
-
Blog
Music Transformerを動かしてみる
-
Blog
自前サーバで HTTP Live Streaming 配信をする
-
Blog
MacBook Proをクラムシェルにした時iPhoneをウェブカムの代わりにして使うには?と、あと少しのTips
-
Blog
unityを始めてみようか。
-
Blog
ORCΛでMIDI音源を鳴らす(IAC Busの場合)
-
Blog
tensorflow1.15系と2.0系を同居させておくには?(ubuntu, GPU環境)
-
Blog
マジで最初から Swift で iOS アプリ作る(TextView)
-
Blog
マジで最初から Swift で iOS アプリ作る (Hello SwiftUI!)