モデルプルーニングは、大規模モデルに引き算をする手法です。重みの中でゼロに近く、出力への影響が小さい接続を見つけて削除またはゼロ化し、モデルを小さく速くしながら、能力の低下をわずかに抑えます。量子化や蒸留とまとめてモデル圧縮と呼ばれますが、手を入れる場所はまったく違うため、まずはプルーニング自体を整理します。
切っているのは何か
ニューラルネットワークの体積を占めるのは、ニューロン同士の接続の強さを表す重みです。学習後の重みの分布は均一ではなく、一部の接続が判断の大半を担い、残りの長い裾野はゼロに近く、ほぼ背景ノイズです。プルーニングは接続を重要度で順位付けし、その裾野を取り除きます。
やり方は二つあります。非構造化プルーニングは重みを一つずつゼロ化し、ファイルの中に大量のゼロを作ります。理論上は容量を節約できますが、通常のハードウェアではゼロの計算は速くならず、専用のスパース計算の支援がなければ速度は出ません。構造化プルーニングはチャネル単位、注意ヘッド単位、場合によっては層ごと削除し、形の整ったモデルが残るため、一般的な GPU やスマートフォンのチップでそのまま高速化できます。実務で多いのは後者で、理由はまさにここにあります。
接続をかなり切っても動く理由
鍵は過剰パラメータ化です。学習をうまく進めるため、モデルには課題に本当に必要な量をはるかに超えるパラメータが与えられがちです。多くの接続は最初から冗長で、互いに打ち消し合ったり、ごく少数の事例でしか働かなかったりします。これらを外すのは、耐力壁ではなく足場を撤去するようなものです。
ただし、一度に切って終わりではありません。乱暴に削除すると性能が目に見えて落ちるため、標準的な手順は少し切ってはデータで微調整して回復させ、また切る、という繰り返しです。宝くじ仮説が述べているのも似た現象で、大規模ネットワークの中には、単独で学習しても近い性能に届く、はるかに小さい部分ネットワークが隠れているという考え方です。切れる上限は冗長性の量で決まり、もともと無駄なく学習されたモデルには余裕がほとんどありません。
量子化や蒸留との違い
| 手法 | 変えるもの | モデルの形 | 主な効果 |
|---|---|---|---|
| プルーニング | 接続やチャネルごと削除 | 小さく、疎になる | パラメータ数が減り、構造化ならそのまま高速化 |
| 量子化 | 数値の精度を16ビットから8ビット、4ビットへ | 変わらない | メモリ使用量が大きく減る |
| 蒸留 | 小さいモデルに大きいモデルの出力を真似させる | 別の新しいモデル | 独立した小モデルが得られる |
三つは重ねて使うことが多く、まずプルーニングで痩せさせ、量子化で精度を落とし、蒸留や微調整で性能を取り戻します。オープンなモデルがプルーニング版を名乗っている場合、構造ごと切ったのか、ただゼロ化したのかを確認してください。前者は実際に速くなり、後者は大抵ファイルが小さく見えるだけです。
よくある三つの誤解
第一に、プルーニングはデータを消すことではなく、モデル内部のパラメータに触れる作業で、学習データとは無関係です。第二に、切れば切るほど得というわけではなく、冗長性の境界を越えると性能は崖のように落ち、しかも先に消えるのはニッチな知識やロングテールの能力で、一般的なテストでは検出できません。第三に、プルーニングで空いたメモリでより大きなモデルを学習できるわけではありません。主に推論のデプロイ向けであり、学習時のメモリの主役はオプティマイザの状態と活性化値で、プルーニングの出番はありません。
プルーニングすべきか迷ったら、二点を確認してください。デプロイ先の計算資源とメモリが本当に逼迫しているか、回復用の微調整データがあるか。両方イエスなら着手し、ファイルサイズを格好よくしたいだけなら、性能低下のリスクを冒す価値はありません。