機械学習用のLinuxインスタンスの環境構築(GCEやEC2などクラウド)

最近では機械学習の計算のためにLinuxマシンを構築しては消し、を繰り返すことが多い。サーバの構築と消去が柔軟に可能なことからもEC2やGCEなどクラウドのインスタンスをよく使うということも影響している。
この記事では一般的なサーバ構築の記事では紹介されていない、クラウドのインスタンスで意外と盲点になる点を中心に、機械学習の計算用サーバとして安定した運用をするために最低限必要な設定をまとめた。

Linuxで最初にやっておくべき設定

Amazon EC2やGoogle Compute Engingなどのクラウドインスタンスのデフォルトの設定では不都合があるため、設定を追加する必要がある。

スワップメモリの設定

クラウドのインスタンスではデフォルトでスワップメモリが設定されていないため、念のため設定しておく必要がある。以下は/swap.imgとして4GBのスワップファイルを設置する例。

sudo sh -c 'dd if=/dev/zero of=/swap.img count=4096 bs=1MiB && chmod 600 /swap.img && mkswap /swap.img && swapon /swap.img'

スワップのされやすさをswappinessというパラメータで0~100の数値で指定する。値が大きいほどスワップされやすくなる。デフォルトで60となっているが、これを10に変更(スワップされにくくする)するには

sudo sysctl vm.swappiness=10

確認

cat /proc/sys/vm/swappiness

再起動時に自動で有効化するには

echo '/swap.img none swap sw 0 0' | sudo tee -a /etc/fstab
echo 'vm.swappiness=10' | sudo tee -a /etc/sysctl.conf

タイムゾーンの設定

デフォルトのタイムゾーンがUTCなのでJSTに設定しておく

RHEL6(CentOS6)以前、Amazon Linux 1もこちら

sudo ln -sf /usr/share/zoneinfo/Asia/Tokyo /etc/localtime

RHEL7(CentOS7)以降、Amazon Linux 2、Ubuntuでは

sudo timedatectl set-timezone Asia/Tokyo

SELinuxの無効化

SELinuxが有効になっていると不都合なことが多いので、有効な場合は無効化する。

SELinuxが有効かどうかの確認

getenforce

Enforcingだと有効になっている。

一時的に無効化する場合

sudo setenforce 0

永続的に無効化する場合は

sudo vi /etc/selinux/config
SELINUX=disabled

とする。

カーネルパニックは10秒後に再起動

# 一時的
sudo sysctl kernel.panic=10
# 永続的
sudo sh -c "echo 'kernel.panic = 10' >> /etc/sysctl.conf && sysctl -p"

OOM killerが出ないようにする

# 一時的
sudo sysctl vm.overcommit_memory=2
# 永続的
sudo sh -c "echo 'vm.overcommit_memory=2' >> /etc/sysctl.conf && sysctl -p"

これでもOOM killerは少しは発生するが、特定のプロセスに対して絶対発生させないようにするためには

sudo echo -17 > /proc/プロセスID/oom_adj

/etc/rc.localの有効化

CentOS7の場合
これらのコマンドをシステム起動時に自動実行するためには(公式には古い非推奨の方法だが)/etc/rc.localを使うのが簡単。
デフォルトではこのファイルには実行権限が付けられていないために無効化されているので、実行権限を付ければ有効になる。

sudo chmod 755 /etc/rc.local

Ubuntu16では以下の通り

https://qiita.com/onokatio/items/b2ecabf5da3c725fa542

Redhat系Linux、Debian系Linux、MacOSのパッケージ管理ツールの比較

  • Redhat系(RHEL, CentOS, SUSEなど)
  • Debian系(Debian, Ubuntuなど)
  • Mac(ただしHomebrew)
yum apt Homebrew
インストール yum install packagename apt-get install packagename brew install packagename
アンインストール yum remove packagename apt-get remove packagename brew uninstall packagename
名前で検索 yum search keyword apt-cache search keyword brew search keyword
含まれるファイル名で検索 yum provides filename apt-file search filename
全更新 yum upgrade apt-get dist-upgrade brew upgrade && brew cleanup
インストール済み一覧 yum list installed apt list –installed brew list

Homebrewの場合インストール直後には実行バイナリのパスが$PATHに含まれていないため実行できない。そこでリンクをする必要がある。

全てのパッケージをリンクする

brew list -1 | while read line; do brew unlink $line; brew link --force $line; done

Google Cloud Storageのマウント

Google Cloud Storage上にデータファイルや学習済みモデルなどの大きなファイルを格納するが、
gsutilコマンドではなく通常のローカルファイルと同様にコマンドラインで扱えるようにしたい。
そこでGCS上のバケットをローカルのディレクトリにマウントするツールであるgcsfuseを使う。

gcsfuseのインストール

https://github.com/GoogleCloudPlatform/gcsfuse/blob/master/docs/installing.md

のとおり。

gcsfuseコマンドの使い方

ローカルにマウントポイントとなるディレクトリを作成し、指定のバケットをマウントする。

gcsfuse バケット名 マウントポイント

このままではバケット直下のファイルにしかアクセスできない。バケット内のフォルダにアクセスできないのだが、mkdirコマンドで空のディレクトリを作ることで、その中のファイルにアクセスできるようになる。たとえばgs://バケット名/my_folderの中身にアクセスできるようするには

mkdir マウントポイント/my_folder

個別にmkdirせずに全てのサブディレクトリも同時に読み込めるようにするには、マウント時に

gcsfuse --implicit-dirs バケット名 マウントポイント

デフォルトでキャッシュが効くため、ファイルの更新が反映されにくい。キャッシュを無効にするには

gcsfuse バケット名 マウントポイント --stat-cache-ttl 0 and --type-cache-ttl 0

アンマウントするには

fusermount -u マウントポイント

EC2などのGCE以外の環境では環境変数$GOOGLE_APPLICATION_CREDENTIALSにcredentialを明示的に指定しておく必要がある。

export GOOGLE_APPLICATION_CREDENTIALS=/home/my_user/service-account.json

これを~/.bash_profileなどに記述しておいてあらかじめ実行されるようにしておくといい

[更新日:2022年6月24日]

GCP/Firebase の記事一覧