Lesson 11 / 12

開発・運用環境(Docker・軽量化・GPU)

このレッスンで学ぶこと

  • コンテナ型仮想化と Docker が「環境の再現性」を保つ仕組みだと分かる
  • Dockerfile の主要命令(FROM/RUN/COPY/WORKDIR/CMD)を読める
  • モデル軽量化(プルーニング・蒸留・量子化)の違いを説明できる
  • GPU/TPU と device.to(device) の役割が分かる

1. このレッスンの範囲

E資格の「開発・運用環境」科目から、シラバス範囲の コンテナ型仮想化(Docker・Dockerfile)モデル軽量化(プルーニング・蒸留・量子化)アクセラレータ(GPU/TPU)・分散処理を扱います。 理論よりも「コード・設定ファイルを読めること」に重点を置きます。

2. コンテナ型仮想化と Docker

📘 先に理論を確認: コンテナ型仮想化・Docker・Dockerfile の理論は、E資格対策ページ 「環境構築 ― コンテナ型仮想化(Docker)」 にまとまっています。本レッスンは「コードや設定ファイルを読めること」に絞ります。

「自分のPCでは動いたのに、別の環境では動かない」——これを防ぐのが Docker です。 アプリと必要なライブラリ・設定をコンテナという箱にまとめ、どの環境でも同じように動かす(再現性)。 深層学習では「PyTorchのバージョン・CUDA・依存ライブラリ」を固定するのに不可欠です。

3. Dockerfile を読む

Dockerfile はイメージの作り方を書いたテキストファイル。命令を上から順に実行してイメージを組み立てます。

💡 まずは安心して:Dockerfile は命令の基本的な種類さえ分かればOKです(E資格でも基本的な命令の意味が中心)。 いきなり全部を覚える必要はありません。下のファイルを上から1命令ずつ、コメントと一緒に「どの命令が何をするか」を追っていきましょう。

Dockerfile(読むだけ/上から順に実行される)
# ① FROM:土台にするイメージ(OS+Python)を選ぶ。Dockerfileは必ずここから始まる
FROM python:3.10-slim

# ② WORKDIR:この先のコマンドを実行する「作業フォルダ」を /app に決める(無ければ作成)
WORKDIR /app

# ③ COPY+RUN:まず依存リスト(requirements.txt)だけをコピーして pip install。
#    コードより先に入れておくと、コードを直すたびに入れ直さずに済む(キャッシュ再利用=速い)
COPY requirements.txt .
RUN pip install -r requirements.txt

# ④ COPY . . :いまのフォルダの中身(アプリ本体)をすべてコンテナ内へコピー
COPY . .

# ⑤ CMD:コンテナを「起動したとき」に動く既定コマンド(ここでは学習スクリプトを実行)
CMD ["python", "train.py"]
▼ 使うときのコマンドと結果(イメージ)
$ docker build -t my-dl-app .      # Dockerfileからイメージを作る
  => naming to docker.io/library/my-dl-app          done

$ docker run my-dl-app             # コンテナを起動(CMDのtrain.pyが走る)
  epoch 0 loss 0.69 ...
命令役割
FROM土台になるベースイメージを指定(最初に必ず書く)
WORKDIR以降のコマンドを実行する作業ディレクトリ
COPYホストのファイルをコンテナ内にコピー
RUNイメージ作成時に実行(パッケージのインストール等)
CMDコンテナ起動時に実行する既定コマンド

💡 RUN と CMD の違い(頻出): RUNイメージを作るときに走る(例:ライブラリのインストール)。 CMDコンテナを起動するときに走る(例:学習スクリプトの実行)。 また requirements.txt を先に COPYRUN pip install するのは、 コード変更時にインストールのキャッシュを使い回すための定石です。

4. モデルの軽量化(プルーニング・蒸留・量子化)

📘 先に理論を確認: モデル軽量化(プルーニング・蒸留・量子化)とエッジ実行の理論は、E資格対策ページ 「エッジコンピューティング ― モデルの軽量化」 で復習できます。

学習済みモデルをスマホやエッジ端末で動かすには、小さく・速くする必要があります。代表的な3手法です。

💡 下のコードがやるのは「量子化」:3手法のうち、コードで効果を手早く見せやすい量子化を実演します (プルーニング・蒸留は学習や再構成が絡むので、ここでは概念で押さえればOK)。 torch.quantization.quantize_dynamic(...) が量子化を行う関数です。

quantize.py(PyTorch・読むだけ)
import torch
import torch.nn as nn
import io                       # メモリ上でデータを扱う標準ライブラリ(下でサイズ計測に使う)

model = nn.Sequential(nn.Linear(256, 256), nn.ReLU(), nn.Linear(256, 10))

# モデルの保存サイズ(KB)を測る関数
def size_kb(m):
    b = io.BytesIO()                       # ① メモリ上の"仮想ファイル"を用意(ディスク保存は不要)
    torch.save(m.state_dict(), b)          # ② そこへ重み(state_dict)を書き込む
    return round(len(b.getvalue()) / 1024, 1)  # ③ バイト数 ÷ 1024 = KB

# 動的量子化:Linear層の重みを float32 → int8 に変換(=量子化の本体)
q = torch.quantization.quantize_dynamic(model, {nn.Linear}, dtype=torch.qint8)

print("float32 サイズ:", size_kb(model), "KB")
print("int8量子化後 :", size_kb(q), "KB")
▼ 出力
float32 サイズ: 268.8 KB
int8量子化後 : 70.6 KB

