Amazon SageMaker Studio の JupyterLab で R を使いたい！

## はじめに

こんにちは！ AWS の Amazon SageMaker という機械学習のための IDE をご存知ですか？

どんどんアップデートされていて、最近 UI が大幅に変更されてかなり使いやすくなってきました。そろそろ Amazon SageMaker ノートブックインスタンスから乗り換えを検討する時期かもしれません。

とはいえ、裏側のアーキテクチャもだいぶ違うし、今まで快適に使ってた環境は新しい SageMaker Studio でも使えるのかな？と思われている方もいるかもしれません。そこで今回は、R ユーザの皆様に向けて、新しい SageMaker Studio の特に JupyterLab で R の環境を構築する方法をご紹介します。

もちろん、R 以外の環境も同様にインストール可能です！

## R 環境の選択肢

新しい SageMaker Studio で R 環境を構築する方法はざっくり以下の 4通りです。


1. JupyterLab を起動した後ターミナルで R を手動インストール
1. SageMaker ライフサイクル設定で R をインストール
1. R 入りカスタムコンテナイメージを SageMaker Distribution イメージとして設定
1. RStudio のライセンスを購入して利用

4 の RStudio を使う方法は RStudio のライセンスを購入して SageMaker Studio から使う方法です。 [こちらのドキュメント](https://docs.aws.amazon.com/sagemaker/latest/dg/rstudio-manage.html) で説明されているのでこの記事では割愛します。

### 事前準備

#### Amazon SageMaker Studio の準備
[Quick setup](https://docs.aws.amazon.com/sagemaker/latest/dg/onboard-quick-start.html) か [Custom setup](https://docs.aws.amazon.com/sagemaker/latest/dg/onboard-custom.html) の方法を参照して、SageMaker Domain とユーザプロファイルを作成してください。

### ターミナルで R を手動インストール

（この方法は一番手軽ですが、JupyterLab を再起動するたびにこの手順を実行する必要があります。）

AWS コンソールから Amazon SageMaker Studio を起動してください。以前 Amazon SageMaker を使ったことのある方なら、初回起動の速さに驚くと思います。

こんな感じで、SageMaker Studio が起動します。左側のメニューの左上にある、オレンジ色の JupyterLab アイコンをクリックしてください。

![sagemaker-studio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315319/8a16a9ee-dfb0-a6fb-a9a7-c28190b6788c.png)

すると、以下のような画面が表示されるので、右上にある「+ Create JupyterLab space」ボタンをクリックして、好きな名前をつけて「Create space」ボタンをクリックします。これで JupyterLab space が作成されます。

![jupyterlab.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315319/9e4b2113-dfed-37b2-7ad9-e080b834eef5.png)


数秒待つと、以下のように「Run space」ボタンを押せるようになります。この画面で、「Instance」と書かれているメニューをクリックして、インスタンスタイプを ml.t3.large 以上のスペックに変更します。私が試したときは、デフォルトの ml.t3.medium だと R のインストールがタイムアウトで中断してしまい、うまくいきませんでした。ml.t3.large では問題なく R をインストールできました。

![instance.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315319/bb120f09-5cff-d4c3-e21a-2df10b7f5131.png)

インスタンスタイプを変更したら、「Run space」ボタンをクリックして JupyterLab space を開始します。数分待つと、「Open JupyterLab」ボタンを押せるようになるのでクリックします。すると、以下のような Launcher が表示されます。この画面の Other のエリアにある、Terminal をクリックします。

![launcher.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315319/db402c52-8740-f4e4-0c7f-6ecfaefd3083.png)

すると、以下のようなターミナルが表示されるので、`conda install -c conda-forge --freeze-installed --yes r-base r-irkernel` というコマンドで R をインストールします。

![terminal.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315319/519e344b-fd82-a505-0851-dcff0108d056.png)

すると、Launcher に以下のように R アイコンが表示されるようになります。このアイコンをクリックすれば、R が使える状態のノートブックが開きます。R アイコンが表示されない場合は、いったん Launcher タブを閉じて、+ ボタンで再度 Launcher を開いてください。

![r-installed.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315319/e862e46c-3cf4-98b6-c08c-2a8b1ed05d56.png)

### SageMaker ライフサイクル設定で R をインストール

上記の手動インストールは簡単ですが、JupyterLab を再起動するたびにインストール手順を実行しなければなりません。そこで、ライフサイクル設定を使って、R のインストールを JupyterLab 起動時に自動で行うようにします。

SageMaker コンソール（SageMaker Studio ではなく、AWS コンソールの方）の左側のメニューの、「Admin configurations」->「Lifecycle configurations」をクリックします。

以下のような画面が表示されるので、「JupyterLab」タブを選択して、オレンジ色の「Create configuration」ボタンをクリックします。

![lifecycle.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315319/99fd8794-c309-dce4-6d48-44cfc2b248b9.png)

その後、適当な名前をつけて、 Scripts のエリアにあるテキストボックスに以下のスクリプトをコピー＆ペーストして、右下の「Create configuration」ボタンをクリックします。

```bash
#!/bin/bash
set -eux
conda install -c r --freeze-installed --yes ipykernel r-base r-irkernel
```

次に、SageMaker コンソール左側のメニューの、「Admin configurations」->「Domains」をクリックします。事前準備で作成したドメインが表示されるので、そちらをクリックします。

すると、以下のようにドメインの詳細画面が表示されるので、一番右側の「Environment」タブをクリックします。

![domain.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315319/57efb69d-f316-0255-73fb-b34ac22c1301.png)

すると、「Lifecycle configurations for personal Studio apps」と書かれたエリアがあるので、そこにあるオレンジ色の「Attach」ボタンをクリックします。

すると、以下のような画面が表示されるので、「Existing configuration」を選択して、先ほど作成したライフサイクル設定を選んで、右下にあるオレンジ色の「Attach to domain」ボタンをクリックします。この画面で「New configuration」を選択してここからライフサイクル設定を作成することもできます。

![attach.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315319/1ede6597-c98c-2049-183a-7fa78e5c1ef1.png)

ここまでの手順で、ライフサイクル設定を SageMaker ドメインにアタッチできたので、JupyterLab の画面でライフサイクル設定を選択できるようになります。次の手順に進む前に、JupyterLab が稼働中の場合は、一旦停止させてください。

ライフサイクル設定を選択する前に、「Instance」と書かれているメニューをクリックして、インスタンスタイプを ml.t3.large 以上のスペックに変更します。私が試したときは、デフォルトの ml.t3.medium だと R のインストールがタイムアウトで中断してしまい、うまくいきませんでした。ml.t3.large では問題なく R をインストールできました。

![instance.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315319/bb120f09-5cff-d4c3-e21a-2df10b7f5131.png)

次に、「Lifecycle Configuration」で作成したライフサイクルを選択してから、「Run space」をクリックし、その後、「Open JupyterLab」ボタンをクリックします。

![r-set.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315319/cfa81ef2-f2de-91cd-513b-53bbb45df625.png)

これで、手動で R をインストールしなくても、Launcher に R のアイコンが表示されるようになります。

### R 入りカスタムコンテナイメージを SageMaker Distribution イメージとして設定

最後は、カスタムコンテナイメージを作って、それを SageMaker Distribution イメージとして使う方法です。すでに利用しているカスタムコンテナの環境にできるだけ近づけたいという場合はこちらの方法がおすすめです。また、この方法だと ml.t3.medium インスタンスを使用することができます。

以下は、[こちらのドキュメント](https://docs.aws.amazon.com/sagemaker/latest/dg/studio-updated-jl-provide-users-with-images.html#studio-updated-jl-create-dockerfile) に記載されている例をもとにした、R をインストールする Dockerfile の例です。この例の場合、ビルドしたコンテナイメージのサイズが 3GB ほどになりますが、より小さいイメージを作りたい場合は、[こちらのドキュメント](https://docs.aws.amazon.com/sagemaker/latest/dg/studio-updated-jl-provide-users-with-images.html#studio-updated-jl-create-dockerfile) の Amazon Linux 2 をベースイメージにした方のサンプルをベースにして Dockerfile を作成してください。

```Dockerfile
FROM public.ecr.aws/sagemaker/sagemaker-distribution:latest-cpu
ARG NB_USER="sagemaker-user"
ARG NB_UID=1000
ARG NB_GID=100
ENV MAMBA_USER=$NB_USER
USER root

RUN apt-get update
RUN micromamba install sagemaker-inference --freeze-installed --yes --channel conda-forge --name base 'r-base' 'r-irkernel'

USER $MAMBA_USER
ENTRYPOINT ["jupyter-lab"]
CMD ["--ServerApp.ip=0.0.0.0", "--ServerApp.port=8888", "--ServerApp.allow_origin=*", "--ServerApp.token=''", "--ServerApp.base_url=/jupyterlab/default"]
```

上記 Dockerfile を使って Docker イメージをビルドし、Amazon ECR レポジトリに push します。以下は、ECR レポジトリ作成、Docker イメージのビルド、イメージの push を実行するスクリプトの例です。リージョンやリポジトリ名などは適宜変更してご利用ください。

```bash
REGION="us-west-2"
ACCOUNT_ID=$(aws sts get-caller-identity --query 'Account' --output text)
REGISTRY_URL="${ACCOUNT_ID}.dkr.ecr.${REGION}.amazonaws.com" 
IMAGE_TAG="latest"
ECR_REPOGITORY="custom-r-image"
IMAGE_URI="${REGISTRY_URL}/${ECR_REPOGITORY}"

aws ecr get-login-password | docker login --username AWS --password-stdin $REGISTRY_URL
aws ecr create-repository --repository-name $ECR_REPOGITORY

docker build  -f Dockerfile.r . -t $ECR_REPOGITORY
docker tag ${ECR_REPOGITORY} $IMAGE_URI:${IMAGE_TAG}
docker push $IMAGE_URI:${IMAGE_TAG}
```

コンテナイメージを ECR レポジトリに push できたら、SageMaker のコンソールに行き、左側のメニューにある「Admin configurations」->「Domains」をクリックします。事前準備で作成したドメインが表示されるので、そちらをクリックします。

すると、以下のようにドメインの詳細画面が表示されるので、一番右側の「Environment」タブをクリックします。

![domain.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315319/57efb69d-f316-0255-73fb-b34ac22c1301.png)

一番上の、「Custom images for personal Studio apps」のエリアにあるオレンジ色の「Attach image」をクリックします。「New image」を選択して、先ほど push したコンテナイメージの URI をテキストボックスにコピペして、右下の「Next」をクリックします。

![select-image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315319/130c4bae-29b3-48f2-8d6b-c4342b3c5478.png)

次に、適当な名前をつけて、以下の部分は「Jupyterlab image」を選択して、右下の「Submit」ボタンをクリックします。

![container.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315319/712e95cc-5bbd-429e-630d-09063a4ddd57.png)

ここまでで、カスタムイメージを SageMaker Distribution イメージとして設定できたので、JupyterLab の画面の「SageMaker Distribution」メニューで選択できるようになります。次の手順に進む前に、JupyterLab が稼働中の場合は、一旦停止させてください。

先ほど作成したイメージを選択して、「Run space」をクリックし、その後、「Open JupyterLab」ボタンをクリックします。

![select-dist.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315319/53b13620-b387-341b-a1b7-d163ae97ac96.png)

## おわりに

この記事では、新しくなった Amazon SageMaker Studio の JupyterLab で R 環境をインストールする方法を紹介しました。

環境の移行ができるか不安で新しい SageMaker Studio を使うのを躊躇していたんだよねー、という方のお役に立てば幸いです。