LemonadeをStrix Halo (EVO-X2) で動かしたらVulkanの共有メモリ漏れとROCmの安定性が見えた
前回の紹介記事でAMD公式のローカルAIサーバーLemonadeを取り上げた。HNのコメントや公式ドキュメントをベースに書いた記事だったが、自分のEVO-X2(Ryzen AI Max+ 395 / Radeon 8060S)で実際に動かしてみたので、その結果をまとめる。
検証環境
| 項目 | 値 |
|---|---|
| PC | GMKtec EVO-X2 |
| CPU/GPU | Ryzen AI Max+ 395 / Radeon 8060S (gfx1151) |
| メモリ | 64GB UMA |
| Lemonade | v10.0.1(内蔵llama.cpp b8460) |
| ドライバ | AMD Software 26.3.1 |
BIOS設定は検証項目によって32GB/32GBと48GB/16GBを切り替えた。この配分の意味と影響はVRAM配分の記事に詳しいが、Vulkanリグレッションの記事で書いたとおり、AMDドライバ26.3.1ではBIOS配分がパフォーマンスに直結する状態になっている。
ベースラインとして、llama-server b8183直叩きでのQwen3.5-35B-A3B Q6_K(26.55GB)の速度は前回計測済みで、ctx=65536 / q8_0 KVで53.6 t/s。
Lemonade経由のオーバーヘッド
まず一番気になる「Lemonadeを挟むと遅くなるのか」を確認した。
| 構成 | モデル | ctx | 速度 |
|---|---|---|---|
| Lemonade v10.0.1 (b8460) | Q4_K_XL (21.2GB) | 4096 | 57.9 t/s |
| llama-server b8183 直叩き | Q6_K (26.55GB) | 4096 | 53.7 t/s |
| llama-server b8183 直叩き | Q4_K_M (19.7GB) | 4096 | 54.9 t/s |
Lemonade経由のほうが速いが、これはモデルの量子化が異なるため直接比較はできない。lemonade pullで落ちてくるのはQ4_K_XL(21.2GB)固定で、手持ちの直叩きデータはQ6_K(26.55GB)。abliteratedモデルの選定で試したQ4_K_Mとも量子化方式が異なり、公平な比較にはならない。
Lemonadeの内部構成はこうなっている。
lemonade-router.exe(port 8000: Web UI、port 9000: APIプロキシ)llama-server(port 8001: 推論エンジン、b8460)
推論自体はllama-serverがやっていて、routerはプロキシに過ぎない。紹介記事で引用した開発者の「素のllama.cppと同等」は妥当だろう。オーバーヘッドはほぼゼロと見ていい。
カスタム引数も--llamacpp-argsで渡せる。
lemonade run Qwen3.5-35B-A3B-GGUF --ctx-size 65536 \
--llamacpp-args "--cache-type-k q8_0 --cache-type-v q8_0 --no-mmap --reasoning-budget 0"
ctx=65536 / q8_0 KVで63.5 t/s。直叩きの設定をそのまま持ち込める。
NPU Hybrid実行
紹介記事で「NPUはプリフィルのオフロードに使える」と書いたが、実際にHybridモデルを動かしてみた。
lemonade run Qwen3-8B-Hybridを実行すると、RyzenAI-Server v1.7.0(542MB)が自動ダウンロード・起動された。
| 項目 | 値 |
|---|---|
| バックエンド | ryzenai-llm (FastFlowLM) |
| モデル | Qwen3-8B(AWQ量子化 ONNX) |
| TTFT | 0.44秒 |
| 生成速度 | 24.0 t/s(300トークン) |
比較対象としてVulkanでの35Bモデルが57.9 t/sなので、NPU Hybridの8Bモデルはその半分以下。ただしTTFT 0.44秒は高速で、Vulkanでの大モデルのプリフィルが数秒かかることを考えると、小型モデルの低レイテンシ用途には明確に向いている。NPUはGPU VRAMを消費しないので、GPUで大きいLLMを動かしつつNPUで音声系の小型モデルを常駐させる分担が現実的だ。
なおQwen3.5-35B-A3BのHybrid版はリストになく、NPU対応は小型モデル(8B以下)限定だった。
Vulkan vs ROCm: 共有メモリ漏れの発見
ここが今回の検証で一番大きな発見だった。
48GB VRAM / 16GBシステムのBIOS設定で、Vulkan(mmap)とROCmを比較した。
| バックエンド | 速度 | 専用GPU | 共有メモリ | メインRAM残 |
|---|---|---|---|---|
| Vulkan (mmap) | 46 t/s | 16.1 GB | 7.1 GB | 0.8 GB |
| ROCm | 37.8 t/s | 21.6 GB | 3.3 GB | 6.7 GB |
Vulkanのほうが18%速いが、共有メモリに7.1GBも漏れている。Q4_K_XL(21GB)のうち約5GBがシステムRAM側に配置されてしまっていた。48/16でシステム16GBのうち7.5GBをGPU共有に取られると、OS+Parsec+Tailscaleの残りが0.8GB。実用的に危険な状態だ。
ROCmだと共有メモリ漏れが3.3GBに半減し、メインRAMに6.7GBの余裕ができる。速度は落ちるがメモリ健全性が段違いに良い。
この共有メモリ漏れはAMDドライバ26.3.1 + Vulkan固有の問題で、ROCmバックエンドでは発生しない。後述の画像生成(sd-cpp / ROCm)では共有メモリが0.9GBまで下がることも確認しており、Vulkanドライバのメモリ配置ロジックに問題がある。
4モデル同時起動
Lemonadeの最大の売りであるマルチモダリティ同時起動を試した。48/16 BIOS、ROCmバックエンドで4モデルを同時起動。
| モデル | バックエンド | ポート |
|---|---|---|
| Qwen3.5-35B-A3B Q4_K_XL | llama.cpp ROCm | 8001 |
| Whisper-Small | whisper.cpp + NPU | 8002 |
| Kokoro-v1 TTS | kokoro (ONNX) | 8003 |
| Flux-2-Klein-4B | sd-cpp ROCm | 8004 |
| 項目 | 値 |
|---|---|
| 専用GPU | 37.6 GB / 48 GB(残り10.4 GB) |
| 共有GPU | 3.4 GB |
| メインRAM | 67%(残り約5.3 GB) |
| LLM速度 | 37.7 t/s |
VRAM 10GB余り、メインRAM 5GB余り。4モデル同時でもLLM速度が単体時(37.8 t/s)からほぼ低下していない。Whisper + Kokoroは計+0.3GBしか食わないので影響が軽微。
LLM + 画像生成 + 音声認識 + 音声合成を1つのサーバーで同時に動かせるのは、紹介記事で書いた「Ollamaとの最大の差別化ポイント」を実感できる結果だった。OllamaがMLXバックエンドに移行してApple Silicon側が整理されつつある一方、AMD側はこういう統合レイヤーが必要な段階にある。
mmapとBIOS配分のトレードオフ
4モデル同時起動にはmmap(デフォルト)が必須だった。--no-mmapだとロード時にファイル全体をシステムRAMに読み込むため、48/16の16GBでは溢れてctx=65536のロードが失敗する。mmapはページ単位の読み込みなのでピークメモリが抑えられる。
ただしmmapには速度ペナルティがある。
| 構成 | ctx | 速度 |
|---|---|---|
| 32/32, —no-mmap, Q6_K | 65536 | 53.6 t/s |
| 48/16, mmap, Q4_K_XL | 65536 | 46.3 t/s |
| 48/16, —no-mmap, Q4_K_XL | 4096 | 57.8 t/s |
mmapだと46 t/sで、—no-mmapの57 t/sより遅い。UMA上での共有メモリアクセスパターンの違いが効いている可能性がある。
| BIOS | 向いている用途 | 制約 |
|---|---|---|
| 48/16 | マルチモダリティ同時起動 | ctx=65536はmmap必須(速度低下)、—no-mmapだとctx=4096限定 |
| 32/32 | LLM単体の長コンテキスト | VRAM余裕が少なくマルチモダリティは厳しい |
画像生成: Flux-2-Klein-4B
LLM/Whisper/Kokoroを全停止後、Flux Klein 4Bを単体で起動した。
| 項目 | 値 |
|---|---|
| バックエンド | sd-cpp (ROCm)、Vulkanではなく自動選択 |
| モデルサイズ | 15.4 GB(text encoder 7.7GB + diffusion 7.4GB + VAE 0.3GB) |
| GPU専用 | 16.8 GB |
| 共有メモリ | 0.9 GB |
| 生成時間 | 約2分(512x512、1枚) |
LLM(Vulkan)を外したら共有メモリが7.1GB→0.9GBに激減した。sd-cppのROCmバックエンドは正しく専用GPUメモリに載せている。共有メモリ漏れがVulkan + ドライバ26.3.1固有の問題であることの裏付けになった。
生成結果:


