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