TT Lab
ブログ

한국어 English 日本語 中文

はじめる
ブログ

ブログ

小さなモデルの作成:深さ方向分離畳み込み・プルーニング・蒸留、そしてEfficientTAM

ステータス:ドラフト(2026-10-16)、一部実測値あり。 実際に試したものは、ノートPCのCPUによる例(code/04_small_models.py、1秒前後)と、実験用GPUにおけるEfficientTAMの測定(第6節、自宅ラボの8GBクラスノートPC用GPU1基、使い捨てポッド)です。論文の数値は、条件とともに原典から引用し、ハードウェアはグレードで記載しました。 シリーズ「ビジョンモデルを読む3」の第4編。蒸留の学習原理は「 ビジョンモデルを読む2の第4編」、EfficientTAMの構造は「 ビジョンモデルを読む1の第10編」にあります。

目次

1. 何を削減するのか:計算量・パラメータ数・メモリへのアクセス

モデルを「小さくする」という言葉には、3つの異なる要素が混ざっています。

これら3つは常に連動して変化するわけではありません。本記事の実測値の多くは、その乖離を示しています。

2. 構造の変更:深さ方向分離畳み込み(MobileNet)

작게 만드는 세 가지 길 ① 구조: 깊이별 분리 합성곱(MobileNet) 보통 3×3 채널을 섞으며 공간을 본다 K²·M·N 깊이별 3×3 채널마다 따로 K²·M + 1×1 채널 섞기 M·N 곱셈-덧셈 8.4배↓, 그러나 이 노트북 CPU 시간은 1.6배↓ (채널 128 — 4편 code/04 실측) ② 가지치기: 어디를 0 으로 만드나 비구조적 구조적(행 통째) 모양은 그대로 밀집 곱은 0 도 곱한다 작은 밀집 행렬이 된다 → 바로 빠름 ③ 증류: 큰 교사의 출력을 작은 학생이 따라 배운다 교사 크고 느림 학생 작고 빠름 부드러운 정답
図:通常の3×3畳み込みを深さ方向の3×3と1×1に分解するMobileNetのアイデア、非構造的・構造的プルーニングの形状の違い、教師モデルから生徒モデルへの蒸留

通常の3×3畳み込みは、出力チャネルを1つ生成するたびに、入力チャネル全体の3×3の近傍領域を参照します。「空間を認識する処理」と「チャネルを混合する処理」を同時に行っていると言えます。HowardらのMobileNet(2017)は、この2つを分離します。

  1. 深さ方向(depthwise)3×3:チャネルごとに個別の3×3フィルタを適用。空間の認識のみを行います。
  2. 点別(pointwise)1×1:同一位置のチャネル同士を混合します。

入力チャネル数をM、出力チャネル数をN、フィルタの一辺をK、特徴マップのサイズをH×Wとすると、

보통 합성곱        H·W·M·N·K²
깊이별 분리        H·W·M·K²  +  H·W·M·N
비율(분리 ÷ 보통)  1/N + 1/K²

となります。K=3かつNが大きければ、計算量は約9分の1になります。論文では、3×3畳み込みと比較して8〜9倍少ない計算量であると述べられています(セクション3.1)。

モデル(ImageNet、入力224) top-1 積和演算数 パラメータ数
標準構造、通常の畳み込み 71.7% 4,866M 29.3M
MobileNet(深さ方向分離) 70.6% 569M 4.2M

(MobileNetの論文、表4より。)精度を1%p犠牲にする代わりに、計算量を約8.6倍削減しました。計算の95%が1×1に集中しているという点(表2)も設計の意図通りです。1×1畳み込みは単なる行列積であり、どのようなハードウェアでも高速に実行できるためです。

MobileNetには、サイズを調整するための2つのノブが用意されています。 幅乗数α(チャネル数に乗算)は計算量とパラメータ数を約α²倍にし、 解像度乗数ρ は計算量のみを約ρ²倍に削減します(パラメータ数はそのまま)。論文の表6および7によると、α=0.5の場合、精度は70.6%から63.7%になり(積和演算数149M)、入力解像度が128の場合は64.4%(186M)でした。第5編で解説しますが、解像度を下げると「小さな物体が消えてしまう」という別のトレードオフが発生します。

MobileNetV2(Sandlerら、2018)は、狭いボトルネックを1×1で6倍に拡大した後に深さ方向3×3畳み込みを行い、再び狭める 逆残差構造(Inverted Residuals)を採用しています。再び狭める最後の1×1にはReLUを適用しません(低次元でReLUを適用すると情報が潰れてしまうという観察に基づく)。携帯電話のCPUの大型コア単体での性能は、V1の113msからV2の75msへ向上し、top-1精度は70.6%から72.0%になりました(表4)。

