2025/11/09 Updated by

Docker Image を自作する (6c)

PyTorch23.07 + sshd + jupyter

つくりながら学ぶ!LLM自作入門」が動作する Docker (GPU) 環境


[Up] Japanese English
このページ内での表記:
「ホストOSの対話環境」は背景色を黄色(lightyellow)で表す。
「Conainer 内の root 権限の対話環境」は背景色を水色(azure)であらわす。
「Conainer 内の一般ユーザ権限の対話環境」は背景色を赤色(#ffeeee)であらわす。
「他のPCの対話環境」は紫色(#eeeeff)で表す。

目的


前提条件


Python, PyTorch, TensorFlow のバージョンについての検討事項

追加の検討 (BONUSコードも含めてすべてのコードの実行に必要なパッケージを調べる)

すべての requirements*.txt を探す
$ cd LLMs-from-scratch
$ find . -name requirements\*.txt -print
./ch02/02_bonus_bytepair-encoder/requirements-extra.txt
./ch04/02_performance-analysis/requirements-extra.txt
./ch05/06_user_interface/requirements-extra.txt
./ch05/07_gpt_to_llama/requirements-extra.txt
./ch05/11_qwen3/qwen3-chat-interface/requirements-extra.txt
./ch06/03_bonus_imdb-classification/requirements-extra.txt
./ch06/04_user_interface/requirements-extra.txt
./ch07/02_dataset-utilities/requirements-extra.txt
./ch07/03_model-evaluation/requirements-extra.txt
./ch07/05_dataset-generation/requirements-extra.txt
./ch07/06_user_interface/requirements-extra.txt
./requirements.txt
すべての requirements*.txt をまとめる
find LLMs-from-scratch -name requirements\*.txt -exec printf "# {}\n" \; -exec cat {} \; -exec printf "\n\n" \; > requirements_all.txt
必要なパッケージをすべて含んだ requirements_all.txt
# LLMs-from-scratch/requirements.txt
torch>=2.2.2,<2.6; sys_platform == 'darwin' and platform_machine == 'x86_64'  # Intel macOS
torch >= 2.2.2; sys_platform != 'darwin' or platform_machine != 'x86_64'   # all chapters
jupyterlab >= 4.0          # all
tiktoken >= 0.5.1          # ch02; ch04; ch05
matplotlib >= 3.7.1        # ch04; ch06; ch07
tensorflow>=2.16.2; sys_platform == 'darwin' and platform_machine == 'x86_64'  # Intel macOS
tensorflow >= 2.18.0; sys_platform != 'darwin' or platform_machine != 'x86_64'   # ch05; ch06; ch07
tqdm >= 4.66.1             # ch05; ch07
numpy >= 1.26             # dependency of several other libraries like torch and pandas
pandas >= 2.2.1            # ch06
psutil >= 5.9.5            # ch07; already installed automatically as dependency of torch


# LLMs-from-scratch/ch02/02_bonus_bytepair-encoder/requirements-extra.txt
requests
tqdm
transformers>=4.33.2


# LLMs-from-scratch/ch04/02_performance-analysis/requirements-extra.txt
thop

# LLMs-from-scratch/ch05/06_user_interface/requirements-extra.txt
chainlit>=1.2.0

# LLMs-from-scratch/ch05/07_gpt_to_llama/requirements-extra.txt
blobfile>=3.0.0
huggingface_hub>=0.24.7
ipywidgets>=8.1.2
safetensors>=0.4.4
sentencepiece>=0.1.99


# LLMs-from-scratch/ch05/11_qwen3/qwen3-chat-interface/requirements-extra.txt
chainlit>=1.2.0
huggingface_hub>=0.34.4
llms_from_scratch>=1.0.18  # to import code from this repo
safetensors>=0.6.2
tokenizers>=0.21.1

# LLMs-from-scratch/ch06/03_bonus_imdb-classification/requirements-extra.txt
transformers>=4.33.2
scikit-learn>=1.3.0

# LLMs-from-scratch/ch06/04_user_interface/requirements-extra.txt
chainlit>=1.2.0

# LLMs-from-scratch/ch07/02_dataset-utilities/requirements-extra.txt
openai>=1.30.3
scikit-learn>=1.3.1
tqdm>=4.65.0

# LLMs-from-scratch/ch07/03_model-evaluation/requirements-extra.txt
openai>=1.30.3
tqdm>=4.65.0


# LLMs-from-scratch/ch07/05_dataset-generation/requirements-extra.txt
openai>=1.30.3
tqdm>=4.65.0


# LLMs-from-scratch/ch07/06_user_interface/requirements-extra.txt
chainlit>=1.2.0

nVidia GPU (CUDA) に対応した Docker Image を探す: PyTorch


(参考) nVidia GPU (CUDA) に対応した Docker Image を探す: TensorFlow


「つくって学ぶ!LLM自作入門」が動作する Docker Image (GPU 版) を作成する

方針

作成手順

  1. Windows11 上の Ubuntu-20.04 (WSL) を使って作業を進める。
  2. Windows において WSL のファイルシステムは \\wsl$\Ubuntu-20.04\home\nitta にあることに注意すること。 Ubuntu-20.04 から、Windows11 のホームディレクトリは /mnt/c/User/nitta/ として見える。
  3. 作業用フォルダを作成する
  4.   $ cd /mnt/c/Users/nitta/Documents/docker 
      $ mkdir -p llm_diy_torch2307c  
    
  5. 作業用フォルダの中に Dockerfile を作成する。
  6. Dockerfile
    授業で配布するプリントを参照して下さい。
    
  7. 作業用フォルダの中に entrypoint.sh を作成する
  8. entrypoint.sh
    授業で配布するプリントを参照して下さい。
    
  9. 作業用フォルダの中に supervisord.conf を作成する
  10. supervisord.conf
    授業で配布するプリントを参照して下さい。
    
  11. 上記で作成したファイルを以下のように配置する。llm_diy_torch2307c.zip
  12.   llm_diy_torch2307c/
        |
        +-- Dockerfile
        |
        +-- entrypoint.sh
        |
        +-- supervisord.conf
        |
        +-- requirements_all.txt
    
  13. Image を build する。
  14.   $ docker build -t llm_diy_torch2307c .  
      ...
    成功
    
  15. 生成した Image を確認する
  16. $ docker image ls  
    REPOSITORY               TAG         IMAGE ID       CREATED          SIZE
    llm_diy_torch2307c       latest      b2b8acda9af2   52 seconds ago   29.4GB
    llm_diy_torch2307        latest      ae6c6c06ccf1   5 days ago       29GB
    ...
    

Container 用の永続的なファイルシステムを作成する

コンテナに永続的なファイルシステムを提供するために、1777 のパーミッションでフォルダを作っておく。 skicky bit が on (1777) のフォルダには、 「誰でもファイルを作成できるが、作成した本人だけがファイルを変更したり消したりできる」 という特徴がある。

$ sudo mkdir -p /home/docker            ← ディレクトリを作成する
$ sudo chmod 1777 /home/docker          ← 誰でもファイルを作成できるが、作成した本人にしか消去できないモードに設定する
$ ls -ld /home/docker                   ← ディレクトリのsticky bit が on になっていることを確認する。
drwxrwxrwt 3 root root 4096  4月 26 15:47 /home/docker

Docker Container を生成する

Image llm_diy_torch2307c のデフォルトのユーザ情報とSSHサーバ情報を用いて、 新しい Container llmdiy_01c を生成する。

  1. Image から Container を生成して起動する。ユーザ情報はデフォルト値 (guest) を利用する。 Container のファイルシステム内にホストOSのディレクトリをマウントする。 Container を起動するたびに、sshd サーバが起動される。
  2. $ docker run --name llmdiy_01c \
        --shm-size=1g --ulimit memlock=-1 --ulimit stack=67108864 --gpus all \
        --restart always \
        -p 7078:22 -p 8088:8888 \
        -v /home/docker/llmdiy_01c:/mnt/hostos \
        -it llm_diy_torch2307c  
    
    起動オプション
  3. Container を起動した対話環境が、そのまま Container 内で動作する bash との対話環境になる。root権限でloginした状態である。
  4. First run. Setting up ...       ← 生成された Container 内で entrypoint.sh が実行される
    Creating group guest with GID=3000
    Creating user guest with UID=3000, GID=3000
    ownership of '/home/guest' retained as guest:guest
    No command provided. Starting bash ...
    2025-11-09 00:08:09,901 CRIT Supervisor is running as root.  Privileges were not dropped because no user is specified in the config file.  If you intend to run as root, you can set user=root in the config file to avoid this message.
    2025-11-09 00:08:09,901 INFO Included extra file "/etc/supervisor/conf.d/supervisord.conf" during parsing
    2025-11-09 00:08:09,905 INFO RPC interface 'supervisor' initialized
    2025-11-09 00:08:09,905 CRIT Server 'unix_http_server' running without any HTTP authentication checking
    2025-11-09 00:08:09,905 INFO supervisord started with pid 44
    root@37c75c55ceea:/app# 2025-11-09 00:08:10,910 INFO spawned: 'sshd' with pid 332
    2025-11-09 00:08:11,943 INFO success: sshd entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)
    
    root@37c75c55ceea:/app#              ← Container 内の対話環境 (root権限の bash) が動く
    
  5. (重要) (Container 内で) 直ちに新規ユーザ guest のパスワードを変更する。
  6. # passwd guest   
    New password:                   ← 新しいパスワード を入力する。
    Retype new password:            ← もう一度新しいパスワード を入力する。
    passwd: password updated successfully
    
  7. (Container 内で) ホストOSのマウントポイントを調べる。
  8. # ls -ld /mnt/hostos    
    drwxr-xr-x 2 root root 4096 May 11 09:32 /mnt/hostos
    
  9. (Container 内で) 新規ユーザのホームディレクトリを調べる。
  10. # ls -ld /home/guest    
    drwxr-x--- 2 guest guest 4096 May 11 09:32 /home/guest
    # ls -la /home/guest    
    total 20
    drwxr-x--- 2 guest guest 4096 May 11 09:32 .
    drwxr-xr-x 1 root  root  4096 May 11 09:32 ..
    -rw-r--r-- 1 guest guest  220 Mar 31  2024 .bash_logout
    -rw-r--r-- 1 guest guest 3771 Mar 31  2024 .bashrc
    -rw-r--r-- 1 guest guest  807 Mar 31  2024 .profile
    
  11. (Container 内で) Control-P と Control-Q を順にタイプして、ホストOSの対話環境に戻る。 Container 内のシェルは動作したままとなる。
  12. # ^p ^q                ← Container の対話環境を抜ける
    $              ← ホストOS 内の対話環境に戻る
    
  13. (ホストOS上) Container からマウントされているホストOSのディレクトリを調べる。
  14. $ ls -ld /home/docker/llmdiy_01c  
    drwxr-xr-x 2 root root 4096 Nov  3 09:00 /home/docker/llmdiy_01c
    
  15. (ホストOS上) docker 上の実行中の container の状態を調べる
  16. $ docker container ls  
    CONTAINER ID   IMAGE               COMMAND            CREATED        STATUS        PORTS                   NAMES
    37c75c55ceea   llm_diy_torch2307c   "/entrypoint.sh"   10 hours ago   Up 10 hours   0.0.0.0:7078->22/tcp,   llmdiy_01c
                                                                                       [::]:7078->22/tcp, 
                                                                                       0.0.0.0:8088->8888/tcp,
                                                                                       [::]:8088->8888/tcp,
                                                                                       [::]:8088->8888/tcp
    ...
    
  17. (ホストOS上) docker 上のすべての(停止中を含む) container の状態を調べる
  18. $ docker container ls -a  
    CONTAINER ID   IMAGE               COMMAND            CREATED        STATUS        PORTS                   NAMES
    37c75c55ceea   llm_diy_torch2307c   "/entrypoint.sh"   10 hours ago   Up 10 hours   0.0.0.0:7078->22/tcp,   llmdiy_01c
                                                                                       [::]:7078->22/tcp, 
                                                                                       0.0.0.0:8088->8888/tcp,
                                                                                       [::]:8088->8888/tcp,
                                                                                       [::]:8088->8888/tcp
    ...
    
  19. (ホストOS上) docker 上の Image の一覧を表示する。
  20. $ docker image ls  
    REPOSITORY               TAG         IMAGE ID       CREATED          SIZE
    llm_diy_torch2307c       latest      b2b8acda9af2   18 minutes ago   29.4GB
    llm_diy_torch2307        latest      ae6c6c06ccf1   5 days ago       29GB
    torch2302_sshd           latest      642c2e1fae87   3 weeks ago      20.6GB
    nvcr.io/nvidia/pytorch   23.07-py3   bd784c42fdf0   2 years ago      19.8GB
    nvcr.io/nvidia/pytorch   23.02-py3   7c3375e220ea   2 years ago      20.5GB
    

Docker Host から ssh を用いてContainer 内の対話環境にアクセスする

  1. ホストOSから、Continer の guest ユーザのアカウントに ssh でアクセスする。
  2. $ ssh -p 7078 guest@localhost ← ホストOSの 7078 番ポートに sshアクセスする The authenticity of host '[localhost]:7078 ([127.0.0.1]:7078)' can't be established. ECDSA key fingerprint is SHA256:l7tsXhvQOaz9nn7Aa2JuAyjHN5QTVrxlywRxklHDixA. Are you sure you want to continue connecting (yes/no/[fingerprint])? yes Warning: Permanently added '[localhost]:7078' (ECDSA) to the list of known hosts guest@localhost's password: パスワードを入力する。エコーバックされない。
    Welcome to Ubuntu 24.04.2 LTS (GNU/Linux 6.11.0-25-generic x86_64). ... $ ← Container 内の guest 権限の対話環境が開始する
  3. (Container 内の guest 権限で) ユーザ名を表示する。
  4. $ whoami   
    guest
    
  5. (Container 内の guest 権限で) ホームディレクトリを表示する。
  6. $ pwd   
    /home/guest
    
  7. (Container 内の guest 権限で) ホームディレクトリにあるファイルの一覧を表示する。
  8. $ ls -la   
    total 24
    drwxr-x--- 3 guest guest 4096 Nov  3 01:08 .
    drwxr-xr-x 1 root  root  4096 Nov  3 01:04 ..
    -rw-r--r-- 1 guest guest  220 Jan  6  2022 .bash_logout
    -rw-r--r-- 1 guest guest 3771 Jan  6  2022 .bashrc
    drwx------ 2 guest guest 4096 Nov  3 01:07 .cache
    -rw-r--r-- 1 guest guest  807 Jan  6  2022 .profile
    -rw-r--r-- 1 guest guest    0 Nov  3 01:08 .sudo_as_admin_successful
    
  9. (Container 内の guest 権限で) ssh 経由の対話環境を終了する。
  10. guest@af401d3cdf85:~$ exit logout
    Connection to localhost closed. $

他のPCからネットワーク経由で Container 内の対話環境にアクセスする

  1. (ホストOS上) 外部のPCからネットワーク経由で Container にアクセスするためには、ホストOSの 7078 番ポートを開けておく必要がある。
  2. Docker の公式文書では、「docker のポートフォワーディングは ufw のフィルタリングよりも前に行わるために、ufw の影響を受けない」 と記述されている (2025年春時点) が、これは現時点では間違いのようだ。 Containerに外部からアクセスするためには、ホストOSのポートを開けておく必要がある。

    Windows 11 の場合:

    「設定」→「ネットワークとインターネット」→「ネットワークの詳細設定」→「Windows ファイアウォール」→ 詳細設定
    1. ssh 用のポートを開ける。
      ローカルコンピューターのセキュリティ
      → 受信の規則
      → 新しい規則
      → 規則の種類「ポート」 → 次へ
      → プロトコルおよびポート → TCP → 特定のローカルポート → 7070-7079 → 次へ
      → 操作「接続を許可する」→ 次へ
      → プロファイル: ドメイン、プライベート、パブリックのすべてをチェックする
      → 名前: docker ssh → 完了
    2. WWWサーバ (jupyter) 用のポートを開ける
    3. 上と同様で → ... →
      → プロトコルおよびポート → TCP → 特定のローカルポート → 8080-8089 → 次へ → ...
      → 名前: docker http → 完了

    Ubuntu 24.04LTS の場合:

    ufw を用いる
    1. (ホストOS上) ファイアウォール ufw を有効化する。(既に有効化してあれば必要なし)
    2.   $ sudo apt update                          ← aptのデータベースを更新する
        $ sudo apt install -y ufw                  ← ufw をインストールする。
        $ sudo systemctl enable ufw                  ← ufw を有効化する
        $ sudo systemctl restart ufw                  ← ufw を再起動する
        
    3. (ホストOS上) ホストOSの 7078 番ポートを開放する。
    4.   $ sudo ufw allow 7078                          ← 7078 番ポートを開放する
        ルールを追加しました
        ルールを追加しました (v6)
        
    5. (ホストOS上) ファイアウォールの状態を確認する。
    6.   $ sudo ufw status 7078                          ← 7078 番ポートを開放する
        ...
      状態: アクティブ
      
      To                         Action      From
      --                         ------      ----
      ...
      7078                      ALLOW       Anywhere
      ...
      7078 (v6)                 ALLOW       Anywhere (v6)
        ...
      
  3. (ネットワーク上の他のPC) 他のマシンから、ホストOS上の Container に ssh 接続する。
  4. 以下は、ホストOSの IPアドレスが 192.168.12.10 の場合の、ssh アクセスの様子である。

    (他のPCから) $ ssh -p 7078 guest@192.168.12.10 guest@192.168.12.10's password: ← パスワードを入力する。エコーバックされない。
    Welcome to Ubuntu 24.04.2 LTS (GNU/Linux 6.11.0-25-generic x86_64) ... guest $ whoami ← Container に guest 権限でアクセスできる guest guest $ exit logout
    Connection to 192.168.12.10 closed. $

Container が再起動すると sshd も自動起動されることを確認する

  1. (ホストOS上で) Container を停止する
  2. $ docker container stop llmdiy_01c   
    
  3. (ホストOS上で) Container が停止されたことを確認する
  4. $ docker container ls   
    CONTAINER ID   IMAGE           COMMAND            CREATED         STATUS         PORTS          NAMES
    
  5. (ホストOS上で) 停止中の Container を起動する
  6. $ docker start llmdiy_01c   
    
  7. (ホストOS上で) Container に ssh でアクセスして、sshd が自動的に起動していることを確認する。
  8. $ ssh -p 7078 guest@localhost ← ホストOSの 7078 番ポートに sshアクセスする guest@localhost's password: パスワードを入力する。エコーバックされない。
    Welcome to Ubuntu 24.04.2 LTS (GNU/Linux 6.11.0-25-generic x86_64) ... $ ← Container 内の guest 権限の対話環境が開始する

「つくって学ぶ!LLM自作」入門のソースコードを使って jupyter サーバを動作させる。

  1. guest ユーザとして ssh 接続する。
  2. github からそーそコードをダウンロードする。
  3. $ git clone https://github.com/rasbt/LLMs-from-scratch.git  
    
  4. ./LLMs-from-scratch/ フォルダに移動してから、jupyter lab を起動する。
  5. $ cd LLMs-from-scratch  
    $ jupyter lab --allow-root --ip=0.0.0.0 --no-browser --NotebookApp.token='xxx'  
    
  6. 動作中の jupyter notebook の token を知るには、同じマシンの別のシェルで以下のコマンドを実行する。
  7. $ jupyter lab list  
    

外部のマシンからブラウザで jupyter サーバに接続する。

  1. ローカルネット内のリモートマシンからアクセスする。
  2. http://192.168.12.10:8088/lab?token=xxx
    
  3. インターネット上のリモートマシンからアクセスする場合の URL:
  4. (ルータで 18088 番ポートを 192.168.12.10:8088 にポートフォワーディングしている場合)
    http://ynitta.net:18088/lab?token=xxx