LoginSignup
11
5

More than 1 year has passed since last update.

Elixirでディープラーニング②:Nxのdefn+XLAでGPUを動か…せなかった(T_T)

Last updated at Posted at 2021-02-19

Elixir Digitalization Implementors/fukuoka.ex/kokura.exのpiacereです
ご覧いただいて、ありがとうございます :bow:

引き続き、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」よろしくお願いします :wink:

:ocean::ocean::ocean: Advent Calendar、fukuoka.ex1位、Elixir2位達成ヽ(=´▽`=)ノ :ocean::ocean::ocean:

fukuoka.ex Advent Calendar、Webテクノロジーカテゴリで堂々1位 … 各コラムぜひお読みください
https://qiita.com/advent-calendar/2020/fukuokaex
image.png

そして、プログラミング言語カテゴリは、1位がRust、2位がElixir、3位がGoとモダン言語揃い踏みでのトップ3、熱いネー:laughing:
https://qiita.com/advent-calendar/2020/elixir
image.png

本コラムの検証環境

本コラムは、以下環境で検証しています(Windowsで実施していますが、Linuxやmacでも動作する想定です)

あと下記コラムシリーズの続きとして実施するので、未実施であれば、事前に実施しておいてください

|> Elixirでディープラーニング①:革新的ライブラリ「Nx」の導入

Nxの「defn」で行列処理専用関数を作成

前回はiexで直接Nxを使いましたが、今度は行列処理関数のための新しい構文(マクロ)である「defn」を使って、softmax関数を作ってみます

lib/nx_review.ex
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]
  ]
>

パイプを使うことも、当然できます

なんていうか、こんな形で行列処理できるって、もう、この先、イイ予感しかしませんよね:wink:

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が、数値か行列(テンソル)しか扱えないことが分かります
image.png

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が利用可能になります

lib/nx_review.ex
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(下記)の通りに導入していきます
image.png

まず、EXLAをdepsに追加し、Nxの方も、override: trueを追記します

mix.exs

  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のインストール完了に、一晩待たなければならないということをスッカリ忘れてて、手詰まりました … 強制的に、また明日:sob:

最後に

ニューラルネットワーク/ディープラーニング用ライブラリ「Nx」で、defnによる行列処理専用関数を作ったり、XLAバインディングのインストールを行いました

今回は、EXLAのインストールで苦戦し、Windows 10 Insider Previewのインストール待ちで立ち止まり、残念ながら、GPU駆動とニューラルネットワーク開発まで辿り着けませんでした

なので次回こそは、NxでGPU駆動を完了させ、ニューラルネットワーク開発に入りたい Elixir創始者José ValimからWindows版Nxの修正版の連絡を直接もらったのでその対応です

p.s.このコラムが、面白かったり、役に立ったら…

image.pngimage.png にて、どうぞ応援よろしくお願いします:bow:

11
5
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
11
5