実測:計算量が8.4倍減れば、時間も8.4倍減るのか

チャネル数128、特徴マップ72×128(512×288の入力を4分の1にしたサイズ)において、通常の3×3畳み込みと深さ方向分離をノートPCのCPUのシングルスレッドで測定しました(9回の中央値、 code/04_small_models.out.txt).

パラメータ数 積和演算数 CPU時間 秒間積和演算数
通常の3×3 147,456 1,359.0M 4.23ms 321G/s
深さ方向 3×3 + 1×1 17,536 161.6M 2.62ms(深さ方向 2.06 + 1×1 0.28) —
そのうち深さ方向 3×3 のみ 1,152 10.6M 2.06ms 5.2G/s
そのうち 1×1 のみ 16,384 151.0M 0.28ms 548G/s

計算量は 8.4 倍減ったのに、時間は 1.6 倍しか減りませんでした。犯人は深さ方向 3×3 です。計算量は全体の 7% なのに、時間の 79% を消費しました。深さ方向畳み込みはチャネルを混ぜないため、読み込んだ値一つあたりの計算が非常に少ない(算術強度が低い)です。行列積専用のハードウェアは「一度読み込んだ値で多く計算する」場合にのみ高速であるため、深さ方向畳み込みではそのハードウェアをほとんど遊ばせてしまいます。このノートPCのCPUには行列アクセラレータがあるため、密な畳み込みが特に高速であり、この格差がより大きく見えた可能性があります(他のCPU・GPUは未実測)。

この現象に真っ向から取り組んだ論文が、Ma らによる ShuffleNet V2(2018)です。計算量が同程度の構造でも、GPU とモバイル向け CPU では異なる順序で高速であったため、「計算量は速度の代替指標に過ぎず、ターゲットデバイスで直接測定せよ」と結論付けています。そこで挙げられた 4 つのガイドラインのうち 2 つが、上記の結末と一致しています。グループ畳み込みを過度に使用しないこと(計算量を固定してグループ数を 1 → 8 に増やすと、デスクトップ向け GPU のスループットが 2,451 → 634 に低下)、要素ごとの演算(ReLU・加算)を軽視しないこと(ResNet ブロックから両者を除外すると、GPU・モバイル向け CPU のいずれも約 20% 高速化)です(表 2・4)。

3. 均等なスケーリング:EfficientNet

Tan と Le による EfficientNet(2019)は、逆方向の疑問を投げかけます。小さなベースモデルがあるとき、 深さ・幅・解像度のうち何をスケールアップすべきかという疑問です。一つだけ拡大してもすぐに頭打ちになるため、3 つを所定の比率で同時に拡大します。

깊이 d = α^φ,  폭 w = β^φ,  해상도 r = γ^φ,   조건 α·β²·γ² ≈ 2   (α, β, γ ≥ 1)

畳み込みの計算量は深さに比例し、幅と解像度には2乗で比例するため、Ζ を 1 増やすごとに計算量は約 2 倍になります。ベースモデル B0 は神経構造探索によって見出され、Α=1.2、Β=1.1、Γ=1.15 です。

モデル top-1 パラメータ 計算量(FLOPs)
EfficientNet-B0(224 入力) 77.1% 5.3M 0.39B
EfficientNet-B7 84.3% 66M 37B

(論文の表 2.)アブストラクトの「当時の最高モデルより 8.4 倍小さく、6.1 倍高速」における「高速」とは、 サーバー用 CPU コア 1 つ・バッチ 1 でのレイテンシを指しています(19.0秒対 3.1秒、表 4)。GPU のスループットの話ではないという条件が、要約では抜け落ちがちです。

4. 削減:プルーニング(枝刈り)

学習済みのモデルから小さな重みを 0 にし、再学習によって精度を回復させる手法です。Han らによる Deep Compression(2016)は、プルーニング → 重みの量子化(畳み込み 8 ビット、全結合 5 ビット) → ハフマン符号化により、AlexNet を 240MB → 6.9MB(35 倍)、VGG-16 を 552MB → 11.3MB(49 倍)に縮小しつつ、精度を維持しました(表 1)。プルーニングだけでも、接続数は AlexNet で 9 倍、VGG-16 で 13 倍減少しました。

