分散アプリケーション向け Python ライブラリの Ray を使ってみたくなり、インストールしました。
$ pip install -U ray
普通はこれで終わりですが、遊休の Raspberry Pi で動かしたいと思ったものだから一苦労でした。See also
スワップ領域を増やす
Raspberry Pi 向けにビルドされた ray のパッケージはありませんので、自分でビルドする必要があります。私が使ったのは Raspberry Pi 3 Model B+ なので、メモリが1Gしかありません。ビルドでメモリが足りなくなるので、swap領域を増やします。2048 に設定しました。
$ uname -a
Linux ray1 5.10.17-v7+ #1403 SMP Mon Feb 22 11:29:51 GMT 2021 armv7l GNU/Linux
$ cat /proc/device-tree/model
Raspberry Pi 3 Model B Plus Rev 1.3
$ python3 --version
Python 3.7.3
$ swapon -s
Filename Type Size Used Priority
/var/swap file 2097148 1658320 -2
Bazel をインストールする
ray のビルドに bazel が必要なのでインストールします。これもソースからビルドが必要らしく、尚且つ、ひと手間(と時間)かかります。
sudo apt-get update
sudo apt-get upgrade
sudo apt-get install libatlas-base-dev libatomic-ops-dev
https://github.com/koenvervloesem/bazel-on-arm を使うと、ビルドに必要なパッチをやってくれるので便利でした。
git clone https://github.com/koenvervloesem/bazel-on-arm.git
cd bazel-on-arm
sudo make requirements
export BAZEL_JAVAC_OPTS="-J-Xmx512m"
make bazel
sudo make install
無事にインストールできました。
bazel version
Extracting Bazel installation...
Build label: 4.0.0- (@non-git)
Build target: bazel-out/arm-opt/bin/src/main/java/com/google/devtools/build/lib/bazel/BazelServer_deploy.jar
Build time: 火 4月 6 03:57:30 2021 (1617681450)
Build timestamp: 1617681450
Build timestamp as int: 1617681450
Ray のビルド
ようやく Ray のビルドができます。
git clone -b releases/1.2.0 https://github.com/ray-project/ray.git --single-branch
このページを参考にいろいろやりました。以下の変更を加えてビルドが通りました。
$ git diff
diff --git a/bazel/ray_deps_setup.bzl b/bazel/ray_deps_setup.bzl
index c398dd15d..f613b0fb6 100644
--- a/bazel/ray_deps_setup.bzl
+++ b/bazel/ray_deps_setup.bzl
@@ -243,6 +243,12 @@ def ray_deps_setup():
sha256 = "781fa39693ec2984c71213cd633e9f6589eaaed75e3a9ac413237edec96fd3b9",
)
+ http_archive(
+ name = "com_google_protobuf",
+ strip_prefix = "protobuf-3.15.6",
+ urls = ["https://github.com/protocolbuffers/protobuf/archive/v3.15.6.tar.gz"],
+ )
+
auto_http_archive(
name = "rules_proto_grpc",
url = "https://github.com/rules-proto-grpc/rules_proto_grpc/archive/a74fef39c5fe636580083545f76d1eab74f6450d.tar.gz",
diff --git a/python/setup.py b/python/setup.py
index a1542a7a2..b06456814 100644
--- a/python/setup.py
+++ b/python/setup.py
@@ -292,7 +292,8 @@ def build(build_python, build_java):
bazel_targets += ["//java:ray_java_pkg"] if build_java else []
return bazel_invoke(
subprocess.check_call,
- ["build", "--verbose_failures", "--"] + bazel_targets,
+# ["build", "--verbose_failures", "--"] + bazel_targets,
+ ["build", "--action_env=LD_LIBRARY_PATH", "--linkopt=-latomic", "--"] + bazel_targets,
env=bazel_env)
diff --git a/src/ray/common/ray_config_def.h b/src/ray/common/ray_config_def.h
index d06a1c358..6e574fcc8 100644
--- a/src/ray/common/ray_config_def.h
+++ b/src/ray/common/ray_config_def.h
@@ -197,7 +197,7 @@ RAY_CONFIG(uint64_t, object_manager_default_chunk_size, 5 * 1024 * 1024)
/// The maximum number of outbound bytes to allow to be outstanding. This avoids
/// excessive memory usage during object broadcast to many receivers.
-RAY_CONFIG(uint64_t, object_manager_max_bytes_in_flight, 2L * 1024 * 1024 * 1024)
+RAY_CONFIG(uint64_t, object_manager_max_bytes_in_flight, 2ULL * 1024 * 1024 * 1024)
/// Maximum number of ids in one batch to send to GCS to delete keys.
RAY_CONFIG(uint32_t, maximum_gcs_deletion_batch_size, 1000)
dashboard をビルドします。
cd python/ray/new_dashboard/client
export NODE_OPTIONS="--max-old-space-size=1024"
npm install
npm ci
npm run build
ray をビルドします。とてつもなく時間がかかります。夜寝る前にスタートして、朝起きたら出来てるくらい。気長に待とう。
export LD_LIBRARY_PATH=/usr/lib/arm-linux-gnueabihf:$LD_LIBRARY_PATH
bazel build --action_env=LD_LIBRARY_PATH --linkopt=-latomic -c opt //:ray_pkg
wheelの作成。
cd python
python3 setup.py bdist_wheel
dist にある whl ファイルを使ってインストール。
pip3 install ray-1.2.0-cp37-cp37m-linux_armv7l.whl
Tensorflow をインストール
tensorflow も使いたいのでビルドします。こちらはパソコンでクロスコンパイルしました。
ray もこんな風にクロスコンパイルできたらいいのにな。
Ray cluster on Raspberry Pi
ray, tensorflow をインストールした Raspberry Pi の SD カードをコピーして、それぞれ ray0, ray1, ray2 と名付けて3台の Raspberry Pi を起動します。
まず ray0 で head node を起動します。
ray start --head --port=6379 --dashboard-host 0.0.0.0
ray1, ray2 は、ray0 へ接続します。
ray start --address='192.168.0.13:6379' --redis-password='5241590000000000'
クラスターの状態を確認します。
ray status
======== Cluster status: 2021-04-11 13:55:59.022854 ========
Node status
------------------------------------------------------------
1 node(s) with resources: {'CPU': 4.0, 'node:192.168.0.13': 1.0, 'object_store_memory': 3.0, 'memory': 10.0}
1 node(s) with resources: {'object_store_memory': 3.0, 'node:192.168.0.8': 1.0, 'memory': 12.0, 'CPU': 4.0}
1 node(s) with resources: {'object_store_memory': 3.0, 'node:192.168.0.10': 1.0, 'memory': 12.0, 'CPU': 4.0}
Resources
------------------------------------------------------------
Usage:
0.0/12.0 CPU
0.00/1.660 GiB memory
0.00/0.439 GiB object_store_memory
Demands:
(no resource demands)
ダッシュボードを確認しましょう。私の環境では http://192.168.0.13:8265/
RLlib で分散強化学習
RLlib を使って、クラスター上で強化学習を動かしてみましょう。
import ray
from ray import tune
from ray.rllib.agents.dqn import DQNTrainer
ray.init(address='auto')
tune.run(DQNTrainer, config={"env": "CartPole-v0", "num_workers": 11})
tensorboard で確認。
tensorboard --logdir=DQN_2021-04-11_14-06-02 --bind_all
ラズパイの Ray クラスターが、実用的な性能とは思えませんが、Ray の学習用として使おうと思います。