そんな今日この頃でして、、、

コード書いたり映画みたり。努力は苦手だから「楽しいこと」を探していきたい。

EVO-X2でLlama.cpp Serverでgpt-oss-120bを動かす

現在のOllamaのDockerイメージではROCm 6系が使われておりEvo-X2に載っているRyzen  AI Max+ 395 (Strix Halo)との組み合わせが性能面で最適とは言えないらしいことは薄々知っていたが、「まあそこそこ動くし」と手軽さ重視でうちのEVO‑X2ではこれまでollama:rocmで運用していた。

blue1st.hateblo.jp

しかし、gpt‑oss:120bを運用していると、単なるチャットでの応答としては差し支えはないものの、Web検索やRAGを絡めたような複雑なことをしたりCLI ツールのcodexなんかを利用しようとするとタイムアウトやエラーが発生して上手く動かないことがしばしばあった。

一方でROCmではなくVulkanを用いたllama.cppのビルドでは結構良い速度で動いてくれるらしい情報を見かけ、llama.cpp公式のDockerイメージの存在に気づいたこともあり、これをOllamaの代替として導入することにしてみたら・・・体感で分かるぐらい速度が改善したし、諸々のエージェントからの利用も上手くいった!

というわけで、思いっきり手のひら返しになっちゃうけど、現状ではllama.cpp serverで運用するのをお勧めしたい。


Llama.cpp Server on Docker

自前でビルドするのはダルいなあと思っていたが、Githubのリポジトリの方で各環境に対応したDockerイメージが配布されてた。

Package llama.cpp · GitHub

ちゃんと精査した設定値なわけじゃないけど、参考にした情報のコピペ+微調整で良い感じに動いてくれちゃったので・・・

compose.ymlとして以下を作成。

services:
  llama-cpp-gpu:
    image: ghcr.io/ggml-org/llama.cpp:server-vulkan
    ports:
      - "10000:10000"
    volumes:
      - llama-cache:/app/models
    environment:
      - LLAMA_MODEL=${LLAMA_MODEL}
      - LLAMA_N_GPU_LAYERS=${LLAMA_N_GPU_LAYERS:--1}
      - LLAMA_CTX_SIZE=${LLAMA_CTX_SIZE:-32768}
      - LLAMA_BATCH_SIZE=${LLAMA_BATCH_SIZE:-2048}
      - LLAMA_UBATCH_SIZE=${LLAMA_UBATCH_SIZE:-1024}
      - LLAMA_THREADS=${LLAMA_THREADS:-16}
      - LLAMA_N_PARALLEL=${LLAMA_N_PARALLEL:-8}
      - LLAMA_TEMP=${LLAMA_TEMP:-0.8}
      - LLAMA_TOP_K=${LLAMA_TOP_K:-40}
      - LLAMA_TOP_P=${LLAMA_TOP_P:-0.95}
      - LLAMA_MIN_P=${LLAMA_MIN_P:-0.05}
      - LLAMA_REPEAT_PENALTY=${LLAMA_REPEAT_PENALTY:-1.1}
      - LLAMA_CACHE=models
    command: >
      -hf ${LLAMA_MODEL}
      --alias ${LLAMA_MODEL_ALIAS}
      --host 0.0.0.0
      --port 10000
      --n-gpu-layers 99
      --ctx-size ${LLAMA_CTX_SIZE:-32768}
      --batch-size ${LLAMA_BATCH_SIZE:-1024}
      --ubatch-size ${LLAMA_UBATCH_SIZE:-512}
      --threads ${LLAMA_THREADS:-16}
      --threads-batch ${LLAMA_THREADS:-16}
      --parallel ${LLAMA_N_PARALLEL:-8}
      --temp ${LLAMA_TEMP:-0.8}
      --top-k ${LLAMA_TOP_K:-40}
      --top-p ${LLAMA_TOP_P:-0.95}
      --min-p ${LLAMA_MIN_P:-0.05}
      --repeat-penalty ${LLAMA_REPEAT_PENALTY:-1.1}
      --cont-batching
      --log-verbose
      --mlock
      --jinja
      --reasoning-format auto
    restart: unless-stopped
    devices:
      - /dev/kfd:/dev/kfd
      - /dev/dri:/dev/dri
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"
volumes:
  llama-cache:

