LoginSignup
27
14

Google Colaboratory 上で Elixir Livebook を動かす(GPUを無料で使う)

Last updated at Posted at 2022-10-26

はじめに

Elixir の Nx を GPU 上で動かしたい

Nx を GPU で動かせば、 AI モデルもスイスイ動かせるはず

でも手元に GPU もないし、お金もない、、、

そんな人にオススメなのが Google Colaboratory です

ブラウザからコードを実行、結果を表示できます

基本無料で使用でき、 GPU や TPU まで使える最高のサービスです

え、 Python 用じゃないかって?

そう、 Google Colaboratory は Python の Jupyter Notebook をクラウド上で使用できるサービスです

が、実は Elixir Livebook も実行できてしまうのです

実装したノートブックはこちら(※Evisionを入れるための設定も含んでいます)

2023/08/02

Evision 0.1.33 リリースに伴い改訂

参考記事

準備

以下の二つのアカウントが必要になります

  • Google アカウント
  • ngrok アカウント

ngrok はローカルで起動した Web サービスを外部に公開できるサービスです

例えばローカルの http://localhost:8080https://xxxx-12-34-567-890.ngrok.io のような URL で一時的に外部からアクセスできるようにしてくれます

(もう何をやるか気づいた人は気付いたと思います)

ngrok にサインインしたら、左メニューの「Your Authtoken」を開き、
認証トークンを出しておいてください

スクリーンショット 2022-10-26 18.15.13.png

Google Colaboratory での Livebook 起動

ランタイムの設定

Google Colaboratory で「ノートブックを新規作成」をクリックしてください

スクリーンショット 2022-10-26 18.18.46.png

以下のような画面が開きます

スクリーンショット 2022-10-26 18.21.30.png

GPU が使いたいので、ラインタイムを変更します

上メニューの「ランタイム」から「ラインタイムのタイプを変更」をクリックしてください

スクリーンショット 2022-10-26 18.23.26.png

開いたモーダルで「GPU」を選択し、「保存」をクリックします

スクリーンショット 2022-10-26 18.23.37.png

Erlang と依存パッケージのインストール

再生マークの右にある入力エリア(セル)に以下のコードを貼り付けてください

!echo 'debconf debconf/frontend select Noninteractive' | sudo debconf-set-selections

再生ボタンをクリック(=セルのコードを実行)して、しばらくすると左側に緑色のチェックマークが表示されます

スクリーンショット 2022-10-26 18.26.34.png

Jupyter Notebook で ! を先頭に付けると、シェルコマンドを実行することができます

これを利用して、 Google Colaboratory のコンテナ上に Elixir をインストールするわけです

今実行したシェルコマンドは依存パッケージのインストール中にユーザー入力をしないための設定です

先ほどのセルの下辺あたりにマウスカーソルを持っていくと、「+コード」というボタンが出てくるのでこれをクリックします

(上に表示されている「+コード」ボタンでも良い)

スクリーンショット 2022-10-26 18.28.24.png

すると、セルが一つ下に追加されるので、以下のコードを貼り付けてから、新しいセルを実行してください

apt-get で Erlang と必要なライブラリをインストールします

!wget https://packages.erlang-solutions.com/erlang-solutions_2.0_all.deb && sudo dpkg -i erlang-solutions_2.0_all.deb

!sudo apt-get update -y

!sudo apt-get install -y erlang-base
!sudo apt-get install -y build-essential
!sudo apt-get install -y erlang-dev
!sudo apt-get install -y erlang-inets
!sudo apt-get install -y erlang-parsetools
!sudo apt-get install -y erlang-os-mon
!sudo apt-get install -y erlang-ssl
!sudo apt-get install -y erlang-xmerl
!sudo apt-get install -y libopencv-dev

インストールされた Erlang のバージョンを確認します

!erl -run halt

実行結果は以下のようになります

Erlang/OTP 24 [erts-12.2.1] [source] [64-bit] [smp:2:2] [ds:2:2:10] [async-threads:1] [jit]

{"init terminating in do_boot",{undef,[{halt,start,[],[]},{init,start_em,1,[]},{init,do_boot,3,[]}]}}
init terminating in do_boot ({undef,[{halt,start,[],[]},{init,start_em,1,[]},{init,do_boot,3,[]}]})

Crash dump is being written to: erl_crash.dump...done

asdf のインストール

Elixir は新しいものを使いたいので、 asdf を使います

まず asdf をインストールしましょう

GitHub から asdf をクローンします

!git clone https://github.com/asdf-vm/asdf.git ~/.asdf

asdf の実行ファイルにパスを通します

import os
os.environ['PATH'] = "/root/.asdf/shims:/root/.asdf/bin:" + os.environ['PATH']

Elixir のインストール

asdf で Elixir をインストールするため、プラグインを追加します

!asdf plugin add elixir

2023/08/02 時点の最新 Elixir 1.15.4 をインストールしますが、 Erlang のバージョンが 24 なので、それに合わせて 1.15.4-otp-24 を指定します

!asdf install elixir 1.15.4-otp-24

使用する Elixir のバージョンを 1.15.4-otp-24 に固定します

!asdf global elixir 1.15.4-otp-24

Elixir のバージョンを確認します

!elixir -v

実行結果は以下のようになります

Erlang/OTP 24 [erts-12.2.1] [source] [64-bit] [smp:2:2] [ds:2:2:10] [async-threads:1] [jit]

