技術研究所(技研)のまつけんです。
技研では現在、2台のゲーミングデスクトップPCにLinux (Ubuntu)とJupyterをインストールして、共有で計算(主に機械学習)サーバとして使っています。最近、計算量が増えてきたので、近いうちに3台目を購入し、セットアップする予定です。また、休眠状態だったゲーミングラップトップPCがあったので、一足先にセットアップして計算サーバ化しました。この記事では技研で確立した「機械学習用の計算サーバ構築手順」を紹介したいと思います。OSはUbuntu Server 20.04 LTSです。
※ここに記載されいてる情報は2020年9月現在のものです。また、今回のセットアップ対象は、DELLのゲーミングラップトップG5[1]です。
- Ubuntu Serverのインストーラ
https://jp.ubuntu.com/download
からISOイメージを入手できます。検索エンジンで「ubuntu server iso」などを検索すれば見つかるかと思います。ダウンロードしたISOイメージのファイル名は「ubuntu-20.04.1-live-server-amd64.iso」です。
- DVD-RドライブまたはUSBメモリ
ISOイメージファイルから起動メディアを作成します。勿論、DVD-Rに書き込むことも出来ますが、USBメモリに書き込むとスピーディにインストールできます(今回は起動からインストール完了まで3分くらいでした)。ISOファイルからUSBブートデバイスを作るソフトウェアを使います。検索エンジンで「isoファイル usbブート」などと検索すると幾つかヒットしますが、今回はインストールせずに使える「Refus 3.11 Portable」を使いました。USBメモリは7年前に購入した4 GBのもの[2]が余っていたので、それを使いました。
USBメモリを装着し、起動します。内蔵ストレージのOSが起動してしまう場合は、再起動し、F2キーでBIOSメニューを開いてUSBから起動するように切り替えてください。
インストールは基本的にデフォルト設定で大丈夫ですが、「Install OpenSSH server」にはチェック(X)を入れます。インストール先は内蔵ストレージの「entire disk」を選べば良いのですが、「インストールできるディスクが無い」旨の表示となっていまい、今回、進まなくなってしまいました。原因はRAID設定がONなっていることでした。Ubuntu Serverでは詳しい原因がわからなかったので、Ubuntu Desktopのインストーラに切り替えて試した所、「This computer uses Intel RST (Rapid Storage Technology). You need to turn off RST before isntalling Ubuntu.」と表示されたので、BOISメニューのSystem Configuration→SATA OperationでAHCIを選択することで解決しました。
ホスト名はgiken-ml-11、初期ユーザはgiken、ネットワーク設定はDHCPです(最終的には固定IPアドレスにする)。
aptのプロキシの設定は/etc/apt/apt.confに以下の2行:
Acquire::http::Proxy "http://プロキシサーバのアドレス:ポート番号"; |
Acquire::https::Proxy "http://プロキシサーバのアドレス:ポート番号"; |
を追加することで設定します。ファイルの末尾に追加する場合は「cat >> /etc/apt/apt.conf」が便利です。必要な内容を入力またはペーストして、ctrl-dで抜けます。またwgetについて、/etc/wgetrcに以下の3行を追加します:
https_proxy = http://プロキシサーバのアドレス:ポート番号/ |
http_proxy = http://プロキシサーバのアドレス:ポート番号/ |
ftp_proxy = http://プロキシサーバのアドレス:ポート番号/ |
インストールが終わったら、まず、アップデートを行って最新の状態にします:
giken@giken-ml-11:~$ sudo apt update |
giken@giken-ml-11:~$ sudo apt upgrade -y |
リモートログインすることで、コマンドのコピー&ペーストなどが出来ます。ネットで調べ物をして、そこに載っているコマンドをそのまま実行したり出来ます。また、最終的にサーバとして使うのでsshログインが出来ないと管理するのが困難です。普段Windowsを使っている場合は、Windows側にcygwinをインストールしておくと便利です。
リモートログインするには、サーバ(giken-ml-11)のIPアドレスが必要です。今回は、ひとまずDHCPでIPアドレスを自動取得する設定でインストールしたので、ifconfigなどで調べる必要があります。ifconfigを使うには、net-toolsが必要なのでaptでインストールします:
giken@giken-ml-11:~$ sudo apt install -y net-tools |
サーバのIPアドレスが192.168.0.10ならば、cygwin側からは、
cygwin:~$ ssh -l giken 192.168.0.10 |
のように-lでユーザ名を指定してログインします。パスワードはインストール中に設定したものを入力します。
タイムゾーンをアジア/東京に設定し、日付と時刻が合っていることを確認します:
giken@giken-ml-11:~$ sudo timedatectl set-timezone Asia/Tokyo |
giken@giken-ml-11:~$ date |
Tue 8 Sep 10:41:36 JST 2020 |
giken@giken-ml-11:~$ |
ゲーミングラップトップをサーバとして使う場合、シェル(蓋)を閉じた状態でもサスペンドしないように設定すると便利です。この設定は/etc/systemd/logind.confで行います。このファイルに「HandleLidSwitch=ignore」を追記して、
giken@giken-ml-11:~$ sudo systemctl restart systemd-logind |
を実行すると蓋を閉じてもサスペンドしなくなります[3]。デスクトップPCの場合は、この作業は不要です。
Ubuntu Serverをインストールした直後は起動時にX Window System (以下、X)は起動せず、CUIのログイン画面となります。が、内部的には「グラフィカル」モードに設定されていて、後ほど、nvidiaのデバイスドライバをインストールすると、Xが起動するようになります。サーバとして使うのでXは不要ですから、モードを変更します[4]:
giken@giken-ml-11:~$ systemctl get-default |
graphical.target |
giken@giken-ml-11:~$ sudo systemctl set-default multi-user.target |
Created symlink /etc/systemd/system/default.target → /lib/systemd/system/multi-user.target. |
giken@giken-ml-11:~$ systemctl get-default |
multi-user.target |
giken@giken-ml-11:~$ |
かつて、この設定はrunlevelと呼ばれていて数値で管理されていて、sudo initで変更するようになていたのですが、現在はsudo initでは変更できないようです。
グラフィックボードのデバイスドライバとユーティリティをインストールします。インストール後は再起動が必要です。
giken@giken-ml-11:~$ sudo apt install -y nvidia-driver-440 nvidia-utils-440 nvidia-cuda-toolkit |
giken@giken-ml-11:~$ sudo shutdown -r now |
Ubuntuのバージョンによっては事前に「sudo -E add-apt-repository ppa:graphics-drivers/ppa」を実行する必要があります。また、セキュアブートが有効になっている場合は、パスワード設定画面が表示されます。再起動時に「Enrol MOK」を選択して、パスワードを入力します。
再起動したら、nvidia-smiコマンドでグラフィックボードの状態が確認できることを確かめます:
giken@giken-ml-11:~$ nvidia-smi |
Tue Sep 8 11:05:28 2020 |
+-----------------------------------------------------------------------------+ |
| NVIDIA-SMI 440.100 Driver Version: 440.100 CUDA Version: 10.2 | |
|-------------------------------+----------------------+----------------------+ |
| GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC | |
| Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. | |
|===============================+======================+======================| |
| 0 GeForce RTX 2060 Off | 00000000:01:00.0 Off | N/A | |
| N/A 59C P0 16W / N/A | 0MiB / 5934MiB | 0% Default | |
+-------------------------------+----------------------+----------------------+ |
+-----------------------------------------------------------------------------+ |
| Processes: GPU Memory | |
| GPU PID Type Process name Usage | |
|=============================================================================| |
| No running processes found | |
+-----------------------------------------------------------------------------+ |
なお、このとき表示される「CUDA Version: 10.2」というのは「バージョン10.2のCUDAまで利用可能」という意味であって、実際に動いているCUDAのバージョンではないようです。実際のCUDAのバージョンは、nvccで調べることが出来ます(最後の「10.1.243」の部分がバージョン番号):
matsken@giken-ml-11:~$ nvcc --version |
nvcc: NVIDIA (R) Cuda compiler driver |
Copyright (c) 2005-2019 NVIDIA Corporation |
Built on Sun_Jul_28_19:07:16_PDT_2019 |
Cuda compilation tools, release 10.1, V10.1.243 |
Jupyterをインストールします:
giken@giken-ml-11:~$ sudo apt install -y jupyter jupyter-core jupyter-notebook |
その他に、動画を扱うことがあるのでffmpegとmediainfo、バージョン管理にsubversionとgit、メインのサーバから/homeをNFSマウントするのに、nfs-commonをインストールします:
giken@giken-ml-11:~$ sudo apt install -y ffmpeg mediainfo |
giken@giken-ml-11:~$ sudo apt install -y subversion git |
giken@giken-ml-11:~$ sudo apt install -y nfs-common |
サーバとして運用するので、IPアドレスを固定します。これについては計算サーバ構築の本質とは関係ないので、詳しい説明は割愛しますが、/etc/netplan/99_config.yamlを作成しnetplan applyを実行します[5]。ただし、デバイス名が「eth0」とは限らないので、事前にifconfigで確認します:
giken@giken-ml-11:~$ ifconfig |
enp60s0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 |
(以下略) |
今回は「enp60s0」でした。
全体の設定(管理者権限での設定)は、ここまでです。ここから先は、個々人のhome directory内の設定となります。
Jupyterの設定は、以下の通りです:
giken@giken-ml-11:~$ jupyter notebook --generate-config |
Writing default config to: /home/giken/.jupyter/jupyter_notebook_config.py |
giken@giken-ml-11:~$ sed -e s%^'#c.NotebookApp.ip = '\'localhost\'$%'c.NotebookApp.ip = '\'\*\'% -i .jupyter/jupyter_notebook_config.py |
jupyter notebook –generate-configを実行すると、設定ファイル.jupyter/jupyter_notebook_config.pyが作られます。その中の
#c.NotebookApp.ip = 'localhost' |
という行を
c.NotebookApp.ip = '*' |
に書き換えるのですが、エディタで書き換えるより、sedで書き換えるスクリプトを作った方が、複数のユーザの設定を行うときに楽なので、sedを使っています。
設定が出来たら、Jupyterを起動します:
giken@giken-ml-11:~$ jupyter notebook |
[W 17:48:19.817 NotebookApp] WARNING: The notebook server is listening on all IP addresses and not using encryption. This is not recommended. |
[I 17:48:19.819 NotebookApp] Serving notebooks from local directory: /home/giken |
[I 17:48:19.819 NotebookApp] The Jupyter Notebook is running at: |
[I 17:48:19.819 NotebookApp] http://giken-ml-11:8888/?token=3445e22f92ae7fbec5ccb63fee938876125178a9258dc474 |
[I 17:48:19.819 NotebookApp] or http://127.0.0.1:8888/?token=3445e22f92ae7fbec5ccb63fee938876125178a9258dc474 |
[I 17:48:19.819 NotebookApp] Use Control-C to stop this server and shut down all kernels (twice to skip confirmation). |
[W 17:48:19.821 NotebookApp] No web browser found: could not locate runnable browser. |
[C 17:48:19.821 NotebookApp] |
To access the notebook, open this file in a browser: |
file:///home/giken/.local/share/jupyter/runtime/nbserver-5061-open.html |
Or copy and paste one of these URLs: |
http://giken-ml-11:8888/?token=3445e22f92ae7fbec5ccb63fee938876125178a9258dc474 |
or http://127.0.0.1:8888/?token=3445e22f92ae7fbec5ccb63fee938876125178a9258dc474 |
サーバ側が固定IPアドレスに設定してあり、クライアント側のhostsファイルなどを設定してあれば(またはDNSなどで名前が解決できれば)、ここに表示されている「http://giken-ml-11:8888/?token=xxx」をクライアント側のブラウザで開き、Jupyterが使える筈です(DHCPのままでも「http://192.168.0.10:8888/?token=xxx」のようにIPアドレスを指定すれば使えます)。

