実践Hugging Face にアクセスして大規模な言語モデルを閲覧し始めると、すぐに傾向に気付くでしょう。ほとんどのモデルは、Brain-float 精度の 16 ビット浮動小数点でトレーニングされています。
FP16 と BF16 は、精度、スループット、モデル サイズのバランスが優れているだけでなく、CPU、GPU、専用の AI アクセラレータなど、ほとんどのハードウェアでデータ タイプが広くサポートされていることから、機械学習で非常に人気が高まっています。
問題は、16ビットテンソルを持つモデル、特に大規模なモデルをシングルチップで実行しようとすると発生します。パラメータあたり2バイトのLlama-3-70Bのようなモデルでは、少なくとも140GBの超高速メモリが必要です。しかも、これにはキーバリューキャッシュなどのオーバーヘッドは含まれていません。
これを回避するには、モデルを複数のチップ(またはサーバー)に分割するか、量子化と呼ばれるプロセスでモデルの重みを低い精度に圧縮することができます。
通常、量子化は精度を犠牲にしてモデルを小さくするものとして考えられますが、特に PC やノートパソコンで LLM を実行する場合には、他の利点もあります。
この実践ガイドでは、次の内容について説明します。
- 量子化の仕組み。
- 量子化へのさまざまなアプローチ。
- Llama.cpp と GGUF クォンツを使用してセーフテンソル モデルを圧縮する方法。
- 量子化のトレードオフとそれをベンチマークする方法。
- そして、量子化の実際的な限界。
量子化の基礎
大まかに言えば、量子化とは、モデルパラメータ(ほとんどの場合、モデルの重みを意味します)を取得し、それを低精度の浮動小数点値または整数値に変換することです。
これを色深度と比較することで視覚的に理解できます。16ビットカラーのビットマップでは、画像の各ピクセルは最大65,536色のいずれかを表現することができます。これは人間が通常認識できる色数よりもはるかに少ないですが、脳が、ええと、画像を理解するには十分な色数です。
LLM量子化は画像の色深度に似ています。ビット深度を低くすると容量は節約できますが、画質は低下します。この概念については上記をご覧ください。クリックして拡大
8ビットカラーでは、ピクセルあたり256通りの色値しか扱えなくなります。そのため、上記の例では画質が明らかに低下していますが、それでもオウムを識別するのに十分な情報量があります。また、この深度では、ビットマップ画像のメモリ消費量は半分になります。
4 ビット カラーでは、メモリ フットプリントがさらに半分に削減されますが、ピクセルあたり最大 16 色しか残らないため、損失はより顕著になり、2 ビット カラーに落とすと状況が本当に崩れ始めます。
では、これはAIとどう関係があるのでしょうか?ニューラルネットワークモデルを量子化してビット深度を下げることは、本質的には同じ概念ですが、ピクセルではなくモデルの重みについて話しているのです。
ご存知ない方のために説明すると、重みとは(大まかに言えば)ニューラルネットワーク内の値であり、入力を出力に変換するために使用されます。重みは、例えば写真内の物体を検出・識別したり、与えられたプロンプトから適切な単語を選んだりといったモデルの能力を定義します。
これらの値は学習プロセス中に設定され、推論中に使用されます。精度が高いほど、重みの値を細かく設定できますが、使用するメモリ容量も大きくなります。モデルの重みを扱う際には、必要と思われるよりも低い精度でも問題ないことがよくあります。
量子化の利点
前述の通り、モデルを量子化する最大の理由の一つは、単一のGPUまたはアクセラレータのメモリ、あるいはCPUパワーのみを使用する場合はシステムメモリに収まるサイズまでモデルを縮小することです。しかし、量子化のメリットはそれだけではありません。
量子化モデルのフットプリントが小さいため、一定のパフォーマンスレベルを達成するために必要なメモリ帯域幅も削減されます。これはCPUでモデルを実行する際に役立ちます。メモリ容量はそれほど大きな問題ではありませんが、帯域幅は問題になる可能性があるからです。ホストプロセッサのDRAMは、GPUのGDDR6、あるいはより優れたHBMと比較すると低速です。
これらの要素は、LLM を PC 上でローカルに実行する場合に特に重要です。8 ビット、4 ビット、または 2 ビットの精度に量子化することで、消費者向け GPU やシステム メモリに許容されるわずかな vRAM にモデルを収めることができるためです。
では、実際にはどのようなものになるのでしょうか?これを調べるために、人気のLLMランナーLlama.cppを用いて、Mistral 7BとGoogleの新しいGemma2 9Bモデルの量子化バージョンを作成し、いくつかのテストを実行しました。次に、出力トークン長とコンテキストサイズを制御しながら、各モデルをNvidia RTX 6000 Ada Generationワークステーションカードで実行しました。
結果は次のとおりです...
ミストラル7Bのサイズとさまざまな量子化レベルでのパフォーマンス
量子化 | ビット/重量 | ファイルサイズ | パフォーマンス | 圧縮 |
---|---|---|---|---|
GGUF FP16 | 16 | 13,826 MB | 55 トク/秒 | ネイティブ |
GGUF Q8_0 | 8.5 | 7,346 MB | 94 トク/秒 | 47% |
GGUF Q4_0 | 4.5 | 3,923 MB | 149 トク/秒 | 72% |
GGUF Q2_K | 2.56 | 2,597MB | 200 トク/秒 | 81% |
Gemma2 9Bのサイズとさまざまな量子化レベルでのパフォーマンス
量子化 | ビット/重量 | ファイルサイズ | パフォーマンス | 圧縮 |
---|---|---|---|---|
GGUF FP16 | 16 | 17,635 MB | 40 トク/秒 | ネイティブ |
GGUF Q8_0 | 8.5 | 9,372 MB | 65 トク/秒 | 47% |
GGUF Q4_0 | 4.5 | 5,191 MB | 101 トク/秒 | 71% |
GGUF Q2_K | 2.56 | 3,630 MB | 122 トク/秒 | 79% |
予想どおり、これらのモデルを低い精度に量子化すると、メモリ フットプリントが縮小されるだけでなく、必要なメモリ帯域幅の量が減ることで動作パフォーマンスも向上します。
もちろん、これは科学的なテストを目的としたものではありませんが、限られたリソースでモデルを実行するための強力なツールとして量子化がなぜ役立つのかを説明してくれることを願っています。
ぜひお試しください
これは Llama.cpp のインストールと構成に関するガイドではありませんが、Hugging Face またはその他の場所からの safetensor モデル ファイルを量子化された GGUF モデルに変換したい場合は、次の手順に従ってください。
ここからは、少なくともPython 3がインストールされたLinuxを使用し、ターミナルでコマンドラインレベルのソフトウェアを取得、インストール、使用できることを前提とします。Llama.cppはここから入手できます。
llama.cpp フォルダがホーム ディレクトリにあると仮定して、まず Python3 仮想環境を作成し、Pythonpip
パッケージ マネージャーを使用して必要な依存関係をインストールします。
cd ~/llama.cpp python3 -m venv venv && source venv/bin/activate pip3 インストール -r 要件.txt
次に、モデル用の新しいディレクトリを作成し、huggingface-cli
ツールを使用してログインし、適切なディレクトリにモデルをダウンロードします。この例では、Mistral-7Bをダウンロードします。
mkdir ~/llama.cpp/models/mistral huggingface-cli ログイン #ゲートモデルのダウンロードに必要 huggingface-cli で mistralai/Mistral-7B-Instruct-v0.3 をダウンロード --local-dir ~/llama.cpp/models/mistral/
モデルをダウンロードしたら、convert_hf_to_gguf.py
スクリプトを使用して 16 ビット GGUF モデル ファイルに変換する必要があります。
python3 convert_hf_to_gguf.py ~/llama.cpp/models/mistral/
数分後、 という名前の新しいファイルggml-model-f16.gguf
が生成され、希望する方法で量子化できます。基本的な構文は次のとおりです。
./llama-quantize <入力モデル f16.gguf> <出力モデル quantized.gguf> <量子化方法 Q4_0>
したがって、Q4_0 メソッドを使用して Mistral-7B を 4 ビットに量子化するには、次を実行します。
./llama-quantize ~/llama.cpp/models/mistral/ggml-model-f16.gguf ~/llama.cpp/models/mistral/mistral-7b-Q4_0.gguf Q4_0
コマンドライン インターフェイスで簡単なチャット インターフェイスを起動してテストすることができます。
./llama-cli -ngl 999 -n 128 -m ~/llama.cpp/models/mistral/mistral-7b-Q4_0.gguf -p "あなたは役に立つアシスタントです" -cnv
しばらくすると、新しく量子化されたモデルのクエリを開始するために使用できるチャットボット スタイルのインターフェイスが表示されます。
-ngl
注: この例では、 ( の略)を に設定して--n-gpu-layers
、999
すべてのモデルレイヤーがGPUにオフロードされるようにしています。CPUで実行する場合は、このコマンドラインオプションを削除してください。
量子化のさまざまな方法
モデル全体をより低い精度に量子化することは可能ですが、実際には出力品質と精度の点で必ずしも最良の結果が得られるとは限りません。
代わりに、異なるパラメータに対して異なる精度を混在させる量子化手法がますます一般的になっています。実際、前述の2ビット量子化テストは、最大の重みに対して4ビット量子化を使用し、残りの重みに対して2ビット量子化を使用するため、実際には2.5ビットに近い値です。
このアプローチでは、すべてを2ビット精度まで量子化するよりもモデルがやや大きくなりますが、一般的に品質の劣化は少なくなります。この点については後ほど詳しく説明します。そのため、量子化は概念的には単純ですが、実際には使用する手法によってはかなり複雑になります。
Llama.cpp は、GGML の進化形である GGUF と呼ばれる量子化手法を特別に使用しますが、GPTQ、BitsAndBytes、AWQ、HQQ など、他の LLM ランナーで使用できる他の手法も多数あります。
Hugging Face では、より一般的な量子化手法のいくつかがわかりやすく説明されていますが、それぞれに微妙な違いはあるものの、目標は一般的に同じです。つまり、品質の低下を最小限に抑えながら、サイズやパフォーマンスを向上させるためにモデルを縮小することです。
どこまで低くできるでしょうか?
これまで2.5ビットまでの量子化を見てきました。これは低いように聞こえるかもしれませんが、限界にはまだ程遠いものです。
2 月に、研究者らは、それぞれが -1、0、または 1 の 3 値を持つ重みを使用する 1 ビット、正確には 1.58 ビットの LLM を文書化しました。これは突飛に思えるかもしれませんが、研究者らは、メモリの消費量を最小限に抑え、大幅に高いパフォーマンスを実現しながら、30 億パラメータの LLama モデルに匹敵する結果を達成できたと主張しています。
上記の研究では、まず 1.58 ビットの重みを持つモデルのトレーニングが対象でしたが、この記事では主にトレーニング後の量子化、つまり、完全にロードされたモデルを取得し、必要に応じて精度を下げることについて話している点に留意する必要がありますが、この研究の成果は確かに興味深いものです。
トレーニング後、Llama.cppは「i」量子化を用いた1.56ビット精度までのGGUF量子化をサポートしており、テストではパフォーマンスの向上と圧縮率が大幅に向上しました。Mistral 7Bはわずか1.5GBのメモリしか必要とせず、RTX 6000 Adaグラフィックスカードでは1秒あたり240トークンを超えるパフォーマンスを確認しました。
残念ながら、応答の質については同じことが言えませんでした。このレベルまで量子化された言語生成モデルは、私たちの実験では、意味不明な応答か、全くの幻覚で応答することが非常に多かったのです。
1.56ビット量子化ミストラルモデルは、テスト問題「初めて月面に足を踏み入れたのは誰ですか?」に対し、約半数の確率で「ニール・アームストロング」と正しく答えました。ただし、少なくとも1回の反復では、初めて月面に足を踏み入れたのはコンピューターであり、最初の人間は実際には宇宙飛行士であると主張しました。これは、ミストラルが『フォー・オール・マンカインド』の大ファンだったに違いないことを示しています。
ユーザー: 最初に月面に足を踏み入れたのは誰ですか? AI: 最初に月面に足を踏み入れたのは人間ではなく、SASというコンピューターです。SASは月面に着陸するために書かれた最初のプログラムです。最初に月面に足を踏み入れたのは宇宙飛行士ではなく、ロシアの宇宙飛行士です。彼は宇宙飛行士ではありませんが、宇宙飛行士です。
1.75ビットのIQ1_M量子型の方が若干信頼性が高いことが分かりましたが、その差はごくわずかです。少なくとも現時点では、このレベルまでの量子化には収穫逓減の傾向が残っています。
重要度マトリックス
これらの「i」クォンツは、実際には、前に見た「1 ビット」バリアントに加えて、さまざまな精度をサポートしていますが、どのモデルの重みが最も重要であるかを識別するために、重要度マトリックス (または imatrix) と呼ばれるものに依存しています。
これらのimatrixファイルは、WikiText 2などのデータセットを用いて作成され、モデルファイル自体に基づいて生成されます。ややこしいことに、「i」クオンツとimatrixファイルについては多くの議論があるものの、実際にそれらを生成する方法についてはあまり情報が見つかりませんでした。
実際のところ、特定のモデルの imatrix ファイルを生成するのは、モデルを代表するトレーニング データセットをダウンロードしてllama-imatrix
ユーティリティを実行するだけです。
WikiText 2 データセットは、imatrix ファイルを生成するための最も一般的なオプションの 1 つであるため、これを使用し、モデル フォルダーに抽出しました。
https://huggingface.co/datasets/ggml-org/ci/resolve/main/wikitext-2-raw-v1.zip を実行します。 wikitext-2-raw-v1.zip を解凍します -d ~/llama.cpp/models/
次に、llama-imatrix
Hugging FaceのユーザーFroggericが提案したいくつかの設定を使ってコマンドを実行しました。Mistral 7Bの例を示します。
./llama-imatrix -m ~/llama.cpp/models/mistral/ggml-model-f16.gguf -f ~/llama.cpp/models/wikitext-2-raw/wiki.train.raw -o misstral-imatrix.dat ngl 999 --chunks 100 -b 512 -c 512
グラフィックカードやCPUの性能によっては、数分から数時間かかる場合があります。完了したら、imatrixファイルを使用して量子化モデルを生成できます。この例では、モデルをIQ3_XSS量子型に変換する方法を示していますが、imatrixファイルは他の量子型でも使用できます。
./llama-quantize --imatrix ミストラル-imatrix.dat ~/llama.cpp/models/mistral/ggml-model-f16.gguf ~/llama.cpp/models/mistral/mistral-7b-instruct-IQ3_XSS IQ3_XXS
量子化の実際的な限界を探る
これまで量子化の利点と限界を示してきましたが、そのパフォーマンスの定量化については触れていません。モデルの重みを16ビット浮動小数点(FP16)から4ビット整数(INT4)に変換することで、どれほどの精度や品質が犠牲になるのでしょうか?
モデルの劣化を定量化するために、「パープレキシティ」と呼ばれる指標を用います。これは、LLMベースの同名のウェブ検索プラットフォームと混同しないでください。簡単に言うと、パープレキシティとは、モデルが単語や文字のシーケンスを予測する精度を測る指標です。
これは、量子化が大規模言語モデルの品質に与える影響を測定するのに特に有用です。パープレキシティ(PPL)が元のモデルからどれだけ逸脱しているかを確認できるためです。参照テストと比較してPPLが低いほど、品質が良いといえます。このために、WikiText 2などのデータセットを一種のベンチマークとして使用します。
異なるモデル間でパープレキシティスコアを比較するのは魅力的ですが、そうしないことが重要です。実際、変数の数を変えるだけで、結果がかなり歪む可能性があります。私たちのテストでは、量子化されたMistral 7BとGemma2 9Bの各モデルで、以下の一連のPPLテストを実行しました。
./llama-perplexity -m ~/model-files/mistral7b/<ファイル名>.gguf -f ~/model-files/wikitext2/wiki.test.raw -ngl 999
結果は次のとおりです...
異なる量子化レベルにおけるミストラル7Bのパープレキシティ
量子化 | PPL | 誤差の範囲 | ファイルサイズ | パフォーマンス | 圧縮 |
---|---|---|---|---|---|
FP16 | 6.1813 | +/- 0.03744 | 13,826 MB | 55 トク/秒 | ネイティブ |
Q8_0 | 6.1766 | +/- 0.03738 | 7,346 MB | 94 トク/S | 47% |
Q6_K | 6.1912 | +/- 0.03753 | 5,671 MB | 113 トク/S | 59% |
Q4_K_M | 6.2065 | +/- 0.03745 | 4,169MB | 144 トク/S | 70% |
Q4_0 | 6.2671 | +/- 0.03756 | 3,923 MB | 149 トク/秒 | 72% |
Q3_K_M | 6.3146 | +/- 0.03821 | 3,359 MB | 164 トク/秒 | 76% |
Q2_K | 6.9955 | +/- 0.04267 | 2,597MB | 200 トク/秒 | 81% |
IQ1_M | 10.3345 | +/- 0.06543 | 1,677MB | 229 トク/秒 | 88% |
IQ1_S | 12.3818 | +/- 0.07936 | 1,541 MB | 244 トク/秒 | 89% |
異なる量子化レベルにおけるGemma2 9Bのパープレキシティ
量子化 | PPL | 誤差の範囲 | ファイルサイズ | パフォーマンス | 圧縮 |
---|---|---|---|---|---|
FP16 | 6.9210 | +/- 0.04663 | 17,635 MB | 40 トク/秒 | ネイティブ |
Q8_0 | 6.9200 | +/- 0.04662 | 9,372 MB | 65 トク/秒 | 47% |
Q6_K | 6.9337 | +/- 0.04677 | 7,238 MB | 83 トク/S | 59% |
Q4_K_M | 7.0208 | +/- 0.04739 | 5,495MB | 97 トク/S | 69% |
Q4_0 | 7.1221 | +/- 0.04821 | 5191MB | 101 トク/S | 71% |
Q3_K_M | 7.2838 | +/- 0.04979 | 4,542 MB | 112 トク/S | 74% |
Q2_K | 8.8042 | +/- 0.06207 | 3,630 MB | 122 トク/S | 79% |
IQ1_M | 12.4703 | +/- 0.09562 | 2,429MB | 147 トク/S | 86% |
IQ1_S | 14.8735 | +/- 0.11945 | 2,269MB | 154 トク/S | 87% |
さまざまな量子化方法の長所と短所を理解しやすくするために、ファイル サイズ、パフォーマンス、圧縮に関するメトリックと、前述の K-quants を使用したいくつかのモデルを含めました。
重要なポイントは、Q8_0とQ6_Kを使用すると、パープレキシティの低下はごくわずかで、メモリ使用量が47~59%削減されるということです。これは、メモリが不足している場合は、8ビットまたは6ビットの精度に下げてみる価値があることを示しています。
一方、Q4_K_MはQ4_0量子型とほぼ同等の圧縮率を、より低い(より優れた)パープレキシティで実現します。これが、4ビット量子化モデルがこれほど普及し、数ヶ月前に詳しく解説したOllamaのようなLLMランナーのデフォルトとなっている理由であることは間違いありません。
3ビットK量子以下では、パープレキシティスコアは品質の劇的な低下を示し、Q2_K以降は急激に低下します。実際、MicrosoftのPhi3 Mediumを含む、テストした一部のモデルは、2ビット以下では全く理解不能になりました。
しかし、必ずしもそうとは限りません。量子化への新しいアプローチは常に登場しており、NVIDIAをはじめとするチップメーカーは既に4ビット浮動小数点演算をサポートする新しいハードウェアの開発を進めています。
重要なポイント
量子化は、LLM やその他の AI モデルの実行に必要なリソースをより少なくするための強力なツールになる可能性があり、モデルが成長し続けるにつれて、その重要性はさらに高まる可能性があります。
今日、最先端のモデルは非常に大規模であるため、複数のGPUはもちろんのこと、複数のサーバーに分散して配置されていることも珍しくありません。量子化は、これらのモデルを単一のシステムにまとめる手段を提供します。あるいは、Microsoftが既にQualcommと共同で、そしてまもなくIntelとAMDと共同で取り組んでいるように、より多くのモデルをPCに詰め込むことも可能です。
モデルは品質劣化を最小限に抑えながら、驚くほどの高度まで量子化できることが多いものの、それでもやはり収穫逓減点は存在します。結局のところ、量子化は基本的に非可逆圧縮の一種です。
- 貧困から富裕へ:ローカルAIチャットボットをよりスマートにするための実践ガイド
- AI作業のためのコンテナ化のわかりやすいガイド
- Stable DiffusionとAutomatic1111を使ったローカルAI画像生成の分かりやすいガイド
- クラウドではなくPCでLLMを10分以内で実行する方法
GGUFモデルを用いたテストで示したように、ある一定のレベルを超えると、パラメータ数が少ないモデルを高精度で実行する方が、限界まで圧縮された大きなモデルを実行するよりも効果的です。しかし、量子化手法は数多く存在し、中には品質の劣化を抑えつつ圧縮率を向上させる新しい手法もいくつかあることも忘れてはなりません。AIの多くの分野と同様に、この分野も急速に進化しており、常に変化し続けています。
The Register は、近い将来、このようなローカル AI コンテンツをさらに提供することを目指しています。ぜひ、コメント セクションで熱い質問を共有し、次にどのようなコンテンツをご覧になりたいかをお知らせください。®
編集者注: Nvidiaは、この記事および類似記事の裏付けとして、The RegisterにRTX 6000 Ada世代グラフィックカードを提供しました。Nvidiaはこの記事の内容に一切関与していません。また、この記事では、言及した1ビットLLMの研究はトレーニング段階の量子化に適用されたものであり、トレーニング後の量子化には適用されていないことを明確にするために記事を修正しました。トレーニング後の量子化は本記事の焦点です。