Elixir Digitalization Implementors/fukuoka.ex/kokura.exのpiacereです
ご覧いただいて、ありがとうございます
引き続き、Elixirの2021年を占うポジションであるニューラルネットワーク/ディープラーニング用ライブラリ「Nx」についてです
前回は、Nxの導入を行ったので、今回は、Nxで新しく入った構文「defn」で行列処理専用関数を作ったり、Nxで提供されるTensorFlow用コンパイラ「XLA(Accelerated Linear Algebra)」バインディングを通じたGPU駆動を試していきます
なおNxは、昨日(2021年2月18日)出たばかりのライブラリで、hexdocも未だ無いような状態ですが、ソースコード中のdoctestを参考にしながら実験していきます
Nxソースコード
https://github.com/elixir-nx/nx/tree/main/nx/lib
内容が、面白かったり、役に立ったら、「LGTM」よろしくお願いします
Advent Calendar、fukuoka.ex1位、Elixir2位達成ヽ(=´▽`=)ノ
fukuoka.ex Advent Calendar、Webテクノロジーカテゴリで堂々1位 … 各コラムぜひお読みください
https://qiita.com/advent-calendar/2020/fukuokaex
そして、プログラミング言語カテゴリは、1位がRust、2位がElixir、3位がGoとモダン言語揃い踏みでのトップ3、熱いネー
https://qiita.com/advent-calendar/2020/elixir
本コラムの検証環境
本コラムは、以下環境で検証しています(Windowsで実施していますが、Linuxやmacでも動作する想定です)
- Windows 10
- WSL2(配下はWSL2上で導入) ※最新版のインストール手順はコチラ
- Ubuntu 18.04 LTS
- Erlang/OTP 23.2.3-1(erts-11.1.7)
- Elixir 1.11.2
- git 2.30.1.windows.1 ※最新版のインストール手順はコチラ
あと下記コラムシリーズの続きとして実施するので、未実施であれば、事前に実施しておいてください
|> Elixirでディープラーニング①:革新的ライブラリ「Nx」の導入
Nxの「defn」で行列処理専用関数を作成
前回はiexで直接Nxを使いましたが、今度は行列処理関数のための新しい構文(マクロ)である「defn」を使って、softmax関数を作ってみます
defmodule NxReview do
import Nx.Defn
defn softmax( matrix ) do
Nx.exp( matrix ) / Nx.sum( Nx.exp( matrix ) )
end
end
このdefn関数を呼び出すときは、こんな感じです
iex> NxReview.softmax( Nx.tensor( [ [ 0.123, 0.456 ], [ 0.789, 1.234 ] ] ) )
#Nx.Tensor<
f64[2][2]
[
[0.135520130365152, 0.18907054376721744],
[0.26378125835705013, 0.4116280675105804]
]
>
パイプを使うことも、当然できます
なんていうか、こんな形で行列処理できるって、もう、この先、イイ予感しかしませんよね
iex> Nx.tensor( [ [ 0.123, 0.456 ], [ 0.789, 1.234 ] ] ) |> NxReview.softmax
#Nx.Tensor<
f64[2][2]
[
[0.135520130365152, 0.18907054376721744],
[0.26378125835705013, 0.4116280675105804]
]
>
ちなみに、Nx.tensor
で作られた行列では無く、中身のリストとかを渡すと、こんな感じで怒られます … defnが、数値か行列(テンソル)しか扱えないことが分かります
Nxで提供される「XLA」バインディングを動かす
Nxでは、「XLA(Accelerated Linear Algebra)」と呼ばれる、線形代数のためのコンパイラのバインディングが含まれているため、Python同様、XLAによるTensorFlowモデルとGPUの操作が可能です
なお、XLAが何者かについての詳細は、下記スライドが分かりやすいです
TensorFlow XLAの可能性
https://www.slideshare.net/ssuser479fa3/tensorflow-xla-78874656
さて、ここも前回同様、結構トラブってます … 恐らくは、Windows以外の環境でもコケると思われるのですが、未検証なので、検証していただける方、本コラムを参考にしながら、よろしくお願いします(私メンションを付けてくれたら嬉しい)
EXLAでGPUを動かすコード
EXLAを使ったコードは、下記の通り、@defn_compiler {EXLA, client: :host}
の1行が関数に追加されるだけです
たった、これだけでGPUが利用可能になります
defmodule NxReview do
import Nx.Defn
@defn_compiler {EXLA, client: :host}
defn softmax( matrix ) do
Nx.exp( matrix ) / Nx.sum( Nx.exp( matrix ) )
end
end
以降では、このコードをビルドして動かすための準備をします
EXLAのライブラリ追加
では、EXLAのREADME(下記)の通りに導入していきます
まず、EXLAをdepsに追加し、Nxの方も、override: true
を追記します
…
defp deps do
[
{:exla, "~> 0.1.0-dev", github: "elixir-nx/nx", sparse: "exla"},
{:nx, "~> 0.1.0-dev", github: "elixir-nx/nx", sparse: "nx", override: true}
]
…
gcc等のビルドツールのインストール
Ubuntuへのインストール手順と同じでOKなので、下記コラムの「ビルドツールをインストール」のところをご参考ください
WindowsからElixir IoT端末を作ってみた:「Raspberry Pi OS」を入れた後、Elixir IoTフレームワーク「Nerves」へ
https://qiita.com/piacerex/items/98e1bde676263f5f9f81
XLA用ビルドツール「bazel」のインストール
次に、bazelの公式サイトにあるUbuntuインストール手順でインストールします
ちなみにbazelは、Google製のビルドツールで、makeを置き換えるような存在です(って言う触れ込みのツール、この25年で幾つ見てきただろう? … って感じですがw)
$ sudo apt install gnupg
$ curl -fsSL https://bazel.build/bazel-release.pub.gpg | gpg --dearmor > bazel.gpg
$ sudo mv bazel.gpg /etc/apt/trusted.gpg.d/
$ echo "deb [arch=amd64] https://storage.googleapis.com/bazel-apt stable jdk1.8" | sudo tee /etc/apt/sources.list.d/bazel.list
$ sudo apt update
$ sudo apt install bazel -y
Python系のインストール
それから、Python/pip/NumPyをインストールします
$ sudo apt install python3.8 -y
$ sudo apt install python-pip
$ pip install numpy
$ which python
/usr/bin/python
$ export PYTHON_BIN_PATH=/usr/bin/python
EXLA付きElixir PJをビルドすると…
必要ツールはインストールしたので、ビルドしてみるとエラー … bazelのバージョンが違うと怒られました
$ iex -S mix
…
==> exla
rm -f /home/piacere/.cache/exla/tf-6af836f407f546cf2f9ab3b5fcb7a8285bda5c96/tensorflow/compiler/xla/exla
ln -s "/mnt/c/piacere/site/nx_review/deps/exla/exla/c_src/exla" /home/piacere/.cache/exla/tf-6af836f407f546cf2f9ab3b5fcb7a8285bda5c96/tensorflow/compiler/xla/exla
rm -f c_src/exla/erts
ln -s "/usr/lib/erlang/erts-11.1.7/include" c_src/exla/erts
cd /home/piacere/.cache/exla/tf-6af836f407f546cf2f9ab3b5fcb7a8285bda5c96 && \
bazel build --define "framework_shared_object=false" -c opt //tensorflow/compiler/xla/exla:libexla.so
ERROR: The project you're trying to build requires Bazel 3.1.0 (specified in /home/piacere/.cache/exla/tf-6af836f407f546cf2f9ab3b5fcb7a8285bda5c96/.bazelversion), but it wasn't found in /usr/bin.
You can install the required Bazel version via apt:
sudo apt update && sudo apt install bazel-3.1.0
If this doesn't work, check Bazel's installation instructions for help:
https://docs.bazel.build/versions/master/install-ubuntu.html
Makefile:25: recipe for target 'all' failed
make: *** [all] Error 1
could not compile dependency :exla, "mix compile" failed. You can recompile this dependency with "mix deps.compile exla", update it with "mix deps.update exla" or clean it with "mix deps.clean exla"
==> nx_review
** (Mix) Could not compile with "make" (exit status: 2).
You need to have gcc and make installed. If you are using
Ubuntu or any other Debian-based system, install the packages
"build-essential". Also install "erlang-dev" package if not
included in your Erlang/OTP version. If you're on Fedora, run
"dnf group install 'Development Tools'".
bazel 3.1.0を改めてインストールし直します(EXLAのREADMEには、bazel-3.7.xと書いてあるけど、エラーメッセージがきっと正しいでしょう)
$ sudo apt remove bazel -y
$ sudo apt install bazel-3.1.0 -y
bazelは、手順内に書いている通り、バージョン指定してインストールすると、コマンドがbazel-3.1.0
のような感じでインストールされるので、シンボリックリンクを作ります
sudo ln -s /usr/bin/bazel-3.1.0 /usr/bin/bazel
改めてビルドすると、またエラー … local_config_git
リポジトリのフェッチ中?
$ iex -S mix
…
==> exla
…
ERROR: An error occurred during the fetch of repository 'local_config_git':
Traceback (most recent call last):
File "/home/piacere/.cache/exla/tf-6af836f407f546cf2f9ab3b5fcb7a8285bda5c96/third_party/git/git_configure.bzl", line 64
_fail(result.stderr)
File "/home/piacere/.cache/exla/tf-6af836f407f546cf2f9ab3b5fcb7a8285bda5c96/third_party/git/git_configure.bzl", line 14, in _fail
fail(<1 more arguments>)
…
ERROR: /home/piacere/.cache/exla/tf-6af836f407f546cf2f9ab3b5fcb7a8285bda5c96/tensorflow/core/util/BUILD:368:1: //tensorflow/core/util:version_info_gen depends on @local_config_git//:gen/branch_ref in repository @local_config_git which failed to fetch. no such package '@local_config_git//': Traceback (most recent call last):
File "/home/piacere/.cache/exla/tf-6af836f407f546cf2f9ab3b5fcb7a8285bda5c96/third_party/git/git_configure.bzl", line 64
_fail(result.stderr)
File "/home/piacere/.cache/exla/tf-6af836f407f546cf2f9ab3b5fcb7a8285bda5c96/third_party/git/git_configure.bzl", line 14, in _fail
fail(<1 more arguments>)
Git Configuration Error: Traceback (most recent call last):
File "/home/piacere/.cache/bazel/_bazel_piacere/bd39af2ecb695c5256163d02cb0ae088/external/org_tensorflow/tensorflow/tools/git/gen_git_source.py", line 32, in <module>
from builtins import bytes # pylint: disable=redefined-builtin
ImportError: No module named builtins
…
エラーメッセージの中身をよく見ていくと、from builtins import bytes
、これはPython 2.x系で書かれたコードが、Python 3.x系で厳格に定義されたbytesで通らないときに使う「future」という、Python 2.x系とPython 3.x系のギャップを埋め合わせるPythonパッケージを使うときのimportで、このモジュールが無いと言われてます
futureは、自分で入れないと入らないハズなのでインストールします
(昔、Python 2.x系コードを、Python 3.x系に移行するタスクを結構やってたので、こんなところで役に立った)
$ pip install --upgrade setuptools
$ pip install future
改めてビルドすると、今度は成功しました(ちなみにビルド時間は結構かかります)
$ iex -S mix
…
==> exla
…
Target //tensorflow/compiler/xla/exla:libexla.so up-to-date:
bazel-bin/tensorflow/compiler/xla/exla/libexla.so
INFO: Elapsed time: 1462.841s, Critical Path: 140.02s
INFO: 5790 processes: 5790 local.
INFO: Build completed successfully, 6134 total actions
INFO: Build completed successfully, 6134 total actions
mkdir -p priv
cp -f /home/piacere/.cache/exla/tf-6af836f407f546cf2f9ab3b5fcb7a8285bda5c96/bazel-bin/tensorflow/compiler/xla/exla/libexla.so priv/libexla.so
Compiling 16 files (.ex)
Generated exla app
==> nx_review
Compiling 12 files (.ex)
Generated nx_review app
NVIDIAドライバー/CUDAのインストール
下記コラムの通り、WSL2でGPUを使うための導入を行います
待ってました CUDA on WSL 2
https://qiita.com/ksasaki/items/ee864abd74f95fea1efa
そしてココで、Windows 10 Insider Previewのインストール完了に、一晩待たなければならないということをスッカリ忘れてて、手詰まりました … 強制的に、また明日
最後に
ニューラルネットワーク/ディープラーニング用ライブラリ「Nx」で、defnによる行列処理専用関数を作ったり、XLAバインディングのインストールを行いました
今回は、EXLAのインストールで苦戦し、Windows 10 Insider Previewのインストール待ちで立ち止まり、残念ながら、GPU駆動とニューラルネットワーク開発まで辿り着けませんでした
なので次回こそは、NxでGPU駆動を完了させ、ニューラルネットワーク開発に入りたい Elixir創始者José ValimからWindows版Nxの修正版の連絡を直接もらったのでその対応です