強化学習に使うゲーミングPCはOSにUbuntu Serverをインストールし、普段遣いのノートパソコンでSSHで操作します。
目次
Ubuntu Serverの初期設定
- USBでUbuntu Serverをインストールする。
- DNSを8.8.8.8 8.8.4.4に変更する。
- ポート開放をする。(例:32199)
- ローカルIPアドレスを固定する。(例:192.168.0.99)
- NVMeの省電力設定を無効化する。
- 普段遣いのノートパソコンからSSH接続できることを確認する。
- GPUのドライバーをインストールする。
# 実行してrecommendedと推奨されているドライバーを確認する
ubuntu-drivers devices
# 推奨されているドライバーをインストールする
sudo apt install nvidia-driver-550
# 再起動する
sudo reboot
# ドライバーがインストールされたか確認する
nvidia-smi
Pythonで強化学習する場合
Jupyter Labの設定
Pythonのコードを書くときはJupyter Labが便利です。
- Ubuntuで必要なパッケージをインストールする。
sudo apt install -y git cmake clang build-essential python3 python3-dev python3-pip python3-venv python-is-python3 g++ libboost-all-dev libgmp-dev libsdl2-dev zlib1g-dev tmux
- 開発用のPython仮想環境を作成して、その環境に切り替える。
cd ~
python3 -m venv open_spiel_venv
source open_spiel_venv/bin/activate
- Jupyter Labをインストールする。
pip install jupyterlab
- 設定ファイルを作成する。
jupyter lab --generate-config
- 設定ファイルを開き、下記の箇所のコメントアウトを外して編集し、Ctrl+O、Enter、Ctrl+Xで閉じます。
sudo nano ~/.jupyter/jupyter_lab_config.py
c.ServerApp.ip = '0.0.0.0'
c.ServerApp.open_browser = False
c.ServerApp.port = 8888
- Jupyter Labにパスワードを設定します。
jupyter lab password
- サーバーでJupyter Labを起動します。tmuxでJupyter Lab用のセッションを開始するので、SSHを切ってもJupyter Labは起動し続けることができます。Ctrl+BしてからすぐDを押してtmuxセッションを抜けます。
tmux new -s jupyter
source open_spiel_venv/bin/activate
jupyter lab --no-browser --port=8888
# Jupyter Labのtmuxセッションに戻りたいとき
tmux attach -t jupyter
- 普段遣いのノートパソコンの別のターミナルで下記を実行し、サーバーのポート
8888
とノートパソコンのlocalhost
を繋げます。
ssh -L 8888:localhost:8888 -p 32199 username@192.168.0.99
- ノートパソコンのブラウザで下記を開き、Jupyter Labのパスワード入力画面が出てくれば設定OKです。
http://localhost:8888
OpenSpielのインストール
Python用の公式インストールガイド
- OpenSpielのリポジトリをクローンする。2025年1月時点ではv1.5でした。
cd ~
git clone https://github.com/deepmind/open_spiel.git
- Pythonの依存パッケージをインストールする。
cd ~
source open_spiel_venv/bin/activate
cd ~/open_spiel
pip install --upgrade pip
pip install --upgrade setuptools testresources
pip install -r requirements.txt
pip install pandas
pip install matplotlib
- 標準だとOpenSpielのビルド時にポーカーが除外されてしまうので、
nano ~/open_spiel/open_spiel/CMakeLists.txt
とnano ~/open_spiel/open_spiel/scripts/global_variables.sh
でポーカーの箇所をOFFからONにする。
openspiel_optional_dependency(OPEN_SPIEL_BUILD_WITH_ACPC ON
"Build against the Universal Poker library.")
export OPEN_SPIEL_BUILD_WITH_ACPC="ON"
- OpenSpielをビルドする。
cd ~/open_spiel
./install.sh
./open_spiel/scripts/build_and_run_tests.sh
nano ~/open_spiel_venv/bin/activate
で仮想環境の設定を開き、先頭にPATHを追加する。PATHを追加したら、Jupyter Labを含む全ての仮想環境を一度deactivate
し、またsource open_spiel_venv/bin/activate
で仮想環境を開く。
export PYTHONPATH=~/open_spiel:$PYTHONPATH
export PYTHONPATH=~/open_spiel/build/python:$PYTHONPATH
2回目以降のPython環境起動方法
- サーバーにSSHで接続する。Jupyter Labを起動したままであれば4に飛ぶ。
ssh -p 32100 username@192.168.0.91
- Jupyter Labのtmuxセッションを開き、Pythonの仮想環境を使ってなかったら使う。
tmux attach -t jupyter
# セッションがない場合は作る
tmux new -s jupyter
source open_spiel_venv/bin/activate
- Jupyter Labを起動し、Ctrl+BしてからすぐDを押してtmuxセッションを抜ける。
jupyter lab --no-browser --port=8888
- サーバーとのSSHを
exit
で切ってから、ポートを繋げる。
ssh -L 8888:localhost:8888 -p 32100 username@192.168.0.91
- ノートパソコンのブラウザでJupyter Labを開く。
http://localhost:8888
- Jupyter Labでノートブックに書いたコードを.pyファイルに出力する際は、サーバーで下記を実行します。
jupyter nbconvert --to script example.ipynb
学習を裏で回す方法
SSH画面でスクリプトを実行するとSSH通信が切れた時に実行が止まってしまうので、長時間学習を回す場合はtmuxのセッションを新しく作ってバックグラウンドで回します。
- サーバーにSSHで接続する。
ssh -p 32100 username@192.168.0.91
- .pyファイル用のtmuxセッションを作る。
tmux new -s py_run
# 既にあるのであれば
tmux attach -t py_run
- Pythonの仮想環境を使う。
source open_spiel_venv/bin/activate
- .pyファイルのあるディレクトリに移動して.pyファイルを実行する。
python3 your_script.py
- Ctrl+BしてからすぐDを押してtmuxセッションを抜ける。
C++で強化学習する場合
OpenSpielのインストール
C++ライブラリ用の公式インストールガイド
- OpenSpielのリポジトリをクローンする。
cd ~
git clone https://github.com/deepmind/open_spiel.git
- 標準だとOpenSpielのビルド時にポーカーが除外されてしまうので、
nano ~/open_spiel/open_spiel/CMakeLists.txt
とnano ~/open_spiel/open_spiel/scripts/global_variables.sh
でポーカーの箇所をOFFからONにする。
openspiel_optional_dependency(OPEN_SPIEL_BUILD_WITH_ACPC ON
"Build against the Universal Poker library.")
export OPEN_SPIEL_BUILD_WITH_ACPC="ON"
- 依存パッケージをインストールする。
cd ~/open_spiel
./install.sh
- OpenSpielをビルドする。
mkdir ~/open_spiel/build
cd ~/open_spiel/build
BUILD_SHARED_LIB=ON CXX=clang++ cmake -DCMAKE_CXX_STANDARD=17 -DPython3_EXECUTABLE=$(which python3) -DCMAKE_CXX_COMPILER=${CXX} ../open_spiel
make -j$(nproc) open_spiel
- ターミナルで、
export LD_LIBRARY_PATH="${HOME}/open_spiel/build"
でパスを設定する。
(SSHを切ったらパスはリセットされる) - サンプルのshared_library_example.ccをコンパイルする。
cd ~/open_spiel/open_spiel/examples
clang++ -I${HOME}/open_spiel -I${HOME}/open_spiel/open_spiel/abseil-cpp \
-std=c++17 -o shared_library_example shared_library_example.cc \
-L${HOME}/open_spiel/build -lopen_spiel
- コンパイルされたshared_library_exampleが実行できることを確認する。
実行できなければ、ビルドかコンパイルのどこかで問題がある。
cd ~/open_spiel/open_spiel/examples
./shared_library_example breakthrough
- universal_poker_test.ccを作成し、コンパイルする。
universal_poker_test.ccの中身
#include <iostream>
#include <memory>
#include <string>
#include "open_spiel/algorithms/external_sampling_mccfr.h"
#include "open_spiel/algorithms/tabular_exploitability.h"
#include "open_spiel/games/universal_poker/universal_poker.h"
#include "open_spiel/spiel.h"
#include "open_spiel/spiel_utils.h"
constexpr char kCustom3PlayerAcpcGamedef[] = R"""(
# (Empty lines and lines starting with an '#' are all ignored)
GAMEDEF
nolimit
numPlayers = 3
numRounds = 1
numSuits = 2
numRanks = 4
numHoleCards = 1
# Set per player, so 3 total
stack = 15 15 15
blind = 0 1 0
# Set per round
firstPlayer = 3
numBoardCards = 0
END GAMEDEF
)""";
int main(int argc, char** argv) {
std::string acpc_gamedef = kCustom3PlayerAcpcGamedef;
int num_iters = 2000;
int report_every = 500;
std::cout << "Input ACPC gamedef (raw): " << acpc_gamedef << std::endl;
std::shared_ptr<const open_spiel::Game> game =
open_spiel::universal_poker::LoadUniversalPokerGameFromACPCGamedef(acpc_gamedef);
const auto& game_down_cast =
open_spiel::down_cast<const open_spiel::universal_poker::UniversalPokerGame&>(*game);
std::cout << "Resulting ACPC gamedef used for universal_poker:\n"
<< game_down_cast.GetACPCGame()->ToString() << std::endl;
open_spiel::algorithms::ExternalSamplingMCCFRSolver solver(*game);
std::cerr << "Starting MCCFR on " << game->GetType().short_name << "..."
<< std::endl;
for (int i = 0; i < num_iters; ++i) {
solver.RunIteration();
if (i % report_every == 0 || i == num_iters - 1) {
double exploitability = open_spiel::algorithms::Exploitability(
*game, *solver.AveragePolicy());
std::cerr << "Iteration " << i << " exploitability=" << exploitability
<< std::endl;
}
}
return 0;
}
clang++ -I${HOME}/open_spiel -I${HOME}/open_spiel/open_spiel/abseil-cpp \
-std=c++17 -o universal_poker_test universal_poker_test.cc \
-L${HOME}/open_spiel/build -lopen_spiel
# Override Warningは無視してもいい。
# 気になるなら、sudo nano ~/open_spiel/open_spiel/games/universal_poker/universal_poker.hのstd::unique_ptr<State> ResampleFromInfostate(/* parameters */) const;の箇所をconst override;に変更する。
- コンパイルされたuniversal_poker_testが実行できることを確認する。
実行できなければ、ポーカーのゲーム定義あたりに問題がある。
./universal_poker_test
Visual Studio Codeの設定
- VSCodeを普段遣いのノートパソコンにインストールする。
- VSCodeを開き、拡張機能の「Remote – SSH」をインストールする。
- 左側のサイドバーに追加されている「リモートエクスプローラー」を開き、SSHに
username@192.168.0.99 -p 32199
のように追加して接続する。 - VSCodeでSSH接続している状態でターミナルを開き、必要なパッケージを
sudo apt install -y build-essential gdb cmake
でインストールする。 - Visual Studio Codeに拡張機能の「C/C++ Extension Pack」をインストールする。
- VSCodeのターミナルで開発用のディレクトリを
mkdir -p ~/poker-ai
で作る。
※Gitを使えば開発が少し楽になりますし、ディレクトリは手動で作る必要ないです。 - プロジェクトを
cd ~/poker-ai && code .
で開く。 - 上記のuniversal_poker_test.ccをこのディレクトリに配置する。
- 左側のサイドバーから「実行とデバッグ」を開き、「launch.jsonファイルを作成します」をクリックし、中身を下記に置き換えて保存する。
{
"version": "0.2.0",
"configurations": [
{
"name": "C++ Debug",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/build/${fileBasenameNoExtension}",
"args": [],
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
"environment": [
{
"name": "LD_LIBRARY_PATH",
"value": "${env:HOME}/open_spiel/build"
}
],
"externalConsole": false,
"MIMode": "gdb",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
],
"preLaunchTask": "C++ Build"
}
]
}
- Ctrl Shift Pを同時に押し、「Tasks: Configure Default Build Task」をクリックし、「テンプレートからtasks.jsonを生成」を選択し、「Others」を選択し、中身を下記に置き換えて保存する。
{
"version": "2.0.0",
"tasks": [
{
"label": "C++ Build",
"type": "shell",
"command": "/usr/bin/clang++",
"args": [
"-g",
"-I${env:HOME}/open_spiel",
"-I${env:HOME}/open_spiel/open_spiel/abseil-cpp",
"-std=c++17",
"${file}",
"-o",
"${workspaceFolder}/build/${fileBasenameNoExtension}",
"-L${env:HOME}/open_spiel/build",
"-lopen_spiel"
],
"group": {
"kind": "build",
"isDefault": true
},
"problemMatcher": ["$gcc"],
"detail": "Building using clang++"
}
]
}
- universal_poker_test.ccのコードの左側にブレークポイント(赤点)を作り、デバグができるか確認する。
follyのインストール
cd ~
git clone https://github.com/facebook/folly
cd folly
sudo ./build/fbcode_builder/getdeps.py install-system-deps --recursive
sudo apt install libssl-dev libgflags-dev libgoogle-glog-dev libfmt-dev -y
mkdir _build && cd _build
cmake .. -DCMAKE_INSTALL_PREFIX=$HOME/folly_install
make -j$(nproc)
sudo make install
Tailscaleの設定
- Ubuntu ServerにTailscaleをダウンロードする。
curl -fsSL https://tailscale.com/install.sh | sh
- 認証URLを取得し、ブラウザでログインする。(自分はGitHubアカウントでログイン)
sudo tailscale up
- ノートパソコンにもTailscaleをダウンロードしてインストールする。
https://tailscale.com/download - ノートパソコンのTailscaleにもログインする。
sudo nano /etc/ssh/sshd_config
のAllow UsersにTailscaleのIP帯を追加して、SSHをsudo systemctl restart ssh
で再起動する。AllowUsers *@192.168.0.0/16 *@100.64.0.0/10
- Tailscaleで新しく割り振られたUbuntu ServerのIPアドレスでSSH接続する。
RocksDBの設定
- Ubuntu Serverに
sudo apt install -y librocksdb-dev
でRocksDBをインストールする。 - ビルドする時に
-lrocksdb -lpthread
を追加する。