ここで、「小さくなったこと」と「高速になったこと」を区別する必要があります。この論文が報告している 3〜4 倍の速度向上は、 全結合層のみ、バッチ 1 で測定されたものであり、大きなバッチサイズではそのメリットが失われると論文自身が記しています(セクション 6.3、付録 A)。

実測してみる:0 が 90% なら 10 倍速いのか

2048×2048 の全結合層に対して 64 個の入力を掛け合わせる時間を測定しました(ノートPCのCPU、スレッド 1 つ、9 回の中央値)。

重み 時間
密(プルーニング前) 0.59ms
ランダムに 90% を 0 に(非構造的)、密な乗算 0.59ms
同じ行列をスパース形式(CSR)に変換して乗算 6.83ms
出力行を 90% まるごと削除(構造的)、密な乗算 0.06ms

非構造的プルーニングは形状がそのまま維持されるため、密な乗算は 0 も掛け合わせます。スパース形式に変換すれば 0 をスキップできますが、このサイズとこのスパース性では、不規則なメモリアクセスにかかるコストのため、 11.6 倍低速でした。行をごっそり削除した構造的プルーニングのみが、そのまま小さな密な乗算となり、約 10 倍高速化しました。Li ら(2017)が畳み込みのフィルターを丸ごと削除する手法を提案した理由はここにあります。CIFAR-10 の VGG-16 において計算量が 34% 削減され、デスクトップ向け GPU(バッチ 128)での推論時間が 1.23 秒 → 0.73 秒に短縮されました(表 1・3)。非構造的スパース性も、専用カーネルやハードウェアがあれば高速化する可能性がありますが、今回の測定対象外です(未実測)。

5. 学んだことの移転:知識蒸留

小さな構造で最初から学習させると、大きなモデルほど学習が進まないことがよくあります。 知識蒸留では、大きなモデル(教師)のソフトな出力を、小さなモデル(生徒)の正解ラベルと一緒に使用します。原理と数値については、 ビジョンモデルを読む 2 の第 4 回に詳しく解説されています。リアルタイム性の観点から覚えておくべき点は一つです。 蒸留は構造を変更しません。 生徒の速度は生徒の構造(セクション 2〜4)によって決まり、蒸留はその構造が達成しうる精度により近づける手助けをするだけです。

6. 例:SAM 2 を軽量化した EfficientTAM

Xiong らによる EfficientTAM(2024)は、上記の手法を動画セグメンテーションモデルに適用した例です。 ビジョンモデルを読む 1 の第 10 回に構造についての解説があるため、軽量化した部分のみを改めて記載します。

モデル(論文の表1) パラメータ データセンターGPU FPS スマホの遅延 SA-Vテスト J&F
SAM 2(比較対象) 81M 43.8 — 74.7
EfficientTAM-S 34M 85.0 1,010.8ms 74.5
EfficientTAM-Ti/2 18M 109.4 261.4ms 70.8

(1024×1024入力、GPUはバッチ1。スマホは2023年の上位機種で、計測精度や入力サイズは論文に記載されていません。)入力を512×512に減らした表5では、スマホ80.6ms・SA-V 71.5でした。アブストラクトの「スマホ約10 FPS」に近い数字はこの512入力の場合のみであることは、ビジョンモデルを読む 1 の第10回で指摘した通りです。

私たちの実測:EfficientTAM-Sを実験用GPUで

TT Labの卓球台検出にはEfficientTAM-Sを使用しています。同一の重み(sha256で照合)を、自宅ラボの8GBクラスのノートPC用GPU1枚で計測しました。使い捨てのPod、他のGPUタスクなし、5回のウォームアップ後、10回×3セットの中央値です。

項目 FP32 FP16 BF16
画像エンコーダ、1024×1024、バッチ1 58.8ms 18.7ms 18.7ms
同上、バッチ4(画像あたり) 60.9ms 20.4ms 20.5ms
検出1回(512×288の画面 → エンコーディング + 1つの点でマスク) 69.4ms — 29.9ms
そのうちマスクデコーダのみ(エンコーディング後の1つの点) 3.9ms — —
エンコーダ入力を512×512に変更したバージョン、バッチ1 12.8ms — 5.9ms

7. 限界

8. 当プロジェクトとの関連

次回の記事は、モデルをそのままにして 頻度を少なく、範囲を狭く 実行する方法について解説します。

TTの一言。 乗算を8分の一に減らしたのに、時間は1.6倍しか縮まらなかったよ。計算よりも読み込みの方が遅いときがあるからね。秤(計算量)よりも時計(実測)を信じよう!

参考文献

ログインするといいねできます

コメント

まだコメントはありません。

ログインするとコメントできます