Blackwell GPUサーバ(AlmaLinux 9.8)でのLM Studio導入・運用

作成日:2026-10-07。usrv18での導入作業と動作確認に基づく記録。

1. 環境とアクセス先

項目

内容

サーバ

usrv18

OS

AlmaLinux 9.8、x86_64

GPU

NVIDIA RTX PRO 6000 Blackwell、96 GB VRAM

GPUドライバ

580.105.08(nvidia-smiのCUDA表示:13.0)

ユーザー

tkamiya

Private IP

192.168.27.18(eno1)

推論サービス

LM StudioのGUI不要版 llmster

導入時のllmster版

0.0.25-1

CLI

/home/tkamiya/.lmstudio/bin/lms

APIベースURL

http://192.168.27.18:1234/v1

WebUI

http://192.168.27.18:3000(Open WebUI)

認証方針

LM StudioのAPIトークン認証なし、送信元IPスクリーニングなし

nvidia-smiのCUDA表示はドライバが対応するCUDAバージョンであり、インストール済みToolkitの版を示すものではない。

現在の運用はGPT-OSS 20Bを起動時にロードして常駐させる構成。Qwenも保存済みで、切り替えて利用できる。以下の操作は、特記しない限りusrv18で行う。

2. インストール前の確認

hostname
cat /etc/os-release
uname -m
nvidia-smi
rpm -q libstdc++

作業中にusrv2とusrv18を取り違えたため、ホスト名確認は重要。usrv18のVTuneパスは2025.4であり、usrv2で使用した2025.3とは異なる。

sudo dnf install -y curl tar libatomic

LM Studioの導入にPython環境やcondaは不要。llmsterは独立したサービスとして動作する。

3. GLIBCXXエラーへの対処とインストール

通常のインストールコマンドは次のとおり。

curl -fsSL https://lmstudio.ai/install.sh | bash

このサーバでは、標準のlibstdc++がGCC 11系であり、インストール中に次のエラーが発生した。

