以下の一連の投稿の第三弾です。
-
ASRock 4X4 BOX-8640U上のDebianでAMD iGPU(Radeon 760M)にLemonadeを動かすまで #Vulkan - Qiita
-
ASRock 4X4 BOX-8640U上のAMD iGPU(Radeon 760M )に Lemonadeを動かして、生成AIのローカル推論ベンチマーク #Vulkan - Qiita
-
ASRock 4X4 BOX-8640U上のProxmoxでLemonade Serverをsystemdデーモンとして常駐させる #Vulkan - Qiita
1. はじめに
LemonadeはAMDが支援するオープンソースのLLM推論サーバーです。OpenAI互換APIを提供し、Vulkan/ROCm/CPUバックエンドに対応しています。
前回の記事ではAMD iGPU(Radeon 760M)上でLemonadeをソースからビルドして .deb パッケージでインストールするところまでを紹介しました。今回は、そのLemonadeサーバーを systemd デーモンとして常駐化 し、OS起動時に自動起動する設定を行います。
Proxmox上で動かすと仮想環境とのメモリーの取り合いになります。利用の場合にはご注意ください。
1-1. 環境
| 項目 | 内容 |
|---|---|
| ホスト | ASRock 4X4 BOX-8640U |
| CPU | AMD Ryzen 5 8640U |
| iGPU | Radeon 760M (RDNA3 / gfx1103) |
| メモリ | DDR5-5600 96GB (48GB x2) |
| OS | Proxmox VE (Debian ベース) |
| Lemonade | v10.0.1 (.deb パッケージでインストール済み) |
| Vulkan | Mesa RADV / Vulkan 1.4 |
1-2. 前提条件
- Lemonadeが
.debパッケージからインストール済みであること - Vulkanが動作確認済みであること(
vulkaninfo --summaryでRadeonが認識される) - モデルが既にダウンロード済みであること
2. .debパッケージのsystemdサービス構成
.debパッケージでインストールすると、systemdサービスが自動的に登録されます。
systemctl cat lemonade-server
# /usr/lib/systemd/system/lemonade-server.service
[Unit]
Description=Lemonade Server
After=network-online.target
[Service]
Type=simple
User=lemonade
Group=lemonade
WorkingDirectory=/opt/var/lib/lemonade
EnvironmentFile=-/etc/lemonade/lemonade.conf
EnvironmentFile=-/etc/lemonade/conf.d/*.conf
ExecStart=/opt/bin/lemond
Restart=on-failure
RestartSec=5s
KillSignal=SIGINT
AmbientCapabilities=CAP_SYS_RESOURCE
# Security hardening
PrivateTmp=yes
NoNewPrivileges=yes
ProtectSystem=full
ProtectHome=yes
ReadWritePaths=/opt/var/lib/lemonade
RestrictRealtime=yes
RestrictNamespaces=yes
LockPersonality=yes
[Install]
WantedBy=multi-user.target
2-1. サービスファイルのポイント
-
実行ユーザー:
lemonade(専用のサービスユーザー) -
設定ファイル:
/etc/lemonade/lemonade.confと/etc/lemonade/conf.d/*.conf -
デーモン本体:
/opt/bin/lemond -
作業ディレクトリ:
/opt/var/lib/lemonade -
セキュリティ強化:
ProtectHome=yes,PrivateTmp=yes,NoNewPrivileges=yes等
2-2. デフォルト設定ファイル
/etc/lemonade/lemonade.conf にはビルド時のデフォルト値がコメントアウトされた状態で記載されています。主要な設定項目は以下の通りです:
#LEMONADE_HOST=localhost
#LEMONADE_PORT=8000
#LEMONADE_LOG_LEVEL=info
#LEMONADE_CTX_SIZE=4096
#LEMONADE_LLAMACPP=
#LEMONADE_LLAMACPP_ARGS=
#LEMONADE_MAX_LOADED_MODELS=1
カスタマイズは /etc/lemonade/conf.d/ 以下に個別ファイルとして配置します。パッケージアップデート時に設定が上書きされるリスクを回避できます。
3. セットアップ手順
3-1. lemonade サービスユーザーの作成
.deb インストール時にユーザーが自動作成されない場合は手動で作成します。
useradd -r -s /usr/sbin/nologin -d /opt/var/lib/lemonade -M lemonade
# GPU (Vulkan) アクセスに必要なグループを追加
usermod -aG video,render lemonade
# 確認
id lemonade
# uid=997(lemonade) gid=995(lemonade) groups=995(lemonade),44(video),104(render)
video と render グループにより、/dev/dri/renderD128 等の GPU デバイスにアクセスできるようになります。
3-2. 作業ディレクトリの準備
mkdir -p /opt/var/lib/lemonade
chown lemonade:lemonade /opt/var/lib/lemonade
3-3. モデルキャッシュの配置
Lemonade はデフォルトで ~/.cache/lemonade/ と ~/.cache/huggingface/ にキャッシュを保存します。手動テスト時に root ユーザーで実行していた場合、キャッシュは /root/.cache/ 以下にあります。
サービスは lemonade ユーザー(かつ ProtectHome=yes)で動作するため、/root/ 以下にはアクセスできません。キャッシュを lemonade ユーザーのディレクトリに移動します。
# キャッシュディレクトリを作成
mkdir -p /opt/var/lib/lemonade/.cache
# root のキャッシュを移動
mv /root/.cache/lemonade /opt/var/lib/lemonade/.cache/
mv /root/.cache/huggingface /opt/var/lib/lemonade/.cache/
# 所有権を変更
chown -R lemonade:lemonade /opt/var/lib/lemonade/
# 確認
du -sh /opt/var/lib/lemonade/.cache/*
# 137M /opt/var/lib/lemonade/.cache/lemonade
# 26G /opt/var/lib/lemonade/.cache/huggingface
注意: モデルファイルは大きい(Qwen3.5-27B で約 16GB)ので、ディスク容量に注意してください。
3-4. Vulkan バックエンドの設定
mkdir -p /etc/lemonade/conf.d
cat > /etc/lemonade/conf.d/vulkan.conf << 'EOF'
# Vulkan backend for Radeon 760M (RDNA3 / gfx1103)
LEMONADE_LLAMACPP=vulkan
LEMONADE_HOST=0.0.0.0
LEMONADE_CTX_SIZE=4096
# RADV performance tuning
RADV_PERFTEST=nogttspill
AMD_VULKAN_ICD=RADV
# Cache paths (lemonade ユーザーの HOME を設定)
HOME=/opt/var/lib/lemonade
EOF
各設定項目の説明:
| 設定 | 説明 |
|---|---|
LEMONADE_LLAMACPP=vulkan |
llama.cpp の Vulkan バックエンドを使用 |
LEMONADE_HOST=0.0.0.0 |
全インターフェースでリッスン(LiteLLM 等から接続する場合に必要) |
LEMONADE_CTX_SIZE=4096 |
コンテキストサイズ |
RADV_PERFTEST=nogttspill |
Mesa RADV の GTT スピル抑制。llama.cpp Vulkan での推奨設定 |
AMD_VULKAN_ICD=RADV |
AMD Vulkan ドライバとして RADV を明示指定 |
HOME=/opt/var/lib/lemonade |
~/.cache/ の参照先を lemonade ユーザーの作業ディレクトリに設定 |
3-5. サービスの有効化と起動
# 既存の手動プロセスが残っていれば停止
# (手動で lemond を起動していた場合)
pkill -f lemond
pkill -f llama-server
sleep 2
# systemd にリロード
systemctl daemon-reload
# サービスの有効化(OS起動時に自動起動)
systemctl enable lemonade-server
# 起動
systemctl start lemonade-server
4. 動作確認
4-1. サービス状態の確認
systemctl status lemonade-server
正常に起動していれば以下のように表示されます:
● lemonade-server.service - Lemonade Server
Loaded: loaded (/etc/systemd/system/lemonade-server.service; enabled; preset: enabled)
Active: active (running) since ...
Main PID: XXXXX (lemond)
4-2. ログの確認
journalctl -u lemonade-server --no-pager -n 20
[Info] (main) Starting Lemonade Server...
[Info] (main) Version: 10.0.1
[Info] (main) Port: 8000
[Info] (main) Host: 0.0.0.0
[Info] (main) Log level: info
[Info] (Server) Detected systemd environment - will use journald for log streaming
[Info] (Server) IPv4 HTTP server listening on 0.0.0.0:8000
Host: 0.0.0.0 と IPv4 HTTP server listening on 0.0.0.0:8000 が表示されていれば成功です。
4-3. API 動作確認
モデル一覧の取得:
curl -s http://localhost:8000/api/v1/models | python3 -m json.tool
{
"data": [
{
"id": "Qwen3-0.6B-GGUF",
"downloaded": true,
"recipe": "llamacpp",
"size": 0.38
},
{
"id": "Qwen3-8B-GGUF",
"downloaded": true,
"recipe": "llamacpp",
"size": 5.25
},
{
"id": "Qwen3.5-27B-GGUF",
"downloaded": true,
"recipe": "llamacpp",
"size": 16.7
}
]
}
4-4. 推論テスト
curl -s http://localhost:8000/api/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "Qwen3-0.6B-GGUF",
"messages": [{"role": "user", "content": "Hello, are you working?"}]
}' | python3 -m json.tool
5. サービス管理コマンド
# 状態確認
systemctl status lemonade-server
# 再起動
systemctl restart lemonade-server
# 停止
systemctl stop lemonade-server
# ログのリアルタイム追跡
journalctl -u lemonade-server -f
# 自動起動の無効化
systemctl disable lemonade-server
6. トラブルシューティング
6-1. ポートが既に使用されている
[Error] (Server) Failed to bind IPv4 HTTP server to 0.0.0.0:8000
[Server] Another Lemonade router/server instance is already running on localhost:8000.
手動で起動した lemond プロセスが残っている場合に発生します。
# ポートを占有しているプロセスを確認
ss -tlnp | grep 8000
# 該当プロセスを停止
kill <PID>
# 応答しない場合は強制終了
kill -9 <PID>
# llama-server の孤児プロセスも確認
ps aux | grep llama-server | grep -v grep
lemond を kill しても、子プロセスの llama-server がゾンビとして残る場合があります。kill -9 で強制終了してください。
6-2. モデルが認識されない(data が空)
{"data": [], "object": "list"}
lemonade ユーザーからモデルキャッシュにアクセスできない場合に発生します。
確認すべき点:
-
/opt/var/lib/lemonade/.cache/huggingface/にモデルが存在するか - ファイルの所有者が
lemonade:lemonadeになっているか -
vulkan.confにHOME=/opt/var/lib/lemonadeが設定されているか
ls -la /opt/var/lib/lemonade/.cache/huggingface/hub/
# models--unsloth--Qwen3-xxx が表示されれば OK
# 所有権の修正
chown -R lemonade:lemonade /opt/var/lib/lemonade/.cache/
6-3. GPU デバイスにアクセスできない
lemonade ユーザーが video / render グループに所属していることを確認してください。
id lemonade
# groups に video, render が含まれていること
ls -la /dev/dri/
# renderD128 が render グループに属していること
7. ディレクトリ構成まとめ
/opt/bin/lemond # デーモン本体
/etc/lemonade/lemonade.conf # デフォルト設定(パッケージ提供)
/etc/lemonade/conf.d/vulkan.conf # カスタム設定(Vulkan + RADV)
/opt/var/lib/lemonade/ # 作業ディレクトリ
/opt/var/lib/lemonade/.cache/lemonade/ # Lemonade キャッシュ(バイナリ等)
/opt/var/lib/lemonade/.cache/huggingface/ # HuggingFace モデルキャッシュ
/usr/lib/systemd/system/lemonade-server.service # systemd ユニットファイル
8. まとめ
Lemonadeの.debパッケージには、よく設計されたsystemdサービスファイルが含まれています。専用ユーザーの作成、Vulkan設定のconf.d/配置、モデルキャッシュの移動という3つのステップで、セキュアかつ安定したデーモン運用が可能になります。
RADV_PERFTEST=nogttspillとLEMONADE_HOST=0.0.0.0の設定により、Radeon 760M の iGPU でパフォーマンスを最大限活かしつつ、LiteLLM Proxy等の外部サービスからもアクセスできる構成が実現できます。