現場でローカルLLMを回していると、「起動コマンドを一発で通すこと」より「壊さないこと」の方が先に効いてきます。私(クムビーバー)が社内検証基盤で最初に固定したのも、派手な最適化ではなく dry-run を既定にする ことでした。
この回の答え
起動前に生成される設定とコマンドを読む(空撃ち)を既定にします。設計する人と電源を入れる人を分け、明示許可のときだけ実起動します。
この回だけの用語
| 用語 | ひとことで |
|---|---|
| dry-run | Terraform の plan や apply 前の確認に近い。実害の前に設計を読む |
| builder | 設計図(Compose/コマンド)を作る側。副作用が少ない |
| executor | 電源を入れる側。GPU を占有する実起動・停止 |
| プロファイル | 「誰向け・どの設定で起動するか」の名前付きセット |
| healthcheck | 起動後に「生きているか」を見る検査。初回は長い |
たとえで言うと、dry-run は apply 前の plan です。起動前に生成 YAML を読む。電源は、見たあとで入れる。
ローカルLLMの検証基盤では、モデル起動が Docker Compose などの生成物に落ちることが多いです。便利な一方で、誤ったプロファイルをそのまま実行すると、ポート衝突、メモリ圧迫、キャッシュ汚染が起きます。GPU マシンは共有されやすく、復旧コストも高い。だから実害のある操作は、明示的に許可したときだけ実行する設計にします。
ポイント
実起動の前に、生成される Compose / CLI を目視確認するのを既定にします。
builder と executor を分ける
設計の要点は単純です。
- builder(設計図を作る人): 設定から起動定義(Compose やコマンド列)を生成する。副作用が少ない
- executor(電源を入れる人): 生成物を使って実際に起動・停止する。副作用がある
人間の確認ポイントは builder の出力です。ポート、GPU メモリ枠、モデル参照、環境変数の渡し方が意図どおりかを見てから executor に進みます。
この分離には副次効果もあります。比較対象の vLLM / TensorRT-LLM / SGLang / Atlas を、同じ「生成 → 確認 → 実行 → 計測」の型に載せられることです(比較表に載る=本番採用ではありません。採用は別判断)。ランタイムが違っても、評価軸と運用モデルを揃えやすくなります。実装者ごとに「自分のシェル履歴が正」になると、チームの再現性が一気に崩れます。
| 役割 | やること | やってはいけないこと |
|---|---|---|
| builder | YAML/プロファイルから起動定義を生成 | GPU 上でプロセスを起動する |
| レビュー | 生成物の差分を読む | 「たぶん大丈夫」で up する |
| executor | 明示許可後に起動・停止 | 未確認の生成物を常駐させる |
dry-run で見るチェックリスト
実起動前に、少なくとも次を確認します。
- 使っているプロファイル名は正しいか
- 公開ポートが既存サービスと被っていないか
- GPU メモリ利用率や KV キャッシュ設定が想定内か
- コンテキスト長が用途(コーディング、長文、ツール呼び出し)に合っているか
- モデル ID / 量子化方式が意図した候補か
- healthcheck の開始待ち時間は十分か(初回起動は長い)
- 失敗時に戻れるか(前の安定プロファイルが残っているか)
- volume マウント先が共有キャッシュを壊さないか
- restart ポリシーが検証意図(常駐 / 使い捨て)と一致するか
- 生成コマンド列に秘密情報やホスト固有パスが混入していないか
この確認がないまま「とりあえず up」すると、検証そのものより環境復旧に時間を取られます。dry-run は面倒な儀式ではなく、復旧コストの前払いです。
よくある落とし穴
現場で繰り返し見る失敗を、予防策とセットで残します。
| 落とし穴 | 症状 | 予防 |
|---|---|---|
| プロファイル取り違え | 意図しないモデルが起動 | dry-run 出力の先頭に profile 名を出す |
| ポート衝突 | bind 失敗 / 古いサービスに到達 | プロファイルごとにポートを明示 |
| healthcheck 過短 | ずっと unhealthy | start_period を初回ロード前提で延ばす |
| メモリ枠の見積もり甘い | OOM や他用途の圧迫 | gpu_memory_utilization を用途別に固定 |
| キャッシュ汚染 | 再現不能な速度差 | volume 方針を先に決める |
「起動できた」は成功条件の半分です。誰の検証を壊していないか、まで含めて成功とします。
小さなチームほど効く理由
少人数では、インフラ専任が常に張り付いているとは限りません。dry-run は個人の注意力に依存しすぎないための手順です。
- レビューしやすい(生成 YAML を見て議論できる)
- 再現しやすい(同じプロファイルから同じ定義が生まれる)
- 教育しやすい(新メンバーが「何が起動されるか」を先に読める)
- テストしやすい(GPU が無い開発機でも生成物の忠実性を検証できる)
- 切り分けやすい(生成ミスと実行時障害を分離できる)
特に最後が重要です。Compose 生成が間違っているのにモデル性能を疑い始めると、スパイラルが空転します。
実務への落とし込み
社内検証では、起動・ビルドの既定を dry-run にし、実行は明示フラグで許可する運用にしています。ワンコマンドで「確認 → 起動 → 計測 → 評価 → レポート」まで回す場合も、途中で定義を目視できる余白を残します。
また、生成物には restart ポリシーと healthcheck を必ず含める方針です。常駐サービスとして複数人同時利用に晒される前提なら、単発プロセス感覚の起動は危険です。健康確認が無い常駐は、障害検知が人間の体感依存になります。
PR やレビューでは、次の3点だけでも見てください。
- dry-run 出力が意図したプロファイルか
- 変更軸が1つか(複数変更の同時投入になっていないか)
- 失敗時の戻し先(直前の stable プロファイル)が残っているか
つまずいたこと
本番相当の起動コマンドを、確認なしに流して GPU を占有し切ったことがあります。意図は「すぐ試したい」だけでした。結果、他チームの検証枠を潰し、ロールバック手順も残っていませんでした。
dry-run を義務化したあとも、見た目が正しそうなコマンドが実は古いプロファイルを指している事故が続きました。苦労の本体はツール不足ではなく、「確認したつもり」を仕組みで無効化することでした。
この回の要点
- 本番相当コマンドの前に dry-run を挟む
- 正しそうな見た目より、指しているプロファイルを確認する
- 確認したつもりを、仕組みで無効化する
dry-run は起動事故を減らす型であり、スループットの証拠ではありません。実機ベンチの数字は別途、再計測と匿名化が済んだものから載せます。
次は「起動設定ファイルの読み方:Gemma4を例に」です。dry-run で見た最終コマンドを手元に置きながら読むと、ノブの意味が噛み合います。
よくある質問
dry-run とは何ですか?
実害のある起動の前に、生成される Compose やコマンドを目視確認する手順です。既定は確認のみ、実行は明示許可です。
builder と executor は何が違いますか?
builder は設計図(起動定義)を作る側、executor は実際に電源を入れる側です。確認ポイントは builder の出力です。