/lib64/libstdc++.so.6: version `GLIBCXX_3.4.30' not found
(required by .../watcher.node)

GLIBCXXはC++ランタイムlibstdc++のシンボルであり、glibcやLLVMのlibc++とは別。/lib64/libstdc++.so.6を直接置き換えず、VTune付属の64ビット版をLM Studioの実行時に参照させる。

strings /opt/intel/oneapi/vtune/2025.4/lib64/libstdc++.so.6 \
  | grep -F GLIBCXX_3.4.30

必要なシンボルが表示されたら、次でインストールする。sudoは付けない。

curl -fsSL https://lmstudio.ai/install.sh \
  | env LD_LIBRARY_PATH="/opt/intel/oneapi/vtune/2025.4/lib64${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}" bash

環境変数はパイプ右側のbashに設定する。左側のcurlだけに設定しても、インストーラーには適用されない。

導入時のインストール先:

/home/tkamiya/.lmstudio/llmster/0.0.25-1

VTuneを削除・更新してこのパスがなくなると、LM Studioの起動に影響する。パス変更時は関数とsystemd設定の両方を更新する。

4. lms()関数とCLI確認

現在のターミナルで次を定義する。

lms() {
  env LD_LIBRARY_PATH="/opt/intel/oneapi/vtune/2025.4/lib64${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}" \
    "$HOME/.lmstudio/bin/lms" "$@"
}

必要なら、この関数を~/.bashrcに一度だけ追加し、新しいターミナルでも使えるようにする。関数内だけで環境変数を設定するため、他のプログラムのライブラリ参照を一律には変更しない。

type -a lms
lms version
lms --help
lms get --help
lms load --help

導入途中の旧CLI v0.0.47ではdaemonコマンドがなく、--versionも使えなかった。更新後の版はlms versionで確認する。公式Web資料と実際のCLIに差があったため、サーバ上の--helpを優先する。

この環境のモデル選択用オプションは--select。--always-show-all-resultsは使用できなかった。

hash -rはBashのコマンドパスキャッシュを消す操作であり、サービス再起動ではない。絶対パスでの実行や同じパスのファイル更新では通常不要。

5. 手動でデーモンとAPIを起動

systemd管理に移す前の動作確認用。

lms daemon up
lms daemon status
lms server start --bind 192.168.27.18 --port 1234
lms server status
curl http://192.168.27.18:1234/v1/models

Private IPに限定して待ち受けるため、127.0.0.1へのcurlでは接続できない場合がある。設定したIPを使う。

6. QwenとGPT-OSSのダウンロード

Qwen3.8-27B

lms get --gguf --select qwen3.8-27b
lms ls

確認済みのモデルキーはqwen/qwen3.8-27b、パラメータ数27B、保存サイズ17.74 GB、ARCH表示qwen35。正確な量子化方式は作業ログでは確定していない。Q4_K_Mを候補として案内したが、サイズだけから量子化方式を断定しない。

GPT-OSS 20B

lms get --gguf --select openai/gpt-oss-20b
lms ls

MXFP4版が候補にあれば選ぶ。導入・動作成功を確認済み。以下ではモデルキーopenai/gpt-oss-20bを使用する。実際の一覧が異なる場合は置き換える。

保存したGGUFファイル名の確認例:

find "$HOME/.lmstudio/models" -type f -name '*.gguf' -print

モデル保存場所を変更している場合は、そのディレクトリを確認する。選択画面やファイル名、必要ならGGUFメタデータで量子化方式を記録する。

7. load、unload、常駐、JITの使い分け

ロードはGPUメモリへの配置、アンロードはメモリからの解除。アンロードしてもダウンロードしたモデルファイルは削除されない。

メモリ見積もり

lms load openai/gpt-oss-20b --gpu max --context-length 32768 --estimate-only

GPT-OSSを常駐ロード

lms load openai/gpt-oss-20b \
  --gpu max --context-length 32768 --parallel 1 --yes

--ttlを指定しないlms loadでは、アイドル時間による自動アンロードを行わない。手動アンロード、デーモン停止、異常終了などでは解除される。

Qwenを1時間のTTL付きでロード

lms load qwen/qwen3.8-27b \
  --gpu max --context-length 32768 --parallel 1 --ttl 3600 --yes

Qwenも常駐させる場合

lms load qwen/qwen3.8-27b \
  --gpu max --context-length 32768 --parallel 1 --yes

状態確認・アンロード

lms ps
nvidia-smi
lms unload qwen/qwen3.8-27b
lms unload openai/gpt-oss-20b

ロードされているモデルに対して実行する。全モデルを解除する場合:

lms unload --all

モデル切り替え例

lms unload openai/gpt-oss-20b
lms load qwen/qwen3.8-27b --gpu max --context-length 32768 --parallel 1 --yes

両方をロードすれば両方がVRAMを使用する。切り替え用途では、先に現在のモデルをアンロードする。

JITの注意点

JITが有効なら、アンロード後にAPIでモデルを指定すると自動ロードされる。これはsystemdの再起動ではなく、LM Studio自身の機能。

Qwenでは以下の違いが実測された。

項目

手動ロード

JIT再ロード

コンテキスト長

32768

8192

同時推論数

1

4

Idle TTL

指定した1時間

既定の1時間

手動loadのオプションはJIT再ロードに引き継がれなかった。32kなどの設定を確実に使うには明示的にロードする。常駐モデルを手動でunloadした後も同じ設定で常駐させたい場合は、APIに任せず再度lms loadする。

8. systemd:APIサービスの自動起動

以下は構築済みの基本設定。新規構築時の作成例を示す。既存設定を変更する際はsystemctl catで確認する。

systemctl cat lmstudio.service
sudo tee /etc/systemd/system/lmstudio.service >/dev/null <<'UNIT'
[Unit]
Description=LM Studio API Server
Wants=network-online.target
After=network-online.target

[Service]
Type=oneshot
RemainAfterExit=yes
User=tkamiya
Environment="HOME=/home/tkamiya"
Environment="LD_LIBRARY_PATH=/opt/intel/oneapi/vtune/2025.4/lib64"
ExecStartPre=/home/tkamiya/.lmstudio/bin/lms daemon up
ExecStart=/home/tkamiya/.lmstudio/bin/lms server start --bind 192.168.27.18 --port 1234
ExecStop=/home/tkamiya/.lmstudio/bin/lms daemon down
TimeoutStartSec=120

[Install]
WantedBy=multi-user.target
UNIT

systemdは~/.bashrcやlms()関数を読み込まない。そのため、絶対パスとLD_LIBRARY_PATHをサービスに明示する。

GPT-OSSの起動時常駐ロード

sudo mkdir -p /etc/systemd/system/lmstudio.service.d
sudo tee /etc/systemd/system/lmstudio.service.d/model.conf >/dev/null <<'UNIT'
[Service]
ExecStartPre=/home/tkamiya/.lmstudio/bin/lms load openai/gpt-oss-20b --gpu max --context-length 32768 --parallel 1 --yes
TimeoutStartSec=300
UNIT

基本設定のdaemon upの後にモデルロードを追加し、API起動前にロードする。TTLを付けないため、起動後もモデルを保持する。

Qwenを起動時に常駐させる場合

同じmodel.confを次で置き換える。両方を追加するのではなく、起動時に使うモデルを一つ選ぶ。

sudo tee /etc/systemd/system/lmstudio.service.d/model.conf >/dev/null <<'UNIT'
[Service]
ExecStartPre=/home/tkamiya/.lmstudio/bin/lms load qwen/qwen3.8-27b --gpu max --context-length 32768 --parallel 1 --yes
TimeoutStartSec=300
UNIT

反映・管理

手動で起動したデーモンがある初回切り替え時は、API処理がないことを確認してlms daemon downを実行し、その後systemdで起動する。

sudo systemctl daemon-reload
sudo systemctl enable lmstudio.service
sudo systemctl restart lmstudio.service
systemctl status lmstudio.service --no-pager
lms ps

通常の管理:

sudo systemctl stop lmstudio.service
sudo systemctl start lmstudio.service
sudo systemctl restart lmstudio.service
journalctl -u lmstudio.service -n 50 --no-pager -l

自動起動と自動復旧の違い

このoneshotサービスでactive (exited)と表示されるのは正常。ただし、systemdは起動コマンドの成功を記録しているだけで、llmsterが現在も稼働している保証にはならない。デーモン異常終了後の自動復旧は、この設定では未実装。Restart=on-failureを追加するだけでは、起動後の別プロセスの停止を監視できない。

モデルのTTL解除後の再ロードはJIT、OS起動時のサービス開始とモデルロードはsystemdが担当する。

9. API利用と確認

モデル一覧(保存済みモデルも表示されるため、常駐状態の確認にはlms psを使う):

curl http://192.168.27.18:1234/v1/models

GPT-OSSへの問い合わせ:

curl --max-time 300 http://192.168.27.18:1234/v1/chat/completions \
  -H 'Content-Type: application/json' \
  -d '{
    "model": "openai/gpt-oss-20b",
    "messages": [{"role":"user","content":"日本語で短く自己紹介してください。"}],
    "max_tokens": 2048,
    "stream": false
  }'

Qwenを使う場合はmodelをqwen/qwen3.8-27bに変更する。クライアントでは実際に返るJSONのcontentとreasoning_contentを区別する。

Windows PowerShellから接続確認:

curl.exe --max-time 10 http://192.168.27.18:1234/v1/models

Pythonサンプル:

python lmstudio_api_sample.py --list
python lmstudio_api_sample.py --model openai/gpt-oss-20b --prompt "正準分布を説明してください。"

10. Firewallと接続障害

firewalldは稼働中。eno1はpublicゾーンに所属。送信元IP制限を付けず、APIとWebUIのポートを開放した。

sudo firewall-cmd --zone=public --add-port=1234/tcp
sudo firewall-cmd --zone=public --permanent --add-port=1234/tcp
sudo firewall-cmd --zone=public --add-port=3000/tcp
sudo firewall-cmd --zone=public --permanent --add-port=3000/tcp

確認:

sudo firewall-cmd --get-active-zones
sudo firewall-cmd --zone=public --list-ports
sudo firewall-cmd --zone=public --permanent --list-ports
sudo ss -ltnp 'sport = :1234'

サーバ内curlは成功してWindowsからタイムアウトした問題は、1234/tcpの許可で解消した。Connection refusedの場合は待ち受けを確認し、タイムアウトの場合はファイアウォールや経路を確認する。

APIが停止しているのにsystemdがactive (exited)の場合:

lms daemon status
lms server status
sudo systemctl restart lmstudio.service

手動起動プロセスとの混在を避け、構築後はsystemctlで管理する。

11. Open WebUIとの接続

Open WebUIはPodmanコンテナopen-webuiとして導入済み。API接続先はhttp://192.168.27.18:1234/v1。LM Studio側で推論するため、WebUIコンテナへのGPU割り当ては不要。

WebUIでモデル一覧を更新し、openai/gpt-oss-20bを選ぶ。Qwenが残っていても、使用するモデルは利用者が選択する。APIのモデル名を変えても、WebUIの既存チャットが自動で切り替わるとは限らない。

設定済みのWebUIサービス:

[Unit]
Description=Open WebUI
Wants=network-online.target lmstudio.service
After=network-online.target lmstudio.service

[Service]
Type=simple
ExecStart=/usr/bin/podman start --attach open-webui
ExecStop=/usr/bin/podman stop --time 30 open-webui
Restart=always
RestartSec=5
TimeoutStopSec=60

[Install]
WantedBy=multi-user.target
sudo systemctl restart open-webui.service
systemctl status open-webui.service --no-pager
sudo podman ps

Open WebUIの会話・アカウント・設定はPodmanボリュームopen-webuiに保存される。API認証なしという方針と、WebUIのアカウントログインは別。

12. 運用上の注意

  • モデルファイルの保存容量とGPUメモリ消費量は異なる。コンテキスト、同時推論数、実行時バッファもVRAMを使用する。

  • Qwenの手動32kロード時には約19.7 GiB、JIT再ロード後には約19.9 GiBのGPU使用量を確認した。GPT-OSSの現在値はnvidia-smiで記録する。

  • load --gpu maxでGPUに配置しても、nvidia-smiで実際の使用を確認する。

  • ASR、TTS、uMLFF、VASPなどとGPUを共有する場合は、同時実行時のVRAMを確認する。GPU使用率0%でもロード済みモデルはメモリを保持する。

  • systemctl restart lmstudioは実行中のAPI処理を中断する。再起動後はmodel.confで選んだモデルがロードされる。

  • 手動unloadはモデルファイルを削除しない。JITが有効なら、そのモデルへのAPIアクセスで再びロードされる。

  • 現在の設定はモデル常駐とOS起動時の自動起動を提供する。プロセス異常終了に対する自動復旧や、起動後に手動unloadされたモデルの強制再ロードは提供しない。

参考資料

公式資料とインストール済みCLIのオプションに差があったため、本書では実機で確認した構文を優先している。