GCPでのディープラーニング学習環境構築方法

# GCP(Google Cloud Platform)でディープラーニング学習環境構築方法
## 背景
　ようやく[DockerでのディープラーニングGPU学習環境構築](https://qiita.com/karaage0703/items/e79a8ad2f57abc6872aa)に成功した @karaage0703 。疲れを癒す間も無く、ディープラーニングの帝王Google社のデベロッパーアドボケイトから、新たなる天啓がくだる。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">度々からあげさんの記事を引用して恐縮ですが、もしGCPを使う場合は、このあたりをまるっとイメージにまとめたDeep Learning Containersってのもあります。ポチるだけでCUDA/TF/Jupyter/その他全部入りのコンテナをGKEで動かせます。 <a href="https://twitter.com/hashtag/gcpja?src=hash&amp;ref_src=twsrc%5Etfw">#gcpja</a><a href="https://t.co/tszxsK6sic">https://t.co/tszxsK6sic</a><a href="https://t.co/VMo9OHBjUp">https://t.co/VMo9OHBjUp</a></p>&mdash; Kazunori Sato (@kazunori_279) <a href="https://twitter.com/kazunori_279/status/1291816372222140416?ref_src=twsrc%5Etfw">August 7, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>


<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">CUDAドライバ周り、誰しもハマりますよね。ちなみにGCPではこの辺りまるっと全部入りのDeep Learning VMってのがあるのでラクです。技術サポートも受けられます。GCEとAI Platform Notebooksで使えます。 コンテナ版のDeep Learning Containerもあります。 <a href="https://twitter.com/hashtag/gcpja?src=hash&amp;ref_src=twsrc%5Etfw">#gcpja</a> <a href="https://t.co/FCtxvUZR4O">https://t.co/FCtxvUZR4O</a> <a href="https://t.co/MykmNT4z8G">https://t.co/MykmNT4z8G</a></p>&mdash; Kazunori Sato (@kazunori_279) <a href="https://twitter.com/kazunori_279/status/1290328502160433152?ref_src=twsrc%5Etfw">August 3, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>


　喜び勇んで、GCPの無料アカウントを作成した @karaage0703 そこには、おびただしい数のメニューと、膨大なドキュメント…からあげのGoogleとの戦いは始まったばかりだ！（戦ってません）

## GCPでディープラーニング学習環境を構築するメリット
　以下のようなメリットがあります。

- 様々なフレームワーク（TensorFlow/PyTorch）、バージョンの使い捨ての学習環境を一瞬で構築できる
- 計算リソースを、文字通り一瞬で確保できる
- 家にでかいパソコンを置いて熱々になることが無い

　Googleの無料枠で試せる範囲での記事です。無料枠だとGPUは使えないので、GPUは使っていませんが、基本的な流れは同じです。

## この記事の前提（必要なもの）

- 基礎的なLinuxコマンドの知識
- ネットに繋がるPC（Google ChromeブラウザがあればOK）

# GPUでのディープラーニング学習環境構築の流れ
　最初にGCPに登録した後、以下の2通りの方法があります。

- ComputeEngineで学習環境を構築
- AI Platformで学習環境を構築

　ComputeEngineでVMを立ち上げると、自分の好きな環境が作れます。自由度が高い反面、Jupyter Notebookへのアクセスなどは、設定が色々大変です。

　AI Platformは、あらかじめセットアップされた環境を使えて、起動すればJupyter Labに一瞬でアクセスしてディープラーニングを始めることができます。

　使用感覚はGoogle Colaboratoryに近いと思います。Google Colaboratoryの詳細は以下ブログ記事参照ください。
[Google Colaboratoryを使えば環境構築不要・無料でPythonの機械学習ができて最高](https://karaage.hatenadiary.jp/entry/2018/03/21/073000)

　お手軽に試したいならAI Platformがオススメです。この後、GCP登録から順に説明していきます。とりあえず速く試したい人は「ComputeEngineで学習環境を構築」を飛ばして「AI Platformで学習環境を構築」を読んでください。


## GCPに登録
　[GCPの公式サイト](https://cloud.google.com/)にアクセスします。

　無料という文字にフラフラ吸い寄せられてクリックして登録しましょう。クレジットカードの情報は必要ですが、無料枠を使い切ってもそのまま課金されることはないようです。

## ComputeEngineで学習環境を構築
[Compute Engine](https://console.cloud.google.com/compute/)にアクセスします。

　VMインスタンスと表示されるはずなので「作成」をクリックしましょう。このインスタンスというのは、GCP上の仮想マシンです。インスタンスの作成というのは、どこか遠くにあるパソコンを、誰かがセットアップしてくれるとイメージしてください（もちろん、人が頑張ってセットアップするわけではなくソフトウェア技術を使って自動でセットアップされます）。

<img width="430" alt="gcp_vm_01.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/81919/c0c42491-b5f6-8682-7459-d5cd648e4f8d.png">

　VMインスタンスは、ブートディスクの設定だけ、以下のようにUbuntu 18.04LTSを指定しましょう。

<img width="501" alt="gcp_image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/81919/aaedc717-bf6e-24fb-b4be-4fc051cc5450.png">

　他はそのままでOKです。GPUの指定の設定もあるのですが、無料枠だと設定できません。課金したらGPUを指定できるようになります。

　しばらくまつとVMが立ち上がります。もうこの時点で、Ubuntuがインストールされたマシンが自由に使えるようになったことになります。

　以下のように表示されるので「SSH」の横の下矢印をクリックしましょう。以下のように表示されるので「ブラウザウィンドウで開く」を選びましょう（そのままSSHをクリックしてもOKです）。

<img width="780" alt="gcp_01.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/81919/ed8f23eb-3840-5638-74c2-fae9b78d7e8e.jpeg">

　以下のようにブラウザでクラウド上のサーバにアクセスできます。

<img width="1048" alt="gcp_02.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/81919/e093c7cc-b7ad-1fe1-1109-3f718038b3e2.png">

　このまま学習環境をaptコマンドやpipコマンドで構築すれば、立派なディープラーニング学習環境です。

### Dockerを使って環境構築
　VMインスタンス上でDockerを使えば、環境が簡単に構築できます。詳細は以下記事参照ください。

[DockerでのディープラーニングGPU学習環境構築方法](https://qiita.com/karaage0703/items/e79a8ad2f57abc6872aa)

　Docker自体は、以下コマンド実行してインスタンスを再起動すれば使えるようになります。

```sh
$ curl -s https://raw.githubusercontent.com/karaage0703/ubuntu-setup/master/install-docker.sh | /bin/bash
```

　例えば、TensorFlowのDockerイメージを使えば以下コマンドでDocker環境が立ち上がります。

```sh
$ docker run -it --rm --name tensorflow-cpu tensorflow/tensorflow:latest
```

　以下のようにTensorFlow環境が起動します。

<img width="1012" alt="docker.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/81919/4701a6ba-e4bb-e499-d380-8493a2891669.png">


　冒頭で教えてもらったDeep Learning ContainersのDockerイメージも同様に使えます。

[deeplearning-platform-release](https://console.cloud.google.com/gcr/images/deeplearning-platform-release)で使用したいイメージを探せます。

　例えば、以下のようにDockerイメージを使えます。

```sh
$ docker run -it --rm --name tensorflow-gcp gcr.io/deeplearning-platform-release/tf2-cpu.2-0
```

　Jupyter Labを使用したい場合は設定が必要です。

## AI Platformで学習環境を構築
　[AI Platform](https://console.cloud.google.com/ai-platform/)にアクセスします。

　真ん中上の「新しいインスタンス」をクリックした後、好きなフレームワークを選択します（無料枠だとGPUは使えません）。

<img width="719" alt="gcp_ai_01_01.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/81919/717037d0-9863-55d6-c588-93556de8e5f2.png">

　カスタマイズもできますが、今回はそのまま作成をクリックします。

<img width="531" alt="gcp_ai_02.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/81919/12c92342-0786-0b4a-266a-43a8b0a90da5.png">

　インスタンスができたら「JUPYTER LABを開く」をクリックします。

<img width="606" alt="gcp_ai_03.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/81919/01d851f6-f821-2c61-0019-9a4d70636702.png">

　以下のようなブラウザ画面が表示されます。これでJupyter Notebookやコンソールにログインできます。

<img width="1198" alt="gcp_ai_04.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/81919/252ef593-479b-6c69-4bb8-3c098ca5a3fb.png">

　Jupyter Notebookにアクセスすると、ちゃんとTensorFlowがセットアップされています。　

<img width="1198" alt="gcp_ai_05.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/81919/1d285918-0c04-2c99-97ba-a1ec074fc8d9.png">

## GCP Tips
　Tipsなどをメモしていきます。

### メニューのピン留め
　メニューはピン留めできます。

<img width="268" alt="gcp_menu_01.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/81919/71c493bb-1d93-5a79-690e-fac32fe053fc.png">

　ピン留めすると、以下のようにアクセスしやすくなります。

<img width="272" alt="gcp_menu_02.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/81919/5c7179b3-8035-0b4a-ba71-664fd075fcce.png">

　Googleの中の人から教えてもらいました。
<blockquote class="twitter-tweet" data-conversation="none"><p lang="ja" dir="ltr">確かにトップメニューは項目多いですね。お気に入りの項目をピン留めする機能もあるので、一度慣れると迷いません :)</p>&mdash; Kazunori Sato (@kazunori_279) <a href="https://twitter.com/kazunori_279/status/1293483021778087939?ref_src=twsrc%5Etfw">August 12, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

### ファイルのダウンロード・アップロード
　GCP上のインスタンスに手軽にアップロード、ダウンロードしたいときは、「AI Platform」の左側のメニューから、ダウンロード・アップロードできて便利です。

<img width="1198" alt="gcp_ai_05.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/81919/1d285918-0c04-2c99-97ba-a1ec074fc8d9.png">

　速度も結構速いです。ブラウザのSSH画面からもダウンロード・アップロードできるのですが、そちらは速度かなり遅いです。

　ただし、100MBを超えるようなファイルだと、途中でダウンロードが止まってしまうようです。大容量のファイルをダウンロードする場合は、ファイルを分割するか、おとなしくgcloud appを使いましょう。

### SSHの接続が切れても学習を継続する方法
　SSHの接続が切れても、学習が動き続けるようにして欲しいですね。

　そのような場合は、screenやtmuxといった仮想端末ソフトウェアを使うことが多いようです。

　私は byobu という仮想端末ソフトを使っています。詳細は以下ブログ記事参照ください。

[byobuで仮想端末入門（Mac/Linux/Raspberry Pi）](https://karaage.hatenadiary.jp/entry/2016/04/22/073000)

### gcloud
　ファイルのダウンロードやsshアクセスなどがコマンドからできる便利なツールです。

#### gcloudインストール
　gcloud appのインストールは[Installing Google Cloud SDK](https://cloud.google.com/sdk/docs/install)を参照ください。


#### gcloudのチートシート
　何ができるんだっけ？とか、こんなことできるのか？となったらとりあえずチートシートをみるのが良いでしょう。以下コマンドでみられます。

```sh
$ gcloud cheat-sheet
```

#### gcloudでのGCPインスタンスからのファイルのダウンロード
　具体的なコマンドは以下となります。`<instance name>`はインスタンス名です。コピー元は絶対パス(ex: `/home/<user name>/<file name>`）で指定します。コピー先（ローカルPC）は、コマンドを実行したディレクトリからの相対パスでOKです（今いる場所でよければ`.`）。

```sh
$ gcloud compute scp <instance name>:コピー元 コピー先
```

参考：[GCEからのデータコピーあれこれ (Mac版)](https://www.apps-gcp.com/how-to-copy-from-gce-for-mac/)

#### gcloudでのGCPインスタンスへのファイルのアップロード
　ダウンロードとほぼ同様で、以下となります。

```sh
$ gcloud compute scp コピー元 <instance name>:コピー先
```

　コピー先は絶対パス(ex: `/home/<user name>/`）で指定しましょう。ただ自分の場合`Permission denied`となる場合がありました。

　仕方なく、コピー先（GCP）上で以下のコマンドを実行して、適当なディレクトリ(`test`)を作って、権限を`777`にして、その場所(`/home/<user name>/test`)にアップしました。

```
$ mkdir test && chmod 777 test
```

#### gcloudでのSSHアクセス
　以下のコマンドでSSHでアクセスできます。`<instance name>`はインスタンス名です。

```sh
$ gcloud compute ssh <user name>@<instance name>
```

　gcloud使わず、手軽にSSHログインしたい場合は、ComputerEngineで学習環境を構築のところに書いた、インスタンス立ち上げ後に表示される「SSH」ボタンをクリックしてもOKです。

### VS Codeでのリモート開発
　GCP上のファイルをローカルのVS Codeで直接編集して、リモート開発する方法です。以下ブログ記事参照ください。

[VS CodeのRemote DevelopmentでラズパイでもGCPでもリモート開発](https://karaage.hatenadiary.jp/entry/2020/09/16/073000)

### SSH接続（公開鍵認証）
　gcloudを使わず、自分で公開鍵認証方式でSSH接続する方法です。少し手間なのでgcloudを使うのが基本的にはおすすめです。Macの例ですが、他のOSでも基本的な流れは同じです。秘密鍵と公開鍵という仕組みを使ってアクセスします。この辺りの詳細は割愛しますが（私も詳しくないです）、要は秘密鍵と公開鍵という2つの鍵のペアを勘合札のように使って認証を行う仕組みです。

　まずは鍵を作ります。以下のコマンドを実行ください。メールアドレスはGCPに使用するgmailアカウントを使用します。

```sh
$ cd ~/.ssh
$ ssh-keygen -t rsa -C "<user name>@gmail.com"
```

　以下のように鍵の名前の入力を促すメッセージが出てくるので、好きな名前で保存します（ここでは`gcp`とします）

```
Enter file in which to save the key (/Users/<user name>/.ssh/id_rsa): gcp
```

　続いて、パスワードを2回入力しますので、自分の好きなパスワードを入力してください。

　`gcp`と`gcp.pub`という2つのファイルが生成されますが、それぞれ秘密鍵と公開鍵になります。

　公開鍵の方をGCPに設定します。まずは公開鍵 `gcp.pub` の中身をコピーします。公開鍵は普通のテキストファイルなので、テキストエディタでも開くことができますが、以下コマンドでクリップボードにコピーすると確実です。

```sh
$ pbcopy < gcp.pub
```

　続いて、GCPのインスタンスに鍵を設定しましょう。インスタンスの詳細画面を開きます。AI Platform（GCEでも可）の以下画面で、インスタンス名をクリックします。

<img width="606" alt="gcp_ai_03.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/81919/01d851f6-f821-2c61-0019-9a4d70636702.png">

　インスタンスの詳細情報が出てきます。ここで画面の中ほどに「外部 IP」という表示があります。これがインスタンスのIPアドレスとなります。

　そのあと、画面上の「編集」ボタンをクリックするとインスタンスの編集が可能となります。下の方に「SSH認証鍵が0個あります」という表示があるので、そこに先ほどコピーしたテキストをペーストして保存しましょう。もし入力できない場合は画面上の「編集」ボタンがクリックされていない可能性があります。

　これで設定は完了です。あとは、以下コマンドでsshでアクセスします。`<user name>`はgmailのアカウント名、`<ip address>`は、インスタンスのIPアドレスです（インスタンスの詳細画面で確認できます）。

```sh
$ ssh <user name>@<ip address> -i ~/.ssh/gcp
```

　このあと、パスワードを求められるので、鍵を生成したときに入力したパスワードを入力しましょう。

　ここで注意するのは、秘密鍵を使ってアクセスする点です。間違えて公開鍵（gcp.pub)を使ってアクセスしようとすると、`Permission denied (publickey).`と表示されアクセスできません。理屈を理解していれば間違えませんが、ハマると悩むことになります（私はよく理解せず実行していてハマりました。

　sshでうまく接続できないときはsshコマンドに`-v` オプションをつけると詳細なログを確認できます。エラーメッセージで検索して、原因を調査しましょう。

### GCP上で実行したTensorBoardの結果をローカルで表示
　SSHでトンネルを掘る方法で実現しました。あらかじめ、この前で説明した「SSH接続（公開鍵認証）」ができるように事前に設定しておきます。そして、ローカルPC上で、以下の通りSSHのトンネルを掘ります。`<user name>`はgmailのアカウント名、`<ip address>`はインスタンスのIPアドレスです

```sh
$ ssh -L 8888:localhost:6006 <user name>@<ip address> -i ~/.ssh/gcp
```

　これにより、GCPの6006ポートからローカルPCの8888ポートにトンネルが掘られます。

　GCP上では、TensorBoardを起動します。`<log dir>`はログのあるディレクトリです。ポート番号は、トンネルを掘るときの番号と合わせるようにしてください。

```
$ tensorboard --logdir <log dir> --port 6006
```

　この状態で、ローカルPCのブラウザ（Google Chrome推奨）で、以下のアドレスにアクセスすれば、ブラウザ上にGCPのTensorBoardの実行結果が表示されます。

`http://localhost:8888/`

参考：[リモートからtensorboardにアクセスする](http://miscellanea.hateblo.jp/entry/2017/07/17/231728)

### GCP上でディープラーニングの学習をした後に自動でインスタンスと落とす方法
　クラウド破産しないために。以下記事参照ください。

[GCPでディープラーニング学習後に自動でシャットダウン仕組みを手軽に設定する方法](https://qiita.com/karaage0703/items/cf909547be4912e41733)

## まとめ
　GCPでのディープラーニング学習環境構築方法に関して、簡単に説明しました。

　あまりにメニューが多く絶望しかけましたが、機械学習やディープラーニングなら、Compute EngineとAI Platformを押さえておけば良いのかなと感じました。特にAI Platformはお手軽で良いですね。今後さらにメニューが拡充していきそうです。

　しかし、こんなに簡単に使えるならDockerとか頑張って覚えなくて良かったのでは？という気が今更してきましたが、気づかなかったことにしましょう…　

　今後、GCPに課金もして使っていこうかなと思っています。GCP初心者なので、オススメの使い方などあれば教えてください。

## 参考リンク
[「 GCP入門編」記事一覧（トップゲート）](https://www.topgate.co.jp/tag/gcp-startup-series)

[無料！Tensorflow-gpuをCUDA, cuDNNと共にインストールして使う方法（GCP）](https://qiita.com/Hatomugi/items/9ec1124f370a3fc80057)

[GCPを使ったKaggleのデータ分析　導入編](https://qiita.com/hiro0822/items/44717858462366eda957)

[[秘密鍵/公開鍵]GCPにSSHで接続する方法](https://sleepless-se.net/2018/09/15/gcp-ssh/)

[GCPに自分のPCからssh接続する方法[秘密鍵/公開鍵]](https://dara-blog.com/conect-ssh-gcp)

[Google Colaboratoryで利用していたノートブックをGoogle AI Platformで実行し、さらにコマンドラインからも実行する方法](https://qiita.com/TokyoYoshida/items/f60b165d0b7e60ecb864)

## 変更履歴
- 2020/10/14 Tipsに仮想端末ソフトに関して追記
- 2020/09/16 VS Codeでのリモート開発・gcloudコマンドに関して追記
- 2020/09/15 ファイルのアップロード・ダウンロードに関して追記
- 2020/09/10 GCPへのsshでのアクセスに関して追記
- 2020/08/12 GCP Tips追記