jupyterHub セットアップ (venv 利用)
環境構築
必要なパッケージのインストール
# apt install cmake
プロジェクトの作成.
$ mkdir /home/adm01/jupyter $ cd /home/adm01/jupyter $ python -m venv venv
アクティベート
$ source venv/bin/activate (venv) $ (venv) $ python -V Python 3.7.3
pip でパッケージをインストール.
(venv) $ pip install -U setuptools pip (venv) $ pip install wheel (venv) $ pip install tensorflow (venv) $ pip install keras (venv) $ pip install matplotlib (venv) $ pip install scipy (venv) $ pip install scikit-image scikit-learn pandas (venv) $ pip install Optuna (venv) $ pip install cmake (venv) $ pip install dlib (venv) $ pip install numba (venv) $ pip install opencv-python (venv) $ pip install torch torchvision (venv) $ pip install jupyterhub notebook wheel ipywidgets jupyterlab (venv) $ pip install jupyterthemes
configurable-http-proxy をインストール
(venv) $ sudo apt install node-configurable-http-proxy
jupyter hub の起動
(venv) $ jupyterhub
別のターミナルで起動を確認する. 起動確認できたら jupyterhub を一旦閉じる.
$ w3m http://localhost:8000
設定ファイルを作る.
(venv) $ mkdir jupyterhub
(venv) $ cd jupyterhub
(venv) $ jupyterhub --generate-config
(venv) $ vi jupyterhub_config.py
# デフォルトでjupyter labを用いたいため以下を修正
c.Spawner.default_url = '/lab'
# アクセスしたら各ユーザーディレクトリを参照するように設定
c.Spawner.notebook_dir = '~'
# 環境変数を引き継ぐ.
# NFS しているディスク上では SQLite がうまく動かないらしく,Failed to open SQLite history となる.
c.Spawner.env_keep = ['PATH', 'PYTHONPATH', 'CONDA_ROOT', 'CONDA_DEFAULT_ENV', 'VIRTUAL_ENV', 'LANG', 'LC_ALL', 'JUPYTERHUB_SINGLEUSER_APP', 'IPYTHONDIR']
#IPYTHONDIRの設定
c.Spawner.environment = {'IPYTHONDIR': '~/.deep-learning-mct', 'PATH': '/home/adm01/jupyter/venv/bin:/usr/local/cuda/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin'}
Multiple userで使うには、rootユーザでの起動が必要なので,改めて起動する. (venv) $ sudo -s (venv) # jupyterhub -f jupyterhub_config.py
SSL 化
(venv) # mkdir /home/adm01/jupyter/ssl
(venv) # cd /home/adm01/jupyter/ssl
(venv) # openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout mykey.key -out mycert.pem
(venv) $ vi jupyterhub_config.py
c.JupyterHub.ssl_cert = '/home/adm01/jupyter/ssl/mycert.pem'
c.JupyterHub.ssl_key = '/home/adm01/jupyter/ssl/mykey.key'
設定追加
/etc/profile
if [ "`id -u`" -eq 0 ]; then PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" else PATH="/usr/local/cuda/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games" fi
/etc/skel/
# CUDA export PATH="/usr/local/cuda/bin:$PATH" export LD_LIBRARY_PATH="/usr/local/cuda/lib64:$LD_LIBRARY_PATH"
動作確認
Jupyter で notebook を開く.
GPU の使用状態の確認
!nvidia-smi
利用する GPU の ID を指定 (以下では, ID=2 を使う)
import os os.environ["CUDA_VISIBLE_DEVICES"]="2"
計算を実行する.以下のようなコードが動くことを確認した.
import tensorflow as tf
import tensorflow.keras.backend as K
mnist = tf.keras.datasets.mnist
(x_train, y_train), (x_test, y_test) = mnist.load_data()
x_train, x_test = x_train / 255.0, x_test / 255.0
model = tf.keras.models.Sequential([
tf.keras.layers.Flatten(input_shape=(28, 28)),
tf.keras.layers.Dense(128, activation='relu'),
tf.keras.layers.Dropout(0.2),
tf.keras.layers.Dense(10)
])
predictions = model(x_train[:1]).numpy()
predictions
tf.nn.softmax(predictions).numpy()
loss_fn = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True)
loss_fn(y_train[:1], predictions).numpy()
model.compile(optimizer='adam',
loss=loss_fn,
metrics=['accuracy'])
model.fit(x_train, y_train, epochs=100)
model.evaluate(x_test, y_test, verbose=2)
probability_model = tf.keras.Sequential([
model,
tf.keras.layers.Softmax()
])
probability_model(x_test[:5])
K.clear_session()
GPGPU メモリ管理
Jupyter Notebook は計算が終わっても GPU を握りつづけてしまう. そのため,適当なタイミングで sleep していて GPU を使っているジョブを KILL することにする.
以下のようなスクリプトを実行しておく.
#!/usr/bin/env ruby
# coding: utf-8
#ハッシュ (保管用) の初期化
check3 = Hash.new
check2 = Hash.new
check1 = Hash.new
loop do
#ハッシュの初期化
check0 = Hash.new
# GPU を使っているプロセスの pid の取得
pids = Array.new
output = `nvidia-smi --query-compute-apps=pid --format=csv,noheader`
output.each_line do |pid|
pids.push( pid.chomp )
end
pids.uniq! #重複を切る
#該当するプロセスの状態の調査・実行
# TIME->プロセスが実際にCPUを使った時間
# STATUS->プロセスの状態. R (Run) か S (Sleep) を判断.
pids.each do |pid|
status = `ps h -p #{pid} -o stat ` #STATUS 取得
time = `ps h -p #{pid} -o bsdtime `#TIME 取得. フォーマットは mm:ss
times = time.chomp.split(':')
unless /^R/ =~ status.chomp
check0[pid] = times[0].to_i * 60 + times[1].to_i
if check3[pid] && ( check0[pid] <= check3[pid] + 60 ) #値が存在 & マージン 60 秒
puts "STOP"
system("kill -KILL #{pid}")
end
end
end
p check0
sleep 100
#ハッシュを回す
check3 = check2
check2 = check1
check1 = check0
end
root の cront に登録
# crontab -e MAILTO="" @reboot ruby /home/adm01/jupyter/check.rb
作業ディレクトリ作成 (mkdir.rb)
NFS の領域に sqlite や json などがおけないようだ.それを置くディレクトリのみをローカルに置く.
# coding: utf-8
require "fileutils"
Dir.glob("/work/[a-z]*").sort.each do |path|
next if File.exist?( "#{path}/.deep-learning-mct" )
p path
user = File.basename( path )
uid = File.stat(path).uid
gid = File.stat(path).gid
dir = "/lwork/JUPYTER/#{user}"
FileUtils.mkdir( dir )
FileUtils.chown( uid, gid, dir )
FileUtils.mkdir( "#{dir}/.deep-learning-mct" )
FileUtils.chown( uid, gid, "#{dir}/.deep-learning-mct" )
FileUtils.ln_s( "#{dir}/.deep-learning-mct", "#{path}/.deep-learning-mct")
if File.exist?( "#{path}/.local" )
FileUtils.mv( "#{path}/.local", "#{dir}/.local" )
else
FileUtils.mkdir( "#{dir}/.local" )
FileUtils.chown( uid, gid, "#{dir}/.local" )
end
FileUtils.ln_s( "#{dir}/.local", "#{path}/.local")
end