512x512でフォトリアル系もアニメ系も問題なく生成できた。ただし1枚あたり約2分かかる。RTX 4060 LaptopでComfyUIを回したときと比べても特段速いわけでもなく、画像生成の実用性としては「動くことは動く」という段階。バッチ生成やイテレーションを回す用途には厳しい。
ぶつかった壁
routerプロキシが機能しない
Lemonadeのrouterはlemonade-router.exeがport 9000でAPIプロキシを提供する設計だが、chat completionsリクエストに一切応答しなかった。
| エンドポイント | バインド | ローカル | Tailscale |
|---|---|---|---|
| router (9000) | 0.0.0.0 | 応答なし | 応答なし |
| llama-server (8001) | 127.0.0.1 | 動作 | アクセス不可 |
llama-server(8001)は127.0.0.1バインドなので外部からアクセスできず、router(9000)は応答しない。48/16のクリーン再起動後でも同じ症状で、前セッションのllama-serverとは無関係。router自体のバグだ。
Tailscale経由でAPIを公開する構成をすでに運用しているが、Lemonade単体ではこれが不可能。llama-server直叩き(--host 0.0.0.0)のほうが確実という結論になった。
recipesコマンドが500エラー
lemonade recipesは一貫して500エラー。ログを見ると原因が判明した。
Backend availability:
- NPU hardware: Yes
- System RAM: 64.0 GB (max model size: 51.2 GB)
GPUが検出されていない。NPUとRAMしかリストされず、Radeon 8060S(Vulkan GPU)がBackend availabilityに出ない。
Strix HaloはUMA APUでiGPUとして動作するため、Lemonadeのdiscrete GPU検出ロジックに引っかからないのだろう。推論自体はllama.cppが直接Vulkanデバイスを叩くので動くが、Lemonadeの管理レイヤーがGPUの存在を認識できていない状態。dGPU(RX 7900 XTXなど)なら問題ないはず。
48/16 BIOSに切り替えたらNPUすら検出されなくなり、状況がさらに悪化した。32/32ではNPU: Yesだったので、BIOS配分がバックエンド検出にも影響している。
pullでモデル量子化を選べない
lemonade pull Qwen3.5-35B-A3B-GGUFで落ちてくるのはQ4_K_XL固定。Q6_KやQ8_0を指定する手段がない。手持ちのGGUFを使いたい場合はカスタムパスを指定する必要があるが、その手順が明確にドキュメント化されていない。
VulkanとROCmどちらを選ぶか
最終的な比較をまとめる。
| Vulkan | ROCm | |
|---|---|---|
| LLM速度 | 46 t/s | 37.8 t/s |
| 共有メモリ漏れ | 7.1 GB | 3.3 GB |
| メインRAM残(4モデル時) | 危険(0.8 GB) | 5.3 GB |
| マルチモダリティ | メモリ限界 | 余裕 |
| 画像生成 | 未検証 | ROCm自動選択、正常動作 |
API運用+マルチモダリティならROCmが正解。速度は18%落ちるがメモリ健全性が段違いで、4モデル同時起動しても安定している。LLM単体の速度を最優先するならVulkan + 32/32 BIOS + llama-server直叩きのほうが速い。
Lemonadeは「全部入り」の手軽さに価値があるツールなので、マルチモダリティを活かすならROCm一択という結論になった。
v10.0.1時点ではGPU検出やrouterなどStrix Halo UMA固有の不具合が目立つが、4モデル同時起動がROCmで安定したのは収穫だった。