LANのローカルマシン(NVIDIA DGX Spark / GB10)で動かす、画像ロースト用のLLM推論APIサーバー。 LINEなどから送られた写真を 「① 客観描写(VLM) → ② なんJ風の毒舌コメント(LLM)」 の2段で処理して返す。
LINE(画像) ─▶ [別サーバー: webhook] ─▶ [Spark: POST /roast_b64]
├ Stage1 画像 → 客観描写
└ Stage2 描写 → なんJ毒舌コメント
─▶ comment ─▶ LINEへ返信
- 2段パイプライン。描写(事実ベース)と毒舌(人格)を分離し、それぞれ最適なモデルを使う。
- Stage1 の描写バックエンドを切替可能:ローカルVLM or クラウド(Groq・爆速)。
- Stage2 はローカルの日本語RPモデルで、なんJ語のノリを担当。
- コールドスタートなし:
keep_alive=-1+ 起動時ウォームアップでモデル常駐。 - プロンプトは外部ファイル化。個人カスタムはgit管理外。
| 役割 | 既定 | 備考 |
|---|---|---|
| 推論基盤 | Ollama (rootless) ~/.local/bin/ollama |
127.0.0.1:11434、GB10のGPUを使用 |
| Stage1 描写 | meta-llama/llama-4-scout (Groq) または huihui_ai/qwen3.5-abliterated:35b (ローカル) |
.env の DESCRIBE_BACKEND で切替 |
| Stage2 毒舌 | hf.co/Aratako/calm3-22b-RP-v3-GGUF:Q6_K (ローカル) |
日本語RP特化 |
| API | FastAPI + uvicorn (app.py) |
0.0.0.0:8080、Bearer認証 |
描写を Groq にすると1枚あたり描写が 約0.5〜1秒(ローカルVLMは約25秒)。コストは1枚 約0.03円で、無料枠(30,000 tok/分・14,400 req/日)で個人利用は十分。
- Linux + NVIDIA GPU(GB10想定。Blackwell対応のOllamaランナーが必要)
- Python 3.10+(venv)
- Ollama(rootlessで可) / 取得済みモデル
- (任意)Groq APIキー … 描写をクラウドに逃がす場合
# 1) 取得 & 仮想環境
git clone git@github.com:bucchiy/local-llm-server.git
cd local-llm-server
python3 -m venv .venv
./.venv/bin/pip install -r requirements.txt
# 2) Ollama(rootless)と毒舌モデル
curl -fsSL https://ollama.com/download/ollama-linux-arm64.tar.zst -o /tmp/o.tzst # ※環境に合わせて
# ... 展開して ~/.local/bin/ollama serve を起動 ...
ollama pull hf.co/Aratako/calm3-22b-RP-v3-GGUF:Q6_K
# ローカル描写も使うなら:
ollama pull huihui_ai/qwen3.5-abliterated:35b
# 3) 設定ファイル
cp .env.example .env
# ROAST_API_TOKEN を生成して記入: openssl rand -hex 24
# Groqを使うなら DESCRIBE_BACKEND=groq と GROQ_API_KEY=gsk_... を記入
# 4) プロンプト(雛形からコピー。個人カスタムは .txt 側を編集)
cp prompts/roast_system.example.txt prompts/roast_system.txt
cp prompts/describe_system.example.txt prompts/describe_system.txt
# 5) 起動
./roastbot.sh start./roastbot.sh start # 起動(フォアグラウンド。ollama未起動なら自動で起こす)
./roastbot.sh stop # 停止
./roastbot.sh restart # 再起動(プロンプト編集の反映など)
./roastbot.sh status # 稼働確認 + /health
./roastbot.sh logs # tail -f api.log
# バックグラウンド常駐(手軽版)
nohup ./roastbot.sh start > api.log 2>&1 &| メソッド/パス | 入力 | 用途 |
|---|---|---|
GET /health |
なし | 稼働確認(使用モデル/バックエンドを返す) |
POST /roast |
multipart image=画像ファイル |
テスト・webhook両用 |
POST /roast_b64 |
JSON {"image_b64": "..."} |
webhook用 |
認証: 全リクエストに Authorization: Bearer <ROAST_API_TOKEN>。レスポンスは {"description": ..., "comment": ...}。
TOKEN=$(grep ROAST_API_TOKEN .env | cut -d= -f2)
curl -s -X POST http://127.0.0.1:8080/roast \
-H "Authorization: Bearer $TOKEN" \
-F image=@/path/to/photo.jpg | python3 -m json.tool| キー | 説明 |
|---|---|
ROAST_API_TOKEN |
API認証トークン(必須。openssl rand -hex 24) |
DESCRIBE_BACKEND |
ollama(ローカルVLM) / groq(クラウド高速) |
GROQ_API_KEY |
Groq利用時のみ。未設定なら自動でローカルにフォールバック |
GROQ_DESCRIBE_MODEL |
既定 meta-llama/llama-4-scout-17b-16e-instruct |
DESCRIBE_MODEL |
ローカル描写モデル |
ROAST_MODEL |
毒舌モデル |
ROAST_MAX_IMAGE_SIDE |
送信前の画像縮小サイズ(既定1024px) |
OLLAMA_KEEP_ALIVE_REQ |
モデル常駐時間(既定 -1=無期限) |
システムプロンプトは prompts/ の外部ファイル:
prompts/roast_system.txt… 実使用ファイル(.gitignore対象。自由に編集してOK、コミットされない)prompts/roast_system.example.txt… リポジトリに含む綺麗な雛形.txtが無ければ.example.txtに自動フォールバック
毒舌の味付けは画像なしで高速イテレーションできる:
# prompts/roast_system.txt を編集 → サンプル説明文で出力確認(calm3だけ叩くので爆速)
./tune_roast.py # 各パターン2回
./tune_roast.py 3 # 各3回
# 気に入ったら反映:
./roastbot.sh restartwebhook_reference.py を公開HTTPSサーバーに置いて動かす(LINE Messaging API)。
役割は「LINEから画像取得 → Sparkの /roast_b64 呼び出し → 結果をpushで返信」。詳細はファイル冒頭のコメント参照。
公開のさせ方の例:webhook機をSparkと同じLANに置き Cloudflare Tunnel で公開HTTPS化(VPS・ポート開放不要)。
注意: LLMは応答に数秒かかるため、webhookは即200を返して裏で処理 → push送信の非同期設計にする(replyTokenの期限切れ・LINEのリトライを避ける)。
- APIは
0.0.0.0:8080、.envのBearerトークンで保護。 - Ollama本体(11434)は
127.0.0.1のまま(外部非公開)。 - ファイアウォールでLANに限定する例:
sudo ufw allow from 192.168.0.0/24 to any port 8080 - このポートをインターネットに直接公開しない。
.env(APIキー・トークン)とprompts/*.txtは.gitignore済み。
~/.config/systemd/user/{ollama,roastbot}.service を用意済み。自動再起動・boot起動が要るなら:
systemctl --user daemon-reload
systemctl --user enable --now ollama roastbot
sudo loginctl enable-linger "$USER" # ログアウト後も維持app.py FastAPI本体(/roast パイプライン)
run.sh / roastbot.sh 起動スクリプト / 管理スクリプト
restart.sh 再起動ヘルパー
tune_roast.py 毒舌プロンプト調整(LLMのみ)
measure.py / measure_groq.py 速度・トークン・コスト計測
webhook_reference.py LINE webhook 雛形(別サーバー用)
prompts/*.example.txt システムプロンプト雛形
.env.example 設定ファイル雛形