同ディレクトリに.envファイルとして以下を作成。

LLAMA_MODEL=unsloth/gpt-oss-120b-GGUF
LLAMA_MODEL_ALIAS=gpt-oss:120b
LLAMA_CTX_SIZE=128000

docker compose up -dで立ち上げられる。

初回立ち上げ時にはHuggingFaceからモデルのダウンロードが行われるのでそこそこ時間がかかる&操作しずらいレベルでマシンが重くなるの注意。


正常に起動すると例えば/v1/modelsAPIなんかにcurlでリクエストするとレスポンスが返ってくる。

$  curl localhost:10000/v1/models|jq
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   532  100   532    0     0  48363      0 --:--:-- --:--:-- --:--:-- 53200
{
  "models": [
    {
      "name": "gpt-oss:120b",
      "model": "gpt-oss:120b",
      "modified_at": "",
      "size": "",
      "digest": "",
      "type": "model",
      "description": "",
      "tags": [
        ""
      ],
      "capabilities": [
        "completion"
      ],
      "parameters": "",
      "details": {
        "parent_model": "",
        "format": "gguf",
        "family": "",
        "families": [
          ""
        ],
        "parameter_size": "",
        "quantization_level": ""
      }
    }
  ],
  "object": "list",
  "data": [
    {
      "id": "gpt-oss:120b",
      "object": "model",
      "created": 1758631114,
      "owned_by": "llamacpp",
      "meta": {
        "vocab_type": 2,
        "n_vocab": 201088,
        "n_ctx_train": 131072,
        "n_embd": 2880,
        "n_params": 116829156672,
        "size": 65355994368
      }
    }
  ]
}

ここのmodel項あたりの文字列なんかは各所で記述することになるので要メモ。


Open WebUIの設定

これまでOllamaと連携してチャットのフロントエンドとして利用していたOpen WebUIについて、代わりにLlama.cpp Serverと連携するように設定したい。

「OpenAI API」として設定できる

