Mímisbrunnr知恵の泉

← MLOps 一覧

🎓 レベル:発展 | 重要度:B(推奨)

📎 前提:レイテンシとスループットのトレードオフ | 関連:LLMの推論サービングと最適化基盤

要点(BLUF)

1. 3手法の概観

flowchart TB
  M["大きく重いモデル"] --> Q["量子化:精度ビット数を下げる"]
  M --> D["蒸留:小モデルに知識を移す"]
  M --> P["枝刈り:小さい重みを削除"]
  Q --> R["小さく速いモデル(精度はわずかに低下)"]
  D --> R
  P --> R
手法やること主な効果主なコスト
量子化float32→int8 等に精度を下げるサイズ約1/4・高速化わずかな精度低下
蒸留教師の出力を生徒が学習小モデルで高い精度学習の手間(教師が必要)
枝刈り寄与の小さい重みを0にスパース化・サイズ減専用ランタイムが要ることも

2. なぜ軽量化が効くのか

推論コストは「モデルの計算量 × リクエスト数」です。バッチングや台数増(ハードウェアとスケーリング)はリクエスト側を捌きますが、軽量化は1リクエストの計算量そのものを減らします。特にエッジ・モバイルや、LLM のように巨大なモデル(LLMの推論サービングと最適化基盤)では、軽量化が実用可否を分けます。

3. 動く最小例:枝刈りと量子化の効果を擬似的に測る

線形モデルの係数で、(a) 枝刈り(小さい係数を0にする)と (b) 量子化(係数を粗い格子に丸める)が、サイズを減らしつつ精度をどれだけ保つかを見ます。深層モデルでなくても、トレードオフの本質は同じです。

import numpy as np
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score

rng = np.random.default_rng(0)
X = rng.normal(0, 1, (1000, 50))
true_w = np.zeros(50); true_w[:10] = rng.normal(0, 1, 10)   # 実質10次元
y = (X @ true_w + 0.3 * rng.normal(size=1000) > 0).astype(int)
k = 800
Xtr, Xte, ytr, yte = X[:k], X[k:], y[:k], y[k:]

model = LogisticRegression(max_iter=1000).fit(Xtr, ytr)
w = model.coef_[0].copy()
base_acc = accuracy_score(yte, model.predict(Xte))

def predict_with(weights, intercept, X):
    return (X @ weights + intercept > 0).astype(int)

b = model.intercept_[0]
# (a) 枝刈り:絶対値が小さい下位60%の係数を0に
thr = np.quantile(np.abs(w), 0.60)
w_pruned = np.where(np.abs(w) < thr, 0.0, w)
acc_pruned = accuracy_score(yte, predict_with(w_pruned, b, Xte))
nonzero = int((w_pruned != 0).sum())

# (b) 量子化:係数を0.25刻みの格子に丸める(粗い表現)
w_quant = np.round(w / 0.25) * 0.25
acc_quant = accuracy_score(yte, predict_with(w_quant, b, Xte))
n_levels = len(np.unique(w_quant))

print(f"元モデル   : 精度={base_acc:.3f}  非ゼロ係数={int((w!=0).sum())}/50")
print(f"枝刈り後   : 精度={acc_pruned:.3f}  非ゼロ係数={nonzero}/50  (60%削除)")
print(f"量子化後   : 精度={acc_quant:.3f}  係数の値の種類={n_levels}(粗い格子)")

出力:

元モデル   : 精度=0.955  非ゼロ係数=50/50
枝刈り後   : 精度=0.945  非ゼロ係数=20/50  (60%削除)
量子化後   : 精度=0.950  係数の値の種類=11(粗い格子)

出力の意味:係数の60%をゼロにする枝刈りをしても精度は 0.955→0.945 とほぼ維持(元データが実質10次元なので、小さい係数はほぼノイズで削っても効かない)。係数を0.25刻みの粗い格子に量子化しても精度は 0.955→0.950 とほぼそのままで、係数の値はわずか11種類に圧縮されました。サイズ(非ゼロ数・表現精度)を大きく削っても精度はわずかしか落ちない——これが軽量化の効く理由です。ただし削りすぎれば精度は崩れるので、許容精度の範囲で軽量化率を選びます(深層モデルでの具体手法は機械学習分野へ)。

4. 運用の勘所

なぜそうするのか

軽量化が成立するのは、学習済みモデルには冗長性があるからです。多くの重みは最終的な予測にほとんど寄与せず(§3 のノイズ係数)、数値精度も過剰なことが多い。だから精度をほぼ保ったままサイズと計算量を削れます。これがコスト(推論単価・メモリ・電力)に直結し、特にエッジや巨大モデルでは「動かせるか否か」を決めます。ただし冗長性には限りがあるので、削りすぎれば精度が崩れる——許容低下を決めて最大の軽量化を選ぶ、という設計になります。

⚠️ よくある落とし穴

対応 lab

関連ノート