画像や文章を作る生成 AI のサービスがありますが、同じことが手元でもできるかを、余っていた GPU で技術検証しました。その中で、生成 AI のジョブを並べて GPU で回す仕組みを試しに組み、そこに llama.cpp の llama-server による文章の生成も足してみました。この仕組みでは GPU を使うジョブを常に1本ずつ回す決まりにしていたので、llama-server を常駐させるか、問い合わせのたびに起こして止めるかを決める必要がありました。

結論

  • llama-server は常駐させず、問い合わせ1回ごとに空いているポートで起こし、1回だけ問い合わせて止める形にしました。GPU を使うジョブを常に1本にするためで、文章の生成もほかのジョブと同じ GPU のジョブの1本として扱いました。
  • Qwen3.8-27B(Q4_K_M)の読み込みは約 13 秒で、この長さなら問い合わせのたびに起こしても足りると判断しました。
  • 起こして止める形でも、RAM の見積もりには注意が要ります。llama-server は GGUF を mmap するので、動いている間は GGUF の大きさの分がページキャッシュに載ります。この分は free では buff/cache に入り、メモリの空きを見てジョブを割り振る仕組みには「空き」に見えます。

試した環境

  • Radeon RX 7900 XT(gfx1100、VRAM 20 GB)
  • Ubuntu、ROCm 7.2.4
  • llama.cpp v0.6.0 を HIP でビルドした llama-server
  • モデル: Qwen3.8-27B(Q4_K_M、16.8 GB)、GPT-OSS Swallow 120B RL v0.1(MXFP4、61.3 GB)
1口のコンロで鍋を1つだけ火にかけ、ほかの鍋が台の上で順番を待っている台所

問い合わせごとに起こして止める

llama-server を常駐させると、その間は VRAM を持ったままになります(Qwen3.8-27B で文脈 32768 のとき 17.8 GB)。この検証では GPU を使うジョブを常に1本にすると決めていたので、文章の生成もほかのジョブと同じ GPU のジョブの1本として扱い、問い合わせ1回ごとに llama-server を起こして止める形にしました。

次の図は、文章生成のジョブ1本の中のやり取りです。

問い合わせ1回ごとに llama-server を起こして止める

  • 実行の道具は Python の標準ライブラリだけで書き、llama-server の OpenAI 互換の API に1回だけ問い合わせます。
  • 応答を結果のファイルとジョブの記録に書き出してから、llama-server を止めます。
  • サンプリングの値は、モデルカードの推奨をモデルごとの表として実行の道具の側に持ち、ジョブの依頼からは受け取りません。

Qwen3.8-27B の読み込みは約 13 秒で、1回の問い合わせの目安は 100 秒ほどです(試しに下書きを3回作ったときの平均)。読み込みが約 13 秒なら、問い合わせのたびに起こしても足りると判断しました。もう1つ試した GPT-OSS Swallow 120B は、ページキャッシュに載った後でも読み込みに 53 秒かかりました(Qwen3.8-27B の約 13 秒が、ページキャッシュに載った状態の値かどうかは確かめていません)。

止めた後に VRAM を見ると、llama-server が残っていないかを数字で確かめられます(Swallow 120B を手で起こして試した2回とも、止めた後に 27 MiB に戻りました)。

RAM を見積もるときの注意: mmap の分は「空き」に見える

問い合わせごとに起こして止める形でも、llama-server が動いている間のメモリの見え方には注意が要ります。llama-server は GGUF を mmap して読みます。そのため、動いている間は GGUF の大きさの分がページキャッシュに載ります。Swallow 120B では、GGUF(61.3 GB)とほぼ同じ量がページキャッシュに載り、RAM の大半を占めました。

ところが free で見ると、この分は buff/cache に数えられます。メモリの空きを見てジョブを割り振る仕組みからは、llama-server が読んでいる分が「空き」に見えてしまいます。メモリの空きの数字だけを見て次のジョブを割り振ると、llama-server が読んでいる GGUF の分を数え落とします。

確かめていないこと

  • 文章生成の1ジョブが RAM をどれだけ使うか
  • ページキャッシュに載っていない状態から読むときの、Qwen3.8-27B の読み込みの時間

おわりに

GPU を使うジョブを1本ずつ回すなら、Qwen3.8-27B のように読み込みが約 13 秒のモデルで、llama-server を常駐させず問い合わせごとに起こして止める形も選べます。そのときも、動いている間は mmap の分がページキャッシュに載るので、RAM の見積もりでは free の空きの数字だけを見ないようにしてください。

※ llama-server の振る舞いは執筆時点の情報で、いまは変わっている可能性があります。