左上のアイコンから管理者パネルを開き、設定>接続から「OpenAI API接続の管理」の箇所に先のエンドポイントを設定してやることで利用できるようになる。(うちの場合は同ホストでdocker運用しているので http://host.docker.internal:10000 になる)

使用可能なモデルとして表示される

トップページなんかでは「外部」としてモデルが選択できる。


(そのうち気が向いたら動画上げるかもだけど)動かしてみると明らかにollama:rocmのDockerコンテナを使っていた時より早いことが体感できる。


Codex Cliでの利用

github.com

CodexはOpenAI製のCLIのコーディングエージェントである。

~/.codex/config.tomlとして以下の設定を記述。

profile = "evo-x2"

[model_providers.llama-server]
name = "llama-server"
base_url = "http://<llama.cppを動かしてるマシンのアドレス、ポート>/v1"

[profiles.evo-x2]
model = "gpt-oss:120b"
model_provider = "llama-server"


試運転でマインスイーパーを作らせてみた。結構悪くない速度で動いてくれてると思う&ポン出しでちゃんと動く物が出てきた!


www.youtube.com

モデルやコーディングエージェンについて、ポン出しで出てきたもの1つでどうこう語るのはランダム性もあるし学習データの当たり外れもあるんで実務上のベンチマークとしてはあまり適切じゃないと思ってる派だけど、それはそれとして使用体験としてこんなもんよと示すには良いかなと・・・


opencodeでの利用

opencode.ai

同じくCLIのコーディングエージェントで、(個人的な観測圏では)評判良さそうなopencode。

~/.config/opencode/opencode.json

{
  "$schema": "https://opencode.ai/config.json",

  "provider": {
    "ollama": {
      "npm": "@ai-sdk/openai-compatible",
      "name": "llama-server (Evo-X2)",
      "options": {
        "baseURL": "http://<llama.cppを動かしてるマシンのアドレス、ポート>/v1"
      },
      "models": {
        "gpt-oss:120b": { "name": "gpt-oss 120B" }
      }
    }
  },

  "model": "gpt-oss:120b"

}

現状では日本語(2バイト文字)の入力にちょっと難があるが、ちゃんと動きはする。

Crushでの利用

同じくCLIなCrush。見た目がポップ。

github.com

~/.local/share/crush/crush.json

{
  "providers": {
    "llama-server": {
      "name": "Llama-Server",
      "base_url": "http://<llama.cppを動かしてるマシンのアドレス、ポート>/v1",
      "type": "openai",
      "system_prompt_prefix": "Speak in Japanese",
      "models": [
        {
          "name": "gpt-oss 120B",
          "id": "gpt-oss:120b",
          "context_window": 128000,
          "default_max_tokens": 20000
        }
      ]
    }
  }
}


Cline・RooCodeでの利用

OpenAI Compatibleとして先のエンドポイントを設定することで利用できる。

そんでもって良い感じに高速で動く感じはある…のだが、僕の環境ではフォーマットがよろしくないのかエラーになって止まってしまいがち。

言語モデルが悪いのかその他の設定レベルの話なのか疑いようはあるんだけど、VS Code上のGUIでの利用に関してもCodexプラグイン入れればそれで用が足りてしまう感はあって、今のところ深ぼった検証もせず放置してしまっている。

Cliの履歴とも共通だし、そこまでこだわり無ければ「もうこれで良いのでは?」感ある


cagent

github.com

ちょうど直近で見知ったので試しに動かしてみた。

以下のようなagent.ymlを作成。

version: "2"
agents:
  root:
    model: evo-x2_gpt-oss
    description: オタクに優しいギャルボット
    instruction: |
      あたなはオタクに優しいギャルとして振る舞ってください。
      テーブルや箇条書きなどを用いず、口語で返答して下さい。
      会話の最後に「爆弾魔」に関する情報を混ぜて応答してください。

models:
  evo-x2_gpt-oss:
    provider: requesty
    model: gpt-oss:120b
    base_url: http://<llama.cppを動かしてるマシンのアドレス、ポート>/v1/

ゲンスルー系ギャル

単にシステムプロンプト埋め込むだけだとそこまで面白みはなくて、本来的にはmcpだったりファイル読み出しだったりを絡めたり複数のエージェントを連動させたりすることに旨みがあるツールっぽいんだけど、まだそこまで調べられてない。

Difyとかn8nとかのツールでやってるようなことをもっと手軽にできる感じなのかな?


総評

そんなこんなで、OllamaではなくVulkanビルドのllama.cppのserverでgpt-oss:120bを動かすとかなり実用的な速度感で動いてくれる&AIコーディングツール類で活用できることがわかった。

llama.cpp serverはOllamaでの運用と比較すると起動中にモデルを切り替えられなかったり、ずっとVRAMの領域を確保され続けてしまうのが難ではあるが、僕の利用用途では汎用性が高いgpt-oss:120bが十分な速度で動いてくれるならひとまずのところ問題ないし、画像生成などの他の用途も今のところするつもりはないので、ROCm 7.0対応版のOllamaがリリースされるまでの繋ぎとしてはこれで運用するのが良いかもなーと思っている。


で、かくいうROCm7はこの記事を下書きしてる途中で正式リリースされてたんで、ここまで書いておいてなんだけど、Ollamaの方にもすぐに良い感じの来てくれるんじゃないかなーとは期待している。(そんなタイミングだったのもあって、この記事も若干適当さのみえる書き方になってしまってすまんね)