llama.cpp量子化:重要度行列(Importance Matrix)計算に使うテキストについて

  • 以前にも取り上げている件ですが、現在のllama.cppでは重要度行列(Importance Matrix)計算を利用することで量子化精度が改善できます。
    • 特に4bit以下の低bit量子化を行う場合は、このiMatrix版の量子化が推奨されます(Metal環境などでは推論速度が遅くなるので要注意)。
  • Claude 3 Opusによると、重要度行列とは以下のように説明できます。

Importance Matrixは、言語モデル量子化において、各パラメータの重要度を表現するために使用される行列のことを指します。

量子化の過程では、モデルの精度を維持しつつ、パラメータを低ビット幅の整数値で表現します。しかし、すべてのパラメータが同等に重要というわけではありません。そこで、Importance Matrixを用いて、各パラメータの重要度を評価します。

具体的には、以下のような手順で計算されます:

1.学習済みのモデルを用意する
2.各パラメータに対して、そのパラメータの値を微小量だけ変化させたときの、モデルの出力への影響を計算する
3.影響の大きさを正規化し、Importance Matrixの対応する要素に格納する

こうして得られたImportance Matrixは、量子化の際のビット割当てに利用されます。重要度の高いパラメータにはより多くのビットを割り当て、重要度の低いパラメータには少ないビットで済ませることで、量子化後のモデル精度の低下を最小限に抑えることができます。

Importance Matrixは、モデル圧縮の分野で広く使われている概念で、特に携帯端末やエッジデバイス向けの小型モデルを作成する際に重宝されています。同様の考え方は、pruning(枝刈り)など、他のモデル圧縮手法にも応用されています。

  • さて、llama.cppの重要度行列計算では通常、英語版のwiki.trainが入力テキストとして使われていますが、この選択が妥当なのかどうかという議論が存在します。
  • 以下はllama.cppのRepoにおけるディスカッションです。

github.com

  • 基本的には、実際の用途に近いテキストを使って重要度行列を計算するのがよいとされています。
    • 例えば、コーディング支援で使うモデルならコードを含むテキストがよく、中国語で使うモデルなら中国語を含むテキストがいいはずです。
  • 以下のデータを見ると、確かにテスト用テキストと同系統の入力テキストを利用したほうがKL-Divergenceの値が改善しています。一方で、入力テキストの量については特に精度に寄与していないことも分かります。

  • 以下は、雑多な内容の疑似ランダムテキスト、C4の英仏混合学習テキスト、通常のwiki.trainテキストを使用した場合の当惑度(Perplexity)およびLLMベンチマーク(MMLUとHellaSwag)のスコア比較です。

  • これらの結果に基づいて、llama.cppの量子化実装を手掛けているikawrakowさんは以下のように指摘しています。
    • Wikitextから得られた重要度行列は、ランダムに近いデータによる重要度行列よりも、小さいとはいえ統計的に有意に優れている。よって、基本的にWikitextを使用するのが無難である。
    • 英語以外の言語で使いたいけれど、その言語では有用なトレーニングテキストが見つからない場合は、疑似ランダムデータが使えるかもしれない。
    • フランス語のC4データセットにおけるモデルの当惑度は、フランス語だけの重要度行列を使用した場合にさらに改善する。特定言語が主なユースケースである場合、その言語だけのテキストを使用してimatrixを作成することが最善かもしれない。
  • なお、日本語テキストによる重要度行列計算については、以下の記事で簡単に検証しています。

sc-bakushu.hatenablog.com

  • 上記記事のあと、日本語モデルのKarakuri 70Bでも試してみましたが、やはり日本語のみの用途であれば日本語テキストで計算したほうが当然ながらベターな結果が得られそうです。
    • ただし、日本語のみのデータセットを使うと英語のPPLが十分に改善しなかったので、実用的には日英混合テキストのほうがよいかもしれません。