確認が終わったら、サーバ側でctrl-cでJupyterを終了させます。
Anacondaのインストーラをダウンロードして実行権限を与えます:
giken@giken-ml-11:~$ wget https://repo.anaconda.com/archive/Anaconda3-2020.07-Linux-x86_64.sh |
giken@giken-ml-11:~$ chmod 755 Anaconda3-2020.07-Linux-x86_64.sh |
実行します:

インタラクティブなインストーラなので途中の>>>が表示されている部分(4か所)でキーボードからの入力が必要です。デフォルトのインストールを行うには順に、
- Enterキー (緑矢印で示した部分)
- yesと入力してEnterキー (赤矢印で示した部分)
- Enterキー (緑矢印で示した部分)
- yesと入力してEnterキー (赤矢印で示した部分)
です。インストールが終わったら、一度ログアウトするなどして、bashを再起動します(.bashrcが変更されているため)。
bashを再起動すると、プロンプトの前に「(base)」が表示されるようになります。この設定を解除するには、インストールの最後に表示されている通り、「conda config –set auto_activate_base false」を実行します。「conda -V」でバージョンを確認できます:
(base) giken@giken-ml-11:~$ conda -V |
conda 4.8.3 |
また、この時点でインストールされているパッケージを控えておくと便利です[6]:
giken@giken-ml-11:~$ conda env export --name base > anaconda3/env-base.`date +%Y-%m-%d_%H-%M-%S`.yml |
giken@giken-ml-11:~$ ls anaconda3 |
bin compiler_compat condabin conda-meta doc env-base.2020-09-08_12-03-45.yml envs etc include lib libexec LICENSE.txt man mkspecs phrasebooks pkgs plugins qml resources sbin share shell ssl translations var x86_64-conda_cos6-linux-gnu |
最新版にアップデートする場合は「conda update -n base -c defaults conda」を実行します(プロキシの設定が必要な環境の場合は、先にプロキシの設定を行います)。
プロキシ設定が必要な場合は、~/.condarcの末尾に以下の3行を追加します:
proxy_servers: |
http: http://プロキシサーバのアドレス:ポート番号/ |
https: http://プロキシサーバのアドレス:ポート番号/ |
以下のように「conda create -n tf-gpu」を実行します:
(base) giken@giken-ml-11:/home/giken$ conda create -n tf-gpu |
Collecting package metadata (current_repodata.json): done |
Solving environment: done |
## Package Plan ## |
environment location: /home/giken/anaconda3/envs/tf-gpu |
Proceed ([y]/n)? |
Preparing transaction: done |
Verifying transaction: done |
Executing transaction: done |
# |
# To activate this environment, use |
# |
# $ conda activate tf-gpu |
# |
# To deactivate an active environment, use |
# |
# $ conda deactivate |
途中で「Proceed ([y]/n)? 」と聞かれるので、Enterキーを押します。インストーラのメッセージの最後に書いてある通り、この環境を有効にするには「conda activate tf-gpu」、無効にするには「conda deactivate」を実行します。続いて、「tf-gpu」の環境を有効にして、tensorflow-gpuをインストールします。「tf-gpu」を有効化するとプロンプトの「(base)」が「(tf-gpu)」に変化します。

