【llama.cpp】補助モデルやFastAttentionは高速化の効果があるのか
はじめに
この記事では、Georgi GerganovさんのXに投稿されたllama.cppの推論速度の高速化手法を試し、その結果をまとめたものです。
背景
Georgi GerganovさんのXにて、llama.cppを補助モデルを使って高速化する方法が紹介されました。
Georgi Gerganovさんのポスト
スクショのみで細かい説明はありませんでしたが、以下の2点が高速化に寄与するということのようです。
- 補助モデルに1.5Bモデルを用いる
- FastAttention(FA)を利用する
この記事では、それぞれの機能を使った場合と使わなかった場合の動作速度、アウトプットの差を評価しています。
忙しい人向けのまとめ
結論としてはどちらも有効です。
とりあえずfastAttentionは有効にしておいて、小さいモデルが用意できるなら補助モデル使うのはアリだと思います。
- 補助モデルはメインモデルの大きさによるが7%高速化。
- FastAttentionは10%程度高速化。アウトプットの劣化も見られない。
補助モデルの使い方
起動時のコマンドで補助モデルを指定します。
以下のコードのように-mdで補助モデルを指定し、--draft-minで補助モデルが 最低限適用されるトークン数を指定します。
./build/bin/llama-server \
-m models/DeepSeek-R1-Distill-Qwen-14B-Q6_K-00001-of-00002.gguf \
-md models/DeepSeek-R1-Distill-Qwen-1.5B-Q8_0-00001-of-00001.gguf \
--draft-min 2 \
--port 8080 \
-fa
FastAttentionの使い方
起動時のコマンドで-faを指定します。これはGPU利用時の時しか効果が出ないようです。
./build/bin/llama-server \
-m models/DeepSeek-R1-Distill-Qwen-14B-Q6_K-00001-of-00002.gguf \
--port 8080 \
-fa
検証方法
検証にはM1Pro32GBのローカルを使用しています。
モデルはDeepSeek-R1-Distill-Qwen-14B-gguf/Q6_Kをベースとし、
補助モデルにDeepSeek-R1-Distill-Qwen-1.5B-gguf/Q8_0を使用しています。
プロンプトは以下のものを使用しています。
英語で考え、日本語で回答してください。
pythonで50までの素数を出力するプログラムを書いてください。
コードとともにアルゴリズムも説明してください。
アウトプットの内容が変わると測定結果がずれるのでseed値を固定とし、1トークンの出力にかかった時間を調べています。
アウトプットの品質は「指示に従って英語で思考したか」「出てきたコードが適切か」の2点で評価しています。
測定結果まとめ
補助なし/FAなし
1トークンあたりの出力時間は0.113secでした。
この値を基準値としていきます。
seed | time_per_token | Content_think | Content |
---|---|---|---|
0 | 0.1119 | NG (中国語で思考) | 50までの素数を出力するプログラムを |
10 | 0.1131 | OK (英語で思考) | 以下に、50までの素数を出力するPython |
20 | 0.1155 | NG (日本語で思考) | 以下に、50までの素数を出力するPython |
30 | 0.1110 | OK (英語で思考) | 以下に、50までの素数を出力するPython |
40 | 0.1114 | OK (英語で思考) | 以下に、50までの素数を出力するPython |
50 | 0.1149 | OK (英語で思考) | 素数とは、1以外の数で、1と自身以外 |
出力のサンプル
補助あり/FAなし
1トークンあたりの出力時間は0.106secでした。
基準値よりも7%早くなっています。アウトプットの品質は特に変わりませんでした。
seed | time_per_token | Content_think | Content |
---|---|---|---|
0 | 0.1098 | NG (中国語で思考) | 素数の定義素数(そすう)と |
10 | 0.1051 | OK (英語で思考) | 以下に、50までの素数を出力するPython |
20 | 0.1145 | NG (日本語で思考) | 以下に、50までの素数を出力するPython |
30 | 0.1053 | OK (英語で思考) | 以下に、50までの素数を出力するPython |
40 | 0.1059 | OK (英語で思考) | 以下に、50までの素数を出力するPython |
50 | 0.0968 | OK (英語で思考) | 素数とは、1以外の数で、1と自身以外 |
補助あり/FAあり
1トークンあたりの出力時間は0.095secでした。
基準値よりも16%早くなっています。アウトプットは内容が少し変わっていますが、品質に特に変わりはないといった感触です。
補助あり/FAなしと比較すると10%程度の改善です。
seed | time_per_token | Content_think | Content |
---|---|---|---|
0 | 0.0976 | NG (中国語で思考) | 素数の定義素数(そすう)と |
10 | 0.0930 | OK (英語で思考) | 以下に、50までの素数を出力するPython |
20 | 0.1061 | NG (日本語で思考) | 以下に、50までの素数を出力するPython |
30 | 0.0927 | OK (英語で思考) | 素数生成プログラム以下の |
40 | 0.0899 | OK (英語で思考) | 以下に、50までの素数を出力するPython |
50 | 0.0894 | OK (英語で思考) | 素数とは、1よりも大きい自然数で、1 |
参考:14B-Q4_K_Mをベースに変えてみた
ベースモデルをもう少し小さいものに変えてみました。
こちらは結果はほんの少しだけしか変わらず、誤差レベルといった感じです。
補助なし/FAなし
1トークンあたりの出力時間は0.0793sec
seed | time_per_token | Content_think | Content |
---|---|---|---|
0 | 0.0789 | NG (中国語で思考) | 以下は、Pythonで50までの素数 |
10 | 0.0817 | OK (英語で思考) | プログラムを作成し、50までの素数を |
20 | 0.0796 | NG (日本語で思考) | 解答50までの素数を出力 |
30 | 0.0824 | OK (英語で思考) | 以下に、50までの素数を出力するPython |
40 | 0.0768 | OK (英語で思考) | 素数を出力するPythonプ |
50 | 0.0765 | OK (英語で思考) | 以下に、50までの素数を出力するPython |
補助あり/FAなし
1トークンあたりの出力時間は0.0787sec
seed | time_per_token | Content_think | Content |
---|---|---|---|
0 | 0.0785 | NG (中国語で思考) | ソースコード```pyt |
10 | 0.0813 | OK (英語で思考) | 以下に、50までの素数を出力するPython |
20 | 0.0783 | NG (日本語で思考) | 解答50までの素数を出力 |
30 | 0.0769 | OK (英語で思考) | 素数判別アルゴリズムの説明 |
40 | 0.0800 | OK (英語で思考) | 以下に、50までの素数を出力するPython |
50 | 0.0775 | OK (英語で思考) | 以下に、50までの素数を出力するPython |
まとめ
いかがだったでしょうか?今回はllama.cppの高速化をテーマに補助モデルの利用とfastAttentionの利用を試してみました。
私のXではLLMに限らず、AIを活用した業務改善情報の発信をしております。Nvidiaが使えず置いていかれがちなMac環境の実装を中心に解説・発信していますので。ご興味のある方は是非フォローをお願いします。
Discussion