1. このレッスンの範囲
E資格の「開発・運用環境」科目から、シラバス範囲の コンテナ型仮想化(Docker・Dockerfile)・ モデル軽量化(プルーニング・蒸留・量子化)・アクセラレータ(GPU/TPU)・分散処理を扱います。 理論よりも「コード・設定ファイルを読めること」に重点を置きます。
2. コンテナ型仮想化と Docker
「自分のPCでは動いたのに、別の環境では動かない」——これを防ぐのが Docker です。 アプリと必要なライブラリ・設定をコンテナという箱にまとめ、どの環境でも同じように動かす(再現性)。 深層学習では「PyTorchのバージョン・CUDA・依存ライブラリ」を固定するのに不可欠です。
- イメージ…コンテナの設計図(テンプレート)。Dockerfile から作る。
- コンテナ…イメージを実行した実体。
- 仮想マシン(VM)との違い…VMはOSごと丸ごと仮想化するのに対し、コンテナはOSのカーネルを共有するため軽量・高速。
3. Dockerfile を読む
Dockerfile はイメージの作り方を書いたテキストファイル。命令を上から順に実行してイメージを組み立てます。
💡 まずは安心して:Dockerfile は命令の基本的な種類さえ分かればOKです(E資格でも基本的な命令の意味が中心)。 いきなり全部を覚える必要はありません。下のファイルを上から1命令ずつ、コメントと一緒に「どの命令が何をするか」を追っていきましょう。
# ① 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 を先に COPY → RUN pip install するのは、
コード変更時にインストールのキャッシュを使い回すための定石です。
4. モデルの軽量化(プルーニング・蒸留・量子化)
学習済みモデルをスマホやエッジ端末で動かすには、小さく・速くする必要があります。代表的な3手法です。
- プルーニング(枝刈り)…重要度の低い重み(ほぼ0など)を削る。モデルを疎にして軽量化。
- 蒸留(distillation)…大きな「教師モデル」の出力を真似るように小さな「生徒モデル」を学習させる。
- 量子化(quantization)…重みを float32 → int8 など低ビットに変換。サイズ・計算量を削減。
💡 下のコードがやるのは「量子化」:3手法のうち、コードで効果を手早く見せやすい量子化を実演します
(プルーニング・蒸留は学習や再構成が絡むので、ここでは概念で押さえればOK)。
torch.quantization.quantize_dynamic(...) が量子化を行う関数です。
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です。
5. アクセラレータ(GPU/TPU)と分散処理
深層学習の行列計算は GPU(や TPU)で大幅に高速化します。
PyTorch では モデルとデータを同じ device に載せるのが基本ルール。.to(device) で移します。
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)
使うdevice: cpu
x の device: cpu
⚠ device 不一致エラー(頻出): モデルが GPU、データが CPU のように載っている場所が違うと 「Expected all tensors to be on the same device」エラーになります。 モデルとデータは必ず同じ device に。大規模化では複数GPUに分けて学習する分散処理(データ並列)や、 端末間で協調する連合学習も使われます(こちらはシラバスのオプション項目)。
6. 練習問題
最初に書く Dockerfile の命令は?
Dockerfile の先頭に書き、土台のイメージを指定する命令はどれですか。
- A. RUN
- B. FROM
- C. CMD
答えと解説を見る
正解:B. FROM
FROM でベースイメージ(例:python:3.10-slim)を指定するのが出発点。これが無いとイメージを作れません。
RUN と CMD の違いは?
「コンテナを起動したときに実行されるコマンド」を書く命令はどれですか。
- A. RUN(イメージ作成時に実行)
- B. CMD(コンテナ起動時に実行)
- C. COPY(ファイルをコピー)
答えと解説を見る
正解:B. CMD
RUN はイメージを作るとき(pip install 等)、CMD はコンテナ起動時(学習スクリプトの実行等)。
量子化の目的は?
モデルの量子化(float32 → int8)の主な目的はどれですか。
- A. モデルのサイズと計算量を減らして軽く・速くする
- B. 学習の精度を必ず上げる
- C. クラス数を増やす
答えと解説を見る
正解:A
低ビット化でサイズ・計算量を削減し、エッジ端末でも動かしやすくします。精度はわずかに落ちることがあるのがトレードオフです。
蒸留(distillation)とは?
モデルの蒸留はどのような手法ですか。
- A. 大きな教師モデルの出力を真似るよう、小さな生徒モデルを学習させる
- B. 重要度の低い重みを削る
- C. 画像を回転・反転させてデータを増やす
答えと解説を見る
正解:A
B はプルーニング、C はデータ拡張。蒸留は「教師の知識を小さなモデルに移す」軽量化手法です。
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 を土台にしています。
量子化コードの空欄に入るのは?
重みを int8 に量子化するとき、____ に入るものはどれですか。
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(土台)→WORKDIR→COPY/RUN(作成時)→CMD(起動時) RUN=イメージ作成時、CMD=コンテナ起動時- 軽量化:プルーニング(枝刈り)・蒸留(生徒が教師を真似る)・量子化(低ビット化)
- 量子化は float32→int8 でサイズ約1/4。精度はわずかに低下しうる
- GPU/TPUは
deviceで扱い、モデルとデータを同じ device に(.to(device))
いよいよ最終レッスン。これまでの読み解きの総まとめと、力試しの方法を確認します。
完了するとコース一覧に進捗が記録されます