Elixir 1.15.4 (compiled with Erlang/OTP 24)

Livebook のインストール

次のコードを実行して Livebook の最新版をインストールします

!mix local.hex --force
!mix local.rebar --force
!mix escript.install hex livebook --force

Elixir モジュールの依存パッケージ

Livebook で Evision を使う場合、 OpenCV の依存モジュールが必要になります

また、 Elixir Image を使う場合は libvips が必要になります

Livebook 上で使う Elixir モジュールの依存パッケージをインストールしておきます

!sudo apt-get install -y unzip ffmpeg libavcodec-dev libavformat-dev libavutil-dev libswscale-dev libvips-dev

ngrok CLI のインストール

続いて ngrok のクライアントツールをインストールします

!curl -O https://bin.equinox.io/c/4VmDzA7iaHb/ngrok-stable-linux-amd64.zip
!unzip ngrok-stable-linux-amd64.zip

次のコードを実行すると、パスワード入力が表示されるので、準備しておいた ngrok の認証トークンを入力し、 Enter を押してください

from getpass import getpass

token = getpass()

入力した認証トークンの値を ngrok で使うように設定します

!./ngrok authtoken "$token"

次のコードを実行し、 ngrok でコンテナ内の http://localhost:8888 を外部公開します

get_ipython().system_raw('./ngrok http 8888 &')
!sleep 5s

次のコードを実行すると、公開された URL が表示されます

(ここでエラーが出る場合、 ngrok の認証トークンが誤っています)

!curl -s http://localhost:4040/api/tunnels | python3 -c "import sys, json; print(json.load(sys.stdin)['tunnels'][0]['public_url'])"

スクリーンショット 2022-10-26 18.42.45.png

次のコードを実行し、 Livebook を 8888 ポートで起動します

!!/root/.asdf/installs/elixir/1.15.4-otp-24/.mix/escripts/livebook server --port 8888

うまくいけば Livebook が起動した旨表示され、セルが実行中の状態のままになります

URL の末尾についている ?token=<Livebook認証トークン> の「Livebook認証トークン」の値が必要になるので、コピーしておきます

スクリーンショット 2023-08-02 9.56.21.png

この状態で ngrok の外部公開 URL を開きます

認証を求められるので、先程コピーしておいた「Livebook認証トークン」を貼り付けて "Authenticate ->" をクリックします

スクリーンショット 2023-08-02 9.58.53.png

はい、これで Livebook が開きました

スクリーンショット 2022-10-26 18.47.03.png

Nx の実行

右上「New Notebook」をクリックして、新しいノートブックを開きます

スクリーンショット 2022-10-26 18.49.00.png

Notebook dependencies and setup のセルに以下のコードを貼り付け、実行してください

Mix.install(
  [
    {:benchee, "~> 1.1"},
    {:nx, "~> 0.5"},
    {:exla, "~> 0.5"},
    {:torchx, "~> 0.5"},
    {:evision, "~> 0.1.33"},
    {:kino, "~> 0.10"}
  ],
  system_env: [
    {"XLA_TARGET", "cuda118"},
    {"EXLA_TARGET", "cuda"},
    {"LIBTORCH_TARGET", "cu116"},
    {"EVISION_ENABLE_CUDA", "true"},
    {"EVISION_ENABLE_CONTRIB", "true"},
    {"EVISION_CUDA_VERSION", "118"}
  ]
)

system_env で指定しているのは EXLA、 Torchx、 Evision が GPU を使うための環境変数設定です

しばらく時間がかかりますが、 Nx、 EXLA、 Torchx、 Evsion 等が GPU 用にインストールされます

スクリーンショット 2022-10-26 18.55.33.png

次のコードを実行してみましょう

tensor = Nx.tensor([1, 2, 3], type: {:f, 64}, backend: Nx.BinaryBackend)
Nx.add(tensor, tensor)

スクリーンショット 2022-10-26 18.57.39.png

バイナリバックエンドは正常に動いていますね

続いて EXLA です

EXLA.Backend の場合、 device_id で何番目の GPU を使うか指定できます

tensor = Nx.tensor([1, 2, 3], type: {:f, 64}, backend: {EXLA.Backend, device_id: 0})
Nx.add(tensor, tensor)

スクリーンショット 2022-10-26 18.59.15.png

CUDA で動いていることが分かります

Torchx でも同じようにしてみます

特に指定しなくても GPU を使いますが、 device: :cuda で明示できます

tensor = Nx.tensor([1.0, 2.0, 3.0], backend: {Torchx.Backend, device: :cuda})
Nx.add(tensor, tensor)

スクリーンショット 2022-10-26 19.02.54.png

初回実行だけ4分くらいかかりますが、無事 CUDA で動いています

Torchx の場合、デフォルトで GPU を使うようになっていても CPU 指定が可能です

tensor = Nx.tensor([1.0, 2.0, 3.0], backend: {Torchx.Backend, device: :cpu})
Nx.add(tensor, tensor)

スクリーンショット 2023-08-02 12.41.30.png

最後に Evision です

tensor = Nx.tensor([1.0, 2.0, 3.0], backend: Evision.Backend)
Nx.add(tensor, tensor)

スクリーンショット 2023-08-02 10.03.50.png

おわりに

これで GPU を使った Elixir の機械学習が捗りますね

27
14
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
27
14