SageMakerカスタムカーネルを作って永続化

# 概要

Notebookインスタンスを再起動した後も停止前にインストールしたライブラリを再インストールせずに使えるようにするための方法です。


# 前提/問題
AWS Sagemaker Notebookインスタンスは、インスタンスを停止すると、```pip```コマンドなどでインストールしていたライブラリが**再起動後に使えなくなってしまいます。**

インストールするライブラリの数が2,3個でかつインストールに時間がかからないような場合であれば、インスタンス再起動後にもう一回インストールすれば済むのですが、次のようなシチュエーションでは問題となります。


1. インストールする必要があるライブラリが多数存在し、Notebookインスタンスを再起動するたびにインストールするのに時間がかかってしまう場合
→インストールが面倒くさい。開発/作業効率が落ちる
2. 会社のAWS環境などでプロキシ設定されてしまっており、pipなどで自由にライブラリをインストールできない環境の時、セキュリティ担当部署で一時的にプロキシを開放し、作業完了後にすぐにプロキシを閉じてしまうような場合
→プロキシが閉じられた後にインスタンスを停止してしまうと、インスタンス再起動後、せっかくインストールしていたライブラリが使えなくなってしまう


# 解決方法

自分が使いたいライブラリを事前にインストールしたカスタムカーネルを作成し、そのカーネルを使ってJupyter Notebookを立ち上げるようにします。

具体的な方法を以下で解説します。


# ステップ
細かい方法は各節で解説しますがまずは大きな流れを記載します。


1. ライフサイクルを設定する
2. Notebookインスタンスを作成し、その時にライフサイクル設定にて、ステップ1で作成したライフサイクルを指定する
3. カスタムカーネルを作成する

## 1. ライフサイクルを設定する

Sagemakerマネジメントコンソールから「ライフサイクル設定」（英語の場合は Lifecycle configurations）を開き、「設定の作成」（Create configurations）を開きます。
![Untitled.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/687015/5c58ac93-a094-cb24-e92d-7737b738fea7.png)


「Jupyter server app」を選び、「次へ」をクリックします。
gatewayの方は、別のアプリケーションからjupyterを呼び出して利用する時に使うものなので、今回は使いません。
![Untitled (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/687015/06205b25-8dba-b010-007b-f2ecd37d95ec.png)

次のような画面が出てくるので、適当に名前を付けます。今回は「myenv」という名前にしました。

![Untitled (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/687015/41ea8578-af74-0a83-7dd7-12fa8747abc3.png)

スクリプトの中身は↓の中身をそのままコピペします。

```bash
#!/bin/bash

sudo -u ec2-user -i <<'EOF'


if [ -d "/home/ec2-user/SageMaker/kernels" ]; then
    for env in /home/ec2-user/SageMaker/kernels/*; do
        source activate $env
        python -m ipykernel install --user --name $(basename "$env") --display-name "$(basename "$env")"
        source deactivate
    done
fi

EOF

```







## 2. Notebookインスタンスを作成し、その時にライフサイクル設定にて、ステップ1で作成したライフサイクルを指定する

左のメニューバーから、「ノートブック」を選び、ノートブックインスタンスを作成します。
![図1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/687015/61110d25-51c4-c686-311d-b855de847195.png)


適当にノートブックの名前を付け、下の図の赤枠をクリックして、トグルを開きます。![図2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/687015/0e94bd29-6c6b-78b1-abfb-f7006dfa1fd8.png)


すると、ステップ1で作成した「myenv」が出てきます。（画像ではmyenv2がありますがこれは筆者が実験で作成していたものなので、無視してください）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/687015/24209d32-d6d0-ab95-a840-d01c05e7db7b.png)

Notebookインスタンスを作成します。


## 3. カスタムカーネルを作成する

初期ではカーネルは下の画像のものしかないと思います。今からやる作業をすることで、ここに自分が作成したカスタムカーネルが表示されるようにします（下画像の赤枠）。

![図4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/687015/e4d5f64c-2b68-6e31-af7c-dbfbe4619085.png)


Notebookから「Terminal」を選択します。

![図3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/687015/6297283e-6a70-495d-186e-ab4adc759f52.png)

すると↓のようにターミナル画面が出てきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/687015/d4333236-fd81-6b9d-ad54-7a95edbdd84d.png)



ターミナルの中で↓のコマンドをうちます。ここでは、pythonのバージョンを"3.10" としていますが、それ以外のバージョンを使いたい場合はそこの数値を書き換えてください。

コマンドが意味するところは、```/home/ec2-user/SageMaker/kernels/myenv```というディレクトリにcondaカーネルを新規で作成することを意味しています。そのため、カスタムカーネルの名前を「testenv」としたい場合は、```/home/ec2-user/SageMaker/kernels/testenv```などどすればOKです。
```bash
conda create --prefix /home/ec2-user/SageMaker/kernels/myenv python=3.10 ipykernel
```

次に↓のコマンドを打ちます。
先ほど作成したディレクトリのanacondaカーネルをアクティベートします。

```bash
source activate /home/ec2-user/SageMaker/kernels/myenv
```

自分で入れたいライブラリがある場合は次のコマンドを打ってください。デフォルトのanaconda環境で問題ない場合はここのコマンドは打たなくともOKです。

↓の例では、openaiとpandasを```pip```コマンドでインストールしています。
```bash
pip install openai pandas
```

※anaconda環境をアクティベートする前に```pip install```してしまうと、Notebookインスタンスのデフォルトのディレクトリにライブラリがインストールされてしまうため、今作成しているカスタムカーネル内にはインストールされません。したがって、インスタンスを停止し再開しても当該ライブラリを再インストールする必要が出てしまいます。


次に↓のコマンドを打ちます。
カスタムカーネルを「myenv」ではない名前にしている場合は、下のコマンドで「myenv」としているところを書き換えてください。例えば、「testenv」としている場合は、コマンドは```python -m ipykernel install --user --name testenv --display-name testenv```となります。

```bash
python -m ipykernel install --user --name myenv --display-name myenv
```

最後に↓のコマンドを打ちます。

```bash
source deactivate
```

場合によっては、```conda deactivate```というコマンドを打ってくれという警告が出るので、その警告が出た場合は素直に従いましょう。


ここまで出来たら、ターミナルを開いているタブを閉じてしまってOKです。↓の画像のように、「kernels」という名前のフォルダが出来上がっているはずです。
![Untitled (4).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/687015/90fb3c3a-21f9-5093-c350-085c2efbb7e0.png)


# まとめ

筆者はsagemakerを使っており、節約のためにnotebookインスタンスを停止&再起動を繰り返していたのですが、案の定、毎回同じライブラリを何度もインストールするが面倒くさくなってきました。

そこで、カスタムでライブラリを事前インストールする方法がないか探していたのですが、意外と見つけることができず、いろいろ調べまくって上手くいった方法を今回は備忘録的にまとめてみました。