「Proceed ([y]/n)? 」と聞かれたら、Enterキーを押します (緑矢印で示した部分、-yオプションを付ければ、この確認無しにインストールできます)。cudatoolkit、cudnn、numpy、python、scipy、tensorboard、tensorflow、tensorflow-gpuなどがインストールされていることがわかります。続いて、pythonを起動し、tensorflow.python.client.device_lib.list_local_devices()で、CPU/GPUの情報を確認します:
(tf-gpu) giken@giken-ml-11:/home/giken$ python |
Python 3.8.5 (default, Sep 4 2020, 07:30:14) |
[GCC 7.3.0] :: Anaconda, Inc. on linux |
Type "help", "copyright", "credits" or "license" for more information. |
>>> <span style="text-decoration: underline;" data-mce-style="text-decoration: underline;"><em><strong>from tensorflow.python.client import device_lib</strong></em></span> |
>>> <span style="text-decoration: underline;" data-mce-style="text-decoration: underline;"><em><strong>device_lib.list_local_devices()</strong></em></span> |
2020-09-08 11:18:38.190131: I tensorflow/core/platform/cpu_feature_guard.cc:143] Your CPU supports instructions that this TensorFlow binary was not compiled to use: SSE4.1 SSE4.2 AVX AVX2 FMA |
2020-09-08 11:18:38.217518: I tensorflow/core/platform/profile_utils/cpu_utils.cc:102] CPU Frequency: 2199995000 Hz |
2020-09-08 11:18:38.218002: I tensorflow/compiler/xla/service/service.cc:168] XLA service 0x5565148dbee0 initialized for platform Host (this does not guarantee that XLA will be used). Devices: |
2020-09-08 11:18:38.218025: I tensorflow/compiler/xla/service/service.cc:176] StreamExecutor device (0): Host, Default Version |
2020-09-08 11:18:38.218709: I tensorflow/stream_executor/platform/default/dso_loader.cc:44] Successfully opened dynamic library libcuda.so.1 |
2020-09-08 11:18:38.706454: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:981] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero |
2020-09-08 11:18:38.706818: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1561] Found device 0 with properties: |
pciBusID: 0000:01:00.0 name: GeForce RTX 2060 computeCapability: 7.5 |
coreClock: 1.2GHz coreCount: 30 deviceMemorySize: 5.79GiB deviceMemoryBandwidth: 312.97GiB/s |
(中略) |
2020-09-08 11:18:38.842202: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1247] Created TensorFlow device (/device:GPU:0 with 5491 MB memory) -> physical GPU (device: 0, name: GeForce RTX 2060, pci bus id: 0000:01:00.0, compute capability: 7.5) |
2020-09-08 11:18:38.843718: I tensorflow/compiler/xla/service/service.cc:168] XLA service 0x5565180f7e30 initialized for platform CUDA (this does not guarantee that XLA will be used). Devices: |
2020-09-08 11:18:38.843730: I tensorflow/compiler/xla/service/service.cc:176] StreamExecutor device (0): GeForce RTX 2060, Compute Capability 7.5 |
(中略) |
physical_device_desc: "device: 0, name: GeForce RTX 2060, pci bus id: 0000:01:00.0, compute capability: 7.5" |
, name: "/device:XLA_GPU:0" |
device_type: "XLA_GPU" |
memory_limit: 17179869184 |
locality { |
} |
incarnation: 5683818536693192719 |
physical_device_desc: "device: XLA_GPU device" |
] |
GPUとして「GeForce RTX 2060」とVRAM 5491 MBが正しく認識されています。確認できたら、ctrl-dでPythonを終了します。
以下のコマンドでインストールします。例によって「Proceed ([y]/n)?」と聞かれますので、Enterキーを押します。
(tf-gpu) giken@giken-ml-11:~$ conda install ipykernel |
(中略) |
Proceed ([y]/n)? |
(中略) |
(tf-gpu) giken@giken-ml-11:~$ python -m ipykernel install --user --name tf-gpu --display-name "TensorFlow-GPU" |
Installed kernelspec tf-gpu in /home/giken/.local/share/jupyter/kernels/tf-gpu |
また、後ほどmatplotlibを使うので、ついでにインストールしておきます:
(tf-gpu) giken@giken-ml-11:~$ conda install matplotlib |
再び、Jupyter Notebookを起動し、先程と同様にクライアント側のブラウザで「http://giken-ml-11:8888/?token=xxx」を開きます。右上の「New」から「TensorFLow-GPU」を選び、新しいnotebookを作成します:

