PyCharmでColabをSSH経由で使いたい
はじめに
対象読者
- Google Colabを使っている(それはそう)
- PyCharmを使っている
- VSCodeの人は ( https://qiita.com/Koshka/items/f75ffb910d9ee9202baf )をみてください
背景
colab(これから小文字表記します)はたった1072円/月でGPU(V100, P100)やTPU(v2)を使うことができる超優良サービスです。
自分は .ipynb
でコーディングするのに慣れてないのと愛用してるエディタを大切にしたいという思いがあってSSH接続を試みています。
やり方
colab上でやること
1ブロック目にこれをコピペして実行してください。
ngrokのトークンを求められるのでそれもコピペしてください。
import random, string, urllib.request, json, getpass
#Generate root password
password = ''.join(random.choice(string.ascii_letters + string.digits) for i in range(20))
#Download ngrok
! wget -q -c -nc https://bin.equinox.io/c/4VmDzA7iaHb/ngrok-stable-linux-amd64.zip
! unzip -qq -n ngrok-stable-linux-amd64.zip
#Setup sshd
! apt-get install -qq -o=Dpkg::Use-Pty=0 openssh-server pwgen > /dev/null
#Set root password
! echo root:$password | chpasswd
! mkdir -p /var/run/sshd
! echo "PermitRootLogin yes" >> /etc/ssh/sshd_config
! echo "PasswordAuthentication yes" >> /etc/ssh/sshd_config
! echo "LD_LIBRARY_PATH=/usr/lib64-nvidia" >> /root/.bashrc
! echo "export LD_LIBRARY_PATH" >> /root/.bashrc
#Run sshd
get_ipython().system_raw('/usr/sbin/sshd -D &')
#Ask token
print("Copy authtoken from https://dashboard.ngrok.com/auth")
authtoken = getpass.getpass()
#Create tunnel
get_ipython().system_raw('./ngrok authtoken $authtoken && ./ngrok tcp 22 &')
#Get public address and print connect command
with urllib.request.urlopen('http://localhost:4040/api/tunnels') as response:
data = json.loads(response.read().decode())
(host, port) = data['tunnels'][0]['public_url'][6:].split(':')
print(f'SSH command: ssh -p{port} root@{host}')
#Print root password
print(f'Root password: {password}')
すると、下のように出力されます。hoge
の部分は実行ごとに変わります。
hoge_1
: ポート番号root
: ユーザー名hoge_2.tcp.ngrok.io
: ホスト名hogehogehoge_3
: パスワード
SSH command: ssh -phoge_1 root@hoge_2.tcp.ngrok.io
Root password: hogehogehoge_3
PyCharm上でやること
SSH接続
[Settings]→[Add Python Interpreter]で先程colab上で出力されたポート番号からホスト名まで入力してNEXTを押してください。
すると、パスワードを求められるのでこちらも同様にcolabの出力をコピペしてください。
変更点です。
- インタプリタ
- Interpreterを
/usr/bin/python
→/usr/bin/python3
- Interpreterを
次に[Python Interpreter]→⚙→show all→(さっき追加したSSHのものを)Edit
そしたらRoot path
を /content
に変更してください。また、MappingsのほうではDeployment path
とWeb path
を/
に設定してください。
そしたらOK押して、Deployment configuration
がさっき変更した名前と同じか確認してください。違っていたら、Deployent configuration
の右を押すと一覧が出てくるので変更したものを選択してください。
確認
右のタブからRemote Host
を押してください。そこに下のような画面が出てきたらOKです。(contentと1.pyは無いと思うが)
逆にbin
やroot
というフォルダが見えているようであれば、さきほどの設定でRoot path
を設定し忘れているはずです。今回はcolabにあわせて/content
をRoot path
にしています。
あとは、適当なファイルを作って実行をすると勝手にSSH接続先にファイルを転送して実行してくれます。上の画像は実行後の画像なので、下にCPUのコア数と作業ディレクトリの場所が表示されています。
うまく転送できていた場合、colabからも確認することができます。
実行ができない場合
ファイルの転送先が間違ってる可能性が高いです。この画像のDeployment configuration
の設定を確認してください。
あとデバッグする方法として、FileTransfer
をみるものがあります。接続先と転送先をちゃんとみてください。
参考にしたもの、メモなど
How can I to google colaboratory VM? | Stack Overflow
colabでエラー
こんなやつ。
URLError: <urlopen error [Errno 99] Cannot assign requested address>
ngrokは1つしか転送できないことに起因してそうなので、既にngrokを使っているnotebookをshutdownするかアカウントを変えるかなどして対処してください。
colabでどうにもならないとき
http://localhost:4040/api/tunnels
に何も存在しないっていうエラーがあると思います。(この前それになった)
Colab SSH というライブラリを使ってとりあえずSSH接続してください。ファイル転送(SFTP)はPyCharmでできるので設定してください。(OpenSSHというところで)
自分は ~/.ssh/config
を設定したのですが、これをせずにできるかは未検証です。
実行はTerminalでSSH接続してシェル叩けばどうにかなると思います。