💡 見慣れない io.BytesIO() は何者? これはメモリ上の"仮想ファイル"です。モデルのサイズを測るためだけにディスクへ保存するのは面倒なので、 torch.save(...) でこのバッファに書き込み、そのバイト数len(b.getvalue()))を数えて KB に直しています。 state_dict()モデルの重みの中身(学習されたパラメータ)を指します。 本筋は quantize_dynamic(...) の1行=量子化で、io まわりは「サイズを測る道具」と捉えればOKです。

理論の確認: 量子化で float32(4バイト)→ int8(1バイト)になるため、サイズは理論上およそ1/4。 上の例でも約 1/4(268.8 → 70.6 KB)に縮みました。精度はわずかに落ちることがあるのがトレードオフです。

5. アクセラレータ(GPU/TPU)と分散処理

📘 先に理論を確認: GPU/TPU などアクセラレータの理論は 「アクセラレータ ― デバイスによる高速化」、分散処理(モデル並列・データ並列・連合学習)は 「分散処理」 で復習できます。

深層学習の行列計算は GPU(や TPU)で大幅に高速化します。 PyTorch では モデルとデータを同じ device に載せるのが基本ルール。.to(device) で移します。

device.py(PyTorch・読むだけ)
import torch

# GPUが使えれば 'cuda'、なければ 'cpu' を選ぶ定石
device = "cuda" if torch.cuda.is_available() else "cpu"
print("使うdevice:", device)

x = torch.randn(2, 3).to(device)   # データをdeviceへ
# model = model.to(device)        ← モデルも同じdeviceへ載せる
print("x の device:", x.device)
▼ 出力(GPUが無い環境の例)
使うdevice: cpu
x の device: cpu

⚠ device 不一致エラー(頻出): モデルが GPU、データが CPU のように載っている場所が違うと 「Expected all tensors to be on the same device」エラーになります。 モデルとデータは必ず同じ device に。大規模化では複数GPUに分けて学習する分散処理(データ並列)や、 端末間で協調する連合学習も使われます(こちらはシラバスのオプション項目)。

6. 練習問題

問題 1

最初に書く Dockerfile の命令は?

Dockerfile の先頭に書き、土台のイメージを指定する命令はどれですか。

  • A. RUN
  • B. FROM
  • C. CMD
答えと解説を見る

正解:B. FROM

FROM でベースイメージ(例:python:3.10-slim)を指定するのが出発点。これが無いとイメージを作れません。

問題 2

RUN と CMD の違いは?

「コンテナを起動したときに実行されるコマンド」を書く命令はどれですか。

  • A. RUN(イメージ作成時に実行)
  • B. CMD(コンテナ起動時に実行)
  • C. COPY(ファイルをコピー)
答えと解説を見る

正解:B. CMD

RUN はイメージを作るとき(pip install 等)、CMD はコンテナ起動時(学習スクリプトの実行等)。

問題 3

量子化の目的は?

モデルの量子化(float32 → int8)の主な目的はどれですか。

  • A. モデルのサイズと計算量を減らして軽く・速くする
  • B. 学習の精度を必ず上げる
  • C. クラス数を増やす
答えと解説を見る

正解:A

低ビット化でサイズ・計算量を削減し、エッジ端末でも動かしやすくします。精度はわずかに落ちることがあるのがトレードオフです。

問題 4

蒸留(distillation)とは?

モデルの蒸留はどのような手法ですか。

  • A. 大きな教師モデルの出力を真似るよう、小さな生徒モデルを学習させる
  • B. 重要度の低い重みを削る
  • C. 画像を回転・反転させてデータを増やす
答えと解説を見る

正解:A

B はプルーニング、C はデータ拡張。蒸留は「教師の知識を小さなモデルに移す」軽量化手法です。

問題 5

Dockerfile の空欄に入る命令は?

次の Dockerfile の ____ に入る命令はどれですか。

Dockerfile
____ python:3.10-slim
WORKDIR /app
COPY . .
CMD ["python", "app.py"]
  • A. RUN
  • B. COPY
  • C. FROM
答えと解説を見る

正解:C. FROM

Dockerfile は必ず FROM(土台のベースイメージ指定)から始まります。ここでは python:3.10-slim を土台にしています。

問題 6

量子化コードの空欄に入るのは?

重みを int8 に量子化するとき、____ に入るものはどれですか。

quantize.py(PyTorch)
q = torch.quantization.quantize_dynamic(
        model, {nn.Linear}, dtype=____)
  • A. torch.float32
  • B. torch.bool
  • C. torch.qint8
答えと解説を見る

正解:C. torch.qint8

qint8 は「量子化された int8」を表す型。float32 のままでは量子化になりません。int8 化でサイズが約1/4になります。

7. まとめ

このレッスンのポイント

  • Docker はアプリ+環境をコンテナに固め、どこでも同じに動かす(再現性)。VMより軽量
  • Dockerfile:FROM(土台)→ WORKDIRCOPY/RUN(作成時)→ CMD(起動時)
  • RUN=イメージ作成時、CMD=コンテナ起動時
  • 軽量化:プルーニング(枝刈り)・蒸留(生徒が教師を真似る)・量子化(低ビット化)
  • 量子化は float32→int8 でサイズ約1/4。精度はわずかに低下しうる
  • GPU/TPUは device で扱い、モデルとデータを同じ device に.to(device)

いよいよ最終レッスン。これまでの読み解きの総まとめと、力試しの方法を確認します。

完了するとコース一覧に進捗が記録されます