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のオプションに差があったため、本書では実機で確認した構文を優先している。