有名な機械学習の例題MNISTを2段のDenseで学習させてみます:

無事に正解率97%の学習済みモデルが出来ました。学習がCPUではなくGPUで行われているかどうかは、nvidia-smiコマンドで確認します。最下部のジョブのリストに項目が増えている筈です(学習中であれば、消費電力も普段より大きい値になっている筈です):
+-----------------------------------------------------------------------------+ |
| Processes: | |
| GPU GI CI PID Type Process name GPU Memory | |
| ID ID Usage | |
|=============================================================================| |
| 0 N/A N/A 3678 C ...a3/envs/tf-gpu/bin/python 2860MiB | |
+-----------------------------------------------------------------------------+ |
念のため、PID 3678を調べて自分のタスクであることを確認します:
(tf-gpu) giken@giken-ml-11:~$ ps aux | grep 3678 |
giken 3678 2.0 12.3 37314584 2019036 ? Ssl 19:31 0:27 /home/giken/anaconda3/envs/tf-gpu/bin/python -m ipykernel_launcher -f /home/giken/.local/share/jupyter/runtime/kernel-1fc031ad-4367-4b51-8b7c-08175ba938f9.json |
giken 3796 0.0 0.0 13136 1148 pts/0 S+ 19:54 0:00 grep --color=auto 3678 |
如何でしたか? Ubuntu Linuxの新規インストールから、Anacondaを使ったMNISTをDenseで学習する実験までを通しで纏めてみました(今回のソースコードはGoogle Colaboratoryでシェアしています[7])。nvidiaのGPUを搭載したPCを機械学習用Jupyterサーバにするときなどに参考にしていただければと思います。詳しいことは、Anacondaのドキュメント[8]を参考にしてみてください。
[1] https://www.dell.com/ja-jp/shop/gaming-and-games/dell-g5-15-スペシャルエディション-ノートパソコン/spd/g-series-15-5590-se-laptop
[2] I-O DATA USB 2.0/1.1対応 フラッシュメモリー「NT」シリーズ 4GB ピンク TB-NT4G/P
[3] 【Ubuntu 20.04/18.04 LTS Server】ノートPCで蓋を閉じてもサスペンドを防止
[4] Ubuntu 16.04 LTS のランレベルを変更して CUI で動かす
[5] Ubuntu 20.04 LTSで固定IPアドレスの設定
[6] conda環境の保存と再構築の仕方
[7] Google Colaboratory: mnist-2-dense-test.ipynb
[8] ANACONDA DOCUMENTATION