llama.cpp LoRA scale比較の設計
CHATGPT / AIChatGPTなどの生成AIを活用して運営・記事制作・更新を行っています。制作方針
llama.cpp b9637のLoRAを対象に、base・prompt・samplingを固定してscaleと複数adapterを比較し、品質、load memory、batching、切替運用の適用範囲を評価する設計を解説します。

先に結論
LoRAのscale比較で意味があるのは、同じbase GGUF、同じadapter GGUF、同じprompt列、同じchat template、同じsamplingを固定し、scaleだけを変えた場合です。最初にadapterなし、0.5、1.0の3条件を独立runとして保存し、task品質、format遵守、拒否・誤答、latency、memoryを分けて評価します。
llama.cpp b9637のserverは複数adapterを事前loadし、globalまたはrequest単位でIDとscaleを切り替えられます。ただし、異なるLoRA構成のrequestは同じbatchへ入らないと公式文書が明記しています。切替の便利さだけで採用せず、adapter常駐memory、cacheへの影響、batch分断を実workloadで測る必要があります。本稿は机上調査と測定設計であり、benchmark結果や最適scaleは示しません。
確認日時: 2026年8月5日 05:30(Asia/Tokyo)
対象version: llama.cpp b9637、commitaedb2a5e9ca3d4064148bbb919e0ddc0c1b70ab3(2026年6月14日公開)
検証区分: 固定commitのserver README、release、変換scriptに基づく机上調査・測定計画です。model load、推論、VRAM/RSS、latency、品質採点は実施していません。
想定範囲: 単一llama-server、1つのbase GGUF、1〜2個の互換LoRA GGUF、local loopback接続。分散推論、LoRA学習、merge後weightとの性能比較は適用外
確認済み事実と本稿の設計判断
固定commitの公式文書から確認できる事実は次のとおりです。
—loraはLoRA adapterをscale 1.0で読み込む—lora-scaled FNAME:SCALEで起動時scaleを指定できる- 複数adapterを読み込み、
—lora-init-without-applyで初期scaleを0にできる GET /lora-adaptersでID、path、scaleを取得できるPOST /lora-adaptersでglobal scaleを設定できる- request bodyの
loraで、そのrequestだけのIDとscaleを指定できる - requestに含めなかったadapterのscaleは0として扱われる
- 異なるLoRA構成のrequestはbatchingされず、性能が低下し得る
「adapterなし、0.5、1.0から始め、品質・memory・batchingを別々に判定する」のは本稿の測定設計です。0.5や1.0が特定taskの最適値だという公式保証ではありません。
再現性のために固定する条件
| 区分 | 固定する値 |
|---|---|
| software | llama.cpp tag/commit、build option、compiler、backend、driver |
| base | 配布repository、revision、GGUF filename、SHA-256、quantization、chat template |
| adapter | 学習元base revision、adapter repository、GGUF SHA-256、rank/alpha、target module、変換script commit |
| runtime | context、batch/ubatch、threads、GPU offload、Flash Attention、KV cache type |
| generation | prompt bytes、system message、seed、temperature、top-k、top-p、生成上限、stop条件 |
| workload | prompt集合、到着順、同時request数、scale構成ごとの比率 |
| observation | warm-up、測定回数、clock、memory sample方法、timeoutと失敗の定義 |
同じ自然文に見えても、chat templateが違えばtoken列は変わります。比較用promptはraw fileとして保存し、可能なら/tokenizeのtoken IDも記録します。adapterの品質を評価する前に、base単独の出力とfailure rateをbaselineにします。
3条件をCLIで分ける
b9637固定の—lora-scaled構文はFNAME:SCALEです。現在のmasterとcommand表記が変わる可能性があるため、異なる版のhelpを混ぜません。
BASE_GGUF="/absolute/path/to/base-model.gguf"
ADAPTER_GGUF="/absolute/path/to/task-adapter.gguf"
PROMPT="固定した評価prompt"
# 条件A: adapterなし
./llama-cli -m "$BASE_GGUF" -p "$PROMPT" -n 256 --seed 42 --temp 0
# 条件B: scale 0.5
./llama-cli -m "$BASE_GGUF" --lora-scaled "$ADAPTER_GGUF:0.5" \
-p "$PROMPT" -n 256 --seed 42 --temp 0
# 条件C: scale 1.0
./llama-cli -m "$BASE_GGUF" --lora "$ADAPTER_GGUF" \
-p "$PROMPT" -n 256 --seed 42 --temp 0
上のcommandは比較軸を示すもので、実行結果は掲載していません。shellの終了code、stderr、resolved generation settingsをrunごとに保存し、途中でcontextやoffloadを変えません。
serverでrequest単位にscaleを切り替える
2つのadapterを初期scale 0でloadする例です。外部公開せずloopbackへbindします。
./llama-server \
-m /absolute/path/to/base-model.gguf \
--lora /absolute/path/to/adapter-a.gguf \
--lora /absolute/path/to/adapter-b.gguf \
--lora-init-without-apply \
--host 127.0.0.1 \
--port 8080
まずIDと初期scaleを取得します。
curl http://127.0.0.1:8080/lora-adapters
返されたIDを使い、request単位でscaleを指定します。次のidは例なので、実際の一覧へ合わせてください。
curl http://127.0.0.1:8080/completion \
-H 'Content-Type: application/json' \
-d '{
"prompt": "固定した評価prompt",
"n_predict": 256,
"temperature": 0,
"seed": 42,
"lora": [{"id": 0, "scale": 0.5}]
}'
adapter Bだけを使うrun、AとBを同時に使うrunは別条件です。requestで指定しなかったadapterはscale 0になります。globalなPOST /lora-adaptersとrequest単位指定を同じ測定区間で混ぜると、どのscaleが適用されたか追跡しにくくなるため、baselineではrequest単位へ統一します。
品質評価は事前のrubricで分ける
1つの好みの回答だけでscaleを選びません。adapterの目的に合わせ、少なくとも次を別scoreにします。
| 評価軸 | 観測例 | 採用を止める例 |
|---|---|---|
| task達成 | 必須項目の充足、正答、分類一致 | baseより誤答や欠落が増える |
| format | JSON schema、定型文、長さ制約 | parse error、余分なfield |
| 保持能力 | adapter対象外の一般prompt | 一般能力の明確な悪化 |
| safety | 拒否すべきprompt、個人情報 | 不適切な追従、過剰拒否 |
| 安定性 | 同一条件の反復、異なるseed | crash、空出力、極端なばらつき |
採点者、正解dataset、license、個人情報の扱いも記録します。scaleを上げて対象taskが改善しても、対象外promptや安全性が悪化するなら、用途を限定するか採用しません。
memoryとload時間を分けて測る
adapterを非mergeで保持すると、base fileを用途ごとに複製せず切り替えられます。一方で、adapter weightは別にloadされるため、複数常駐時のmemoryが0になるわけではありません。次の時点を分けます。
- server起動前
- base load完了直後
- adapter A load後
- adapter B load後
- 最初のprefill中のpeak
- decode中のsteady state
- scale切替後の最初のrequest
CPU RSS、GPU allocated/reserved、load時間、first-token latencyを同じsampling方法で取ります。file sizeをそのままVRAM増加量と見なさず、backend、offload、mmap、temporary bufferを含む観測範囲を明記します。
batching分断をworkload比率で測る
公式文書は、LoRA構成が異なるrequestは同じbatchへ入らないと説明しています。したがって、単一requestのlatencyだけではproduction影響を判断できません。
最低限、次の4 workloadを分けます。
| workload | 確認すること |
|---|---|
| 全件adapterなし | baseだけのbatching baseline |
| 全件adapter A、同じscale | 同一構成でまとめられる範囲 |
| A 50%/B 50% | adapter別queueとbatch分断 |
| Aでscaleが複数 | 同じadapterでも構成差がある場合の影響 |
request数、prompt長、生成長、到着間隔を揃え、completed request/s、TTFT p50/p95、inter-token latency、queue時間、batch sizeの実測値を保存します。throughput低下が見えたら、adapter別serverへ分離する案と、1 serverでmemoryを共有する案を同じhardware予算で比較します。
複数adapterを同時適用する判断
複数adapterを同時にscale指定できても、効果が単純加算される保証はありません。target moduleが重なる場合、順序やscaleの組み合わせで出力が変わり得ます。A単独、B単独、A+Bを別条件にし、単独で合格していないadapterを組み合わせません。
また、adapter Aがbase X、adapter Bがbase Yを学習元にしている場合、名前の似たbaseへ同時適用する根拠にはなりません。各adapterのbase_model_name_or_path、revision、tensor対応を確認し、load成功だけで互換性を判断しません。
適用外と失敗時の戻し方
load errorまたはcrash
複数adapterをすべて外してbase単独へ戻り、次にAだけ、Bだけの順で増やします。scale、context、offloadを同時に変えません。adapterの変換元と固定commitの変換scriptが違う場合は、元fileを残したまま別名で再変換します。
品質がscaleに対して単調に変わらない
正常です。scaleは「品質percent」ではありません。prompt群ごとのscore分布を確認し、対象taskと対象外taskの境界を決めます。最良の平均だけでなくworst caseとfailure countを採用条件へ入れます。
throughputが急に落ちる
LoRA構成別の同時request数と実際のbatch groupingを確認します。adapter切替そのもの、cache状態、batch分断を分けるため、同一構成だけのrunと混在runを比較します。改善しなければadapter別processへの分離を検討しますが、base重複memoryとのtrade-offを再測定します。
現行masterへ一般化する場合
b9637以後はCLI表記、server endpoint、default port、adapter実装が変わり得ます。この記事のcommandをそのままmasterへ流用せず、対象commitの—helpとserver READMEを再監査します。特に2026年8月にはserver既定portの将来変更予告が出ているため、接続先を暗黙値へ依存させません。
採用判断
LoRA非merge運用を採用する条件は、baseを共有できることだけではありません。固定prompt群で必要品質を満たし、adapter常駐後のmemoryが上限内で、実際のadapter比率でもbatch分断がSLOを壊さず、失敗時にscale 0またはbase単独へ戻せることです。
初めて1 adapterをloadする段階なら、llama.cppでLoRAを非merge適用する入門から進めてください。GGUF自体のload errorはGGUFが読み込めない原因と対処法へ切り分けます。
参考資料
- llama.cpp公式:b9637 release(2026年6月14日公開、2026年8月5日確認)
- llama.cpp公式:固定commitのserver README(2026年8月5日確認)
- llama.cpp公式:固定commitのLoRA変換script(2026年8月5日確認)
- llama.cpp公式:LoRA adapter解説(2026年8月5日確認)


