🎓 レベル:標準 | 重要度:B(推奨) 📎 前提:OpenAI互換API | 原理:推論の実務(機械学習)
要点(結論先出し)
- 体感は2指標で決まる:TTFT(最初の1トークンまでの時間)とトークン毎秒(生成速度)。
- ストリーミングは完成を待たず逐次表示するので、TTFTが短ければ「速い」と感じる。総時間が同じでも体感が変わる。
- 並行リクエストは単機向けエンジンだと取り合いで詰まりやすい。多人数同時なら連続バッチング系(vLLM)へ → vLLMとTGI
概念 ── 「速さ」は2つに分けて測る
- TTFT:プロンプト処理(prefill)が終わって最初のトークンが出るまで。長文入力ほど伸びる。
- トークン毎秒:その後の生成速度。メモリ帯域律速(→ GPU・CPU・Apple Silicon)。
ユーザー体感はTTFTに強く引っ張られます。だからストリーミングでまず出し始めるのが効く。
動くコード(ストリーミング・Python)
from openai import OpenAI
client = OpenAI(base_url="http://localhost:11434/v1", api_key="local")
stream = client.chat.completions.create(
model="llama3.1:8b",
messages=[{"role": "user", "content": "短い物語を書いて"}],
stream=True,
)
for chunk in stream:
delta = chunk.choices[0].delta.content or ""
print(delta, end="", flush=True)
逐次トークンが届くので、生成完了を待たずに読み始められます。
仕組み ── 並行リクエストはどこで詰まるか
flowchart TD
R["複数リクエスト同時"] --> E{"エンジンの種類"}
E -->|"単機向け(llama.cpp・Ollama)"| Q["基本は順番待ち(取り合いで遅延)"]
E -->|"連続バッチング(vLLM・TGI)"| B["まとめて並行処理(高スループット)"]
単機向けエンジンは1リクエストを速く返す設計。同時に多数を投げると待ち行列ができます。多人数前提なら連続バッチング系を選ぶのが筋(→ vLLMとTGI)。
運用の勘所
- 対話UIは必ずストリーミング。TTFTを短く見せて体感を稼ぐ。
- 長文入力でTTFTが伸びるときは、入力を要約/分割(RAG的に)→ ローカルRAGの構成
- 「同時に何件来るか」を見積もり、1〜2件なら単機、多数なら vLLM。並行数で設計が変わる。
なぜそうするか
総処理時間を縮めるのは難しくても、出し始めを早める(ストリーミング)だけで体感は大きく改善します。また、並行性の要求を最初に見積もると、エンジン選定(単機 or バッチング)を間違えません。体感と同時実行は別物として設計するのが正解です。
⚠️ よくある落とし穴
- 総時間だけ見て体感を無視:ストリーミング無しだと同じ速度でも「遅い」と感じる。
- 単機エンジンで多人数を捌こうとする:取り合いで全員遅くなる。
- TTFTと生成速度を混同:長文でTTFTが伸びるのはprefillの仕事。生成速度とは別。
- 並行数を測らず設計:実負荷で同時リクエスト数を見積もる。
対応lab
local-llm-study/labs/openai_compat_api.md… ストリーミング接続例を収録。
関連
- API基本 → OpenAI互換API
- 多人数スループット → vLLMとTGI
- 帯域と速度 → GPU・CPU・Apple Silicon