Skip to content
Published on

vLLM & Ollama完全ガイド: LLMサービングエンジンのセットアップ、パラメータ、環境変数

Authors
  • Name
    Twitter

Part 1: vLLM

1. vLLM入門

vLLMはUC Berkeleyで開発された高性能LLM推論・サービングエンジンです。2023年にPagedAttention論文とともに公開されて以来、本番環境LLMサービングのデファクトスタンダードとしての地位を確立しました。2026年3月時点で最新バージョンはv0.16.xで、V1アーキテクチャへの移行が進行中です。

1.1 PagedAttentionのコア原理

従来のLLM推論では、KV CacheはシーケンスごとにGPUメモリ上の連続ブロックに割り当てられます。このアプローチは最大シーケンス長に基づいてメモリを事前確保するため、実際には60-80%のメモリ浪費が発生します。

PagedAttentionはオペレーティングシステムの仮想メモリページングの概念をKV Cache管理に導入します。

┌─────────────────────────────────────────────────┐
│              従来のKV Cache│  ┌──────────────────────────────────┐            │
│  │ Seq 1: [used][used][used][waste][waste][waste]│  │ Seq 2: [used][waste][waste][waste][waste]│  │ Seq 3: [used][used][waste][waste][waste]│  └──────────────────────────────────┘            │
│              → 60~80% メモリ浪費                  │
├─────────────────────────────────────────────────┤
PagedAttention KV CachePhysical Blocks: [B0][B1][B2][B3][B4][B5]...Block Table:Seq 1[B0, B3, B5]  (logical → physical)Seq 2[B1, B4]Seq 3[B2, B6]│              → < 4% メモリ浪費                    │
└─────────────────────────────────────────────────┘

コアメカニズムは以下の通りです。

  • 固定サイズブロック: KV Cacheを固定サイズのブロック(デフォルト16トークン)に分割
  • Block Table: シーケンスの論理ブロック番号と物理ブロックアドレスの対応テーブルを維持
  • 動的割り当て: トークン生成時に必要に応じて物理ブロックを割り当て
  • Copy-on-Write: シーケンス分岐時(例: Beam Search)は物理ブロックを共有し、変更が必要な場合のみコピー

1.2 Continuous Batching

従来のStatic Batchingはバッチ内のすべてのシーケンスが完了するまで待機します。Continuous Batchingは完了したシーケンスを除去し、各デコーディングステップごとに新しいリクエストを挿入します。

Static Batching:
Step 1: [Seq1, Seq2, Seq3, Seq4]Seq2が完了しても待機
Step 2: [Seq1, Seq2, Seq3, Seq4]
Step 3: [Seq1, ___, Seq3, Seq4]Seq2終了後にスロットが無駄に
...
Step N: すべてのシーケンス完了後に次のバッチを開始

Continuous Batching:
Step 1: [Seq1, Seq2, Seq3, Seq4]
Step 2: [Seq1, Seq5, Seq3, Seq4]Seq2完了後すぐにSeq5を挿入
Step 3: [Seq1, Seq5, Seq6, Seq4]Seq3完了後すぐにSeq6を挿入
GPUアイドル時間を最小化し、スループットを最大化

1.3 サポートモデル

vLLMは主要なTransformerベースLLMアーキテクチャのほぼすべてをサポートしています。

カテゴリサポートモデル
Meta Llama系列Llama 2, Llama 3, Llama 3.1, Llama 3.2, Llama 3.3, Llama 4
Mistral系列Mistral 7B, Mixtral 8x7B, Mixtral 8x22B, Mistral Large, Mistral Small
Qwen系列Qwen, Qwen 1.5, Qwen 2, Qwen 2.5, Qwen 3, QwQ
Google系列Gemma, Gemma 2, Gemma 3
DeepSeek系列DeepSeek V2, DeepSeek V3, DeepSeek-R1
その他Phi-3/4, Yi, InternLM 2/3, Command R, DBRX, Falcon, StarCoder 2
マルチモーダルLLaVA, InternVL, Pixtral, Qwen-VL, MiniCPM-V
EmbeddingE5-Mistral, GTE-Qwen, Jina Embeddings

1.4 LLMサービングエンジン比較

項目vLLMTGITensorRT-LLMllama.cpp
開発元UC Berkeley / vLLMプロジェクトHugging FaceNVIDIAGeorgi Gerganov
言語Python/C++/CUDARust/PythonC++/CUDAC/C++
コア技術PagedAttentionContinuous BatchingFP8/INT4カーネル最適化GGUF量子化
マルチGPUTP + PPTPTP + PP限定的
量子化AWQ, GPTQ, FP8, BnBAWQ, GPTQ, BnBFP8, INT4, INT8GGUF (Q2~Q8)
API互換性OpenAI互換OpenAI互換TritonカスタムAPI
導入難易度
本番環境対応非常に高い高い非常に高い低~中
コミュニティ非常に活発活発NVIDIA主導非常に活発

2. vLLMのインストールと起動

2.1 pipインストール

# 基本インストール(CUDA 12.x)
pip install vllm

# 特定バージョンのインストール
pip install vllm==0.16.0

# CUDA 11.8環境
pip install vllm --extra-index-url https://download.pytorch.org/whl/cu118

2.2 condaインストール

conda create -n vllm python=3.11 -y
conda activate vllm
pip install vllm

2.3 Dockerインストール

# 公式Dockerイメージ(NVIDIA GPU)
docker run --runtime nvidia --gpus all \
  -v ~/.cache/huggingface:/root/.cache/huggingface \
  --env "HUGGING_FACE_HUB_TOKEN=<hf_token>" \
  -p 8000:8000 \
  --ipc=host \
  vllm/vllm-openai:latest \
  --model meta-llama/Llama-3.1-8B-Instruct

# ROCm(AMD GPU)
docker run --device /dev/kfd --device /dev/dri \
  -v ~/.cache/huggingface:/root/.cache/huggingface \
  -p 8000:8000 \
  vllm/vllm-openai:latest-rocm \
  --model meta-llama/Llama-3.1-8B-Instruct

2.4 基本サーバー起動

# vllm serveコマンド(推奨)
vllm serve meta-llama/Llama-3.1-8B-Instruct \
  --host 0.0.0.0 \
  --port 8000

# Python モジュール直接実行(レガシー)
python -m vllm.entrypoints.openai.api_server \
  --model meta-llama/Llama-3.1-8B-Instruct \
  --host 0.0.0.0 \
  --port 8000

# YAML設定ファイルで起動
vllm serve meta-llama/Llama-3.1-8B-Instruct \
  --config config.yaml

config.yamlの例:

# vLLMサーバー設定ファイル
host: '0.0.0.0'
port: 8000
tensor_parallel_size: 2
gpu_memory_utilization: 0.90
max_model_len: 8192
dtype: 'auto'
enforce_eager: false
enable_prefix_caching: true

2.5 オフラインバッチ推論

サーバーを起動せずに、Pythonコードから直接バッチ推論を実行できます。

from vllm import LLM, SamplingParams

# モデル読み込み
llm = LLM(
    model="meta-llama/Llama-3.1-8B-Instruct",
    tensor_parallel_size=1,
    gpu_memory_utilization=0.90,
)

# サンプリングパラメータ設定
sampling_params = SamplingParams(
    temperature=0.7,
    top_p=0.9,
    max_tokens=512,
)

# プロンプトリスト
prompts = [
    "Explain PagedAttention in simple terms.",
    "What is continuous batching?",
    "Compare vLLM and TensorRT-LLM.",
]

# バッチ推論実行
outputs = llm.generate(prompts, sampling_params)

for output in outputs:
    prompt = output.prompt
    generated = output.outputs[0].text
    print(f"Prompt: {prompt!r}")
    print(f"Output: {generated!r}\n")

2.6 OpenAI互換APIサーバー

vLLMサーバーはOpenAI API互換エンドポイントを提供します。

# サーバー起動
vllm serve meta-llama/Llama-3.1-8B-Instruct \
  --served-model-name llama-3.1-8b \
  --api-key my-secret-key

# curlでChat Completionを呼び出し
curl http://localhost:8000/v1/chat/completions \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer my-secret-key" \
  -d '{
    "model": "llama-3.1-8b",
    "messages": [
      {"role": "system", "content": "You are a helpful assistant."},
      {"role": "user", "content": "What is PagedAttention?"}
    ],
    "temperature": 0.7,
    "max_tokens": 512
  }'
# OpenAI SDKで呼び出し
from openai import OpenAI

client = OpenAI(
    base_url="http://localhost:8000/v1",
    api_key="my-secret-key",
)

response = client.chat.completions.create(
    model="llama-3.1-8b",
    messages=[
        {"role": "system", "content": "You are a helpful assistant."},
        {"role": "user", "content": "Explain the advantages of vLLM."},
    ],
    temperature=0.7,
    max_tokens=512,
)

print(response.choices[0].message.content)

3. vLLM CLIオプション完全リファレンス

vllm serveに渡すことができる主要なCLIオプションをカテゴリ別にまとめます。完全なリストはvllm serve --helpで確認でき、グループ別にはvllm serve --help=ModelConfigで照会できます。

3.1 モデル関連オプション

オプションデフォルト説明
--modelstrfacebook/opt-125mHuggingFaceモデルIDまたはローカルパス
--tokenizerstrNone(モデルと同一)別のトークナイザーを指定
--revisionstrNoneモデルの特定Gitリビジョン(ブランチ、タグ、コミットハッシュ)
--tokenizer-revisionstrNoneトークナイザーの特定リビジョン
--dtypestr"auto"モデル重みのデータ型(auto, float16, bfloat16, float32
--max-model-lenintNone(モデル設定に準拠)最大シーケンス長(入力 + 出力トークンの合計)
--trust-remote-codeflagFalseHuggingFaceリモートコード実行を許可
--download-dirstrNoneモデルダウンロードディレクトリ
--load-formatstr"auto"モデル読み込み形式(auto, pt, safetensors, npcache, dummy, bitsandbytes
--config-formatstr"auto"モデル設定形式(auto, hf, mistral
--seedint0再現性のためのランダムシード

3.2 サーバー関連オプション

オプションデフォルト説明
--hoststr"0.0.0.0"バインドするホストアドレス
--portint8000サーバーポート番号
--uvicorn-log-levelstr"info"Uvicornログレベル
--api-keystrNoneAPI認証キー(Bearerトークン)
--served-model-namestrNoneAPI用モデル名(未設定時は--modelの値を使用)
--chat-templatestrNoneJinja2チャットテンプレートファイルパスまたは文字列
--response-rolestr"assistant"チャット完了レスポンスのロール
--ssl-keyfilestrNoneSSLキーファイルパス
--ssl-certfilestrNoneSSL証明書ファイルパス
--allowed-originslist["*"]CORS許可オリジンリスト
--middlewarelistNoneFastAPIミドルウェアクラス
--max-log-lenintNoneログ内のプロンプト/出力の最大長
--disable-log-requestsflagFalseリクエストログを無効化

3.3 並列処理関連オプション

オプションデフォルト説明
--tensor-parallel-size (-tp)int1Tensor Parallelism用GPU数
--pipeline-parallel-size (-pp)int1Pipeline Parallelismのステージ数
--distributed-executor-backendstrNone分散実行バックエンド(ray, mp
--ray-workers-use-nsightflagFalseRayワーカーでNsightプロファイラーを使用
--data-parallel-size (-dp)int1Data Parallelismのプロセス数

使用例:

# 4 GPU Tensor Parallelism
vllm serve meta-llama/Llama-3.1-70B-Instruct \
  --tensor-parallel-size 4

# 2 GPU Tensor + 2-way Pipeline(合計4 GPU)
vllm serve meta-llama/Llama-3.1-70B-Instruct \
  --tensor-parallel-size 2 \
  --pipeline-parallel-size 2

# Ray分散バックエンド(マルチノード)
vllm serve meta-llama/Llama-3.1-70B-Instruct \
  --tensor-parallel-size 8 \
  --distributed-executor-backend ray

3.4 メモリ・パフォーマンス関連オプション

オプションデフォルト説明
--gpu-memory-utilizationfloat0.90GPUメモリ使用率(0.0~1.0)
--max-num-seqsint256最大同時シーケンス数
--max-num-batched-tokensintNone(自動)ステップあたりの最大処理トークン数
--block-sizeint16PagedAttentionブロックサイズ(トークン単位)
--swap-spacefloat4CPUスワップスペースサイズ(GiB)
--enforce-eagerflagFalseCUDA Graphを無効化し、Eagerモードを強制
--max-seq-len-to-captureint8192CUDA Graphキャプチャの最大シーケンス長
--disable-custom-all-reduceflagFalseカスタムAll-Reduceを無効化
--enable-prefix-cachingflagTrue (v1)Automatic Prefix Cachingを有効化
--enable-chunked-prefillflagTrue (v1)Chunked Prefillを有効化
--num-scheduler-stepsint1スケジューラあたりのデコーディングステップ数(Multi-Step)
--kv-cache-dtypestr"auto"KV Cacheデータ型(auto, fp8, fp8_e5m2, fp8_e4m3

使用例:

# メモリ最適化設定
vllm serve meta-llama/Llama-3.1-8B-Instruct \
  --gpu-memory-utilization 0.95 \
  --max-num-seqs 128 \
  --max-model-len 4096 \
  --enable-prefix-caching \
  --enable-chunked-prefill

# Eagerモード(デバッグ/互換性用)
vllm serve meta-llama/Llama-3.1-8B-Instruct \
  --enforce-eager \
  --gpu-memory-utilization 0.85

3.5 量子化関連オプション

オプションデフォルト説明
--quantization (-q)strNone量子化方式を選択
--load-formatstr"auto"モデル読み込み形式

--quantizationのサポート値:

説明備考
awqAWQ(Activation-aware Weight Quantization)4ビット、高速推論
gptqGPTQ(Post-Training Quantization)4ビット、ExLlamaV2カーネル
gptq_marlinGPTQ + Marlinカーネル4ビット、高速カーネル
awq_marlinAWQ + Marlinカーネル4ビット、高速カーネル
squeezellmSqueezeLLMスパース量子化
fp8FP8(8ビット浮動小数点)H100/MI300xのみ
bitsandbytesBitsAndBytes4ビットNF4
ggufGGUFフォーマットllama.cpp互換
compressed-tensorsCompressed Tensors汎用
experts_int8MoE Expert INT8MoEモデルのみ

使用例:

# AWQ量子化モデル
vllm serve TheBloke/Llama-2-7B-AWQ \
  --quantization awq

# GPTQ量子化モデル
vllm serve TheBloke/Llama-2-7B-GPTQ \
  --quantization gptq

# FP8量子化(H100以上)
vllm serve neuralmagic/Meta-Llama-3.1-8B-Instruct-FP8 \
  --quantization fp8

# BitsAndBytes 4ビット(GPUメモリ節約)
vllm serve meta-llama/Llama-3.1-8B-Instruct \
  --quantization bitsandbytes \
  --load-format bitsandbytes

3.6 LoRA関連オプション

オプションデフォルト説明
--enable-loraflagFalseLoRAアダプターサービングを有効化
--max-lorasint1同時に読み込むLoRAの最大数
--max-lora-rankint16LoRAの最大ランク
--lora-extra-vocab-sizeint256LoRAアダプター用の追加語彙サイズ
--lora-moduleslistNoneLoRAアダプターリスト(name=path形式)
--long-lora-scaling-factorslistNoneLong LoRAスケーリングファクター

使用例:

# LoRAアダプターサービング
vllm serve meta-llama/Llama-3.1-8B-Instruct \
  --enable-lora \
  --max-loras 4 \
  --max-lora-rank 64 \
  --lora-modules \
    adapter1=/path/to/lora1 \
    adapter2=/path/to/lora2

3.7 Speculative Decodingオプション

オプションデフォルト説明
--speculative-modelstrNoneドラフトモデル(小型モデルまたは[ngram]
--num-speculative-tokensintNone投機的に生成するトークン数
--speculative-draft-tensor-parallel-sizeintNoneドラフトモデルのTPサイズ
--speculative-disable-by-batch-sizeintNoneバッチサイズが閾値を超えた場合に無効化
--ngram-prompt-lookup-maxintNoneN-gram投機の最大ルックアップサイズ
--ngram-prompt-lookup-minintNoneN-gram投機の最小ルックアップサイズ

使用例:

# 別のドラフトモデルを使用
vllm serve meta-llama/Llama-3.1-70B-Instruct \
  --speculative-model meta-llama/Llama-3.2-1B-Instruct \
  --num-speculative-tokens 5 \
  --tensor-parallel-size 4

# N-gramベースのspeculative decoding(追加モデル不要)
vllm serve meta-llama/Llama-3.1-8B-Instruct \
  --speculative-model "[ngram]" \
  --num-speculative-tokens 5 \
  --ngram-prompt-lookup-max 4

4. vLLMサンプリングパラメータ

vLLMはOpenAI API互換パラメータに加え、追加の高度なパラメータをサポートしています。

4.1 パラメータ完全リファレンス

パラメータデフォルト範囲説明
temperaturefloat1.0>= 0.0低いほど決定的、高いほど創造的。0 = Greedy
top_pfloat1.0(0.0, 1.0]Nucleusサンプリング。累積確率で上位トークンのみサンプル
top_kint-1-1または>= 1上位kトークンのみ考慮。-1で無効
min_pfloat0.0[0.0, 1.0]最小確率閾値。最高確率との比率でフィルタリング
frequency_penaltyfloat0.0[-2.0, 2.0]頻度ベースのペナルティ。正の値は繰り返しを抑制
presence_penaltyfloat0.0[-2.0, 2.0]存在ベースのペナルティ。一度でも出現したトークンにペナルティ
repetition_penaltyfloat1.0> 0.0繰り返しペナルティ(1.0で無効、1.0超で抑制)
max_tokensint16>= 1生成する最大トークン数
stoplistNone-停止文字列のリスト
seedintNone-ランダムシード(再現性を確保)
nint1>= 1プロンプトあたりの応答数
best_ofintNone>= nbest_of個の候補を生成し最良を選択
use_beam_searchboolFalse-Beam Searchを有効化
logprobsintNone[0, 20]返却するトークンあたりのログ確率数
prompt_logprobsintNone[0, 20]返却するプロンプトトークンのログ確率数
skip_special_tokensboolTrue-特殊トークンをスキップするかどうか
spaces_between_special_tokensboolTrue-特殊トークン間にスペースを挿入
guided_jsonobjectNone-JSON Schemaベースの構造化出力
guided_regexstrNone-正規表現ベースの構造化出力
guided_choicelistNone-選択ベースの構造化出力

4.2 curlによるAPI呼び出し例

# 基本Chat Completion
curl http://localhost:8000/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "meta-llama/Llama-3.1-8B-Instruct",
    "messages": [
      {"role": "user", "content": "What is the population of Seoul?"}
    ],
    "temperature": 0.3,
    "top_p": 0.9,
    "max_tokens": 256,
    "frequency_penalty": 0.5,
    "seed": 42
  }'

# 構造化出力(JSONモード)
curl http://localhost:8000/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "meta-llama/Llama-3.1-8B-Instruct",
    "messages": [
      {"role": "user", "content": "Give me the population of Seoul, Busan, and Daegu in JSON"}
    ],
    "response_format": {
      "type": "json_schema",
      "json_schema": {
        "name": "city_population",
        "schema": {
          "type": "object",
          "properties": {
            "cities": {
              "type": "array",
              "items": {
                "type": "object",
                "properties": {
                  "name": {"type": "string"},
                  "population": {"type": "integer"}
                },
                "required": ["name", "population"]
              }
            }
          },
          "required": ["cities"]
        }
      }
    },
    "temperature": 0.1,
    "max_tokens": 512
  }'

# logprobsの返却
curl http://localhost:8000/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "meta-llama/Llama-3.1-8B-Instruct",
    "messages": [
      {"role": "user", "content": "1+1=?"}
    ],
    "logprobs": true,
    "top_logprobs": 5,
    "max_tokens": 10
  }'

4.3 Python requestsの例

import requests
import json

url = "http://localhost:8000/v1/chat/completions"
headers = {"Content-Type": "application/json"}

payload = {
    "model": "meta-llama/Llama-3.1-8B-Instruct",
    "messages": [
        {"role": "system", "content": "You are a helpful Korean assistant."},
        {"role": "user", "content": "What is quantum computing?"},
    ],
    "temperature": 0.7,
    "top_p": 0.9,
    "top_k": 50,
    "max_tokens": 1024,
    "repetition_penalty": 1.1,
    "stop": ["\n\n\n"],
}

response = requests.post(url, headers=headers, json=payload)
result = response.json()
print(result["choices"][0]["message"]["content"])

4.4 OpenAI SDKによるStreaming例

from openai import OpenAI

client = OpenAI(base_url="http://localhost:8000/v1", api_key="token")

# ストリーミングレスポンス
stream = client.chat.completions.create(
    model="meta-llama/Llama-3.1-8B-Instruct",
    messages=[
        {"role": "user", "content": "Implement quicksort in Python"},
    ],
    temperature=0.2,
    max_tokens=2048,
    stream=True,
)

for chunk in stream:
    if chunk.choices[0].delta.content:
        print(chunk.choices[0].delta.content, end="", flush=True)
print()

5. vLLM環境変数完全リファレンス

vLLMは様々な環境変数でランタイムの動作を制御します。以下は主要な環境変数のカテゴリ別まとめです。

5.1 コア環境変数

環境変数デフォルト説明
VLLM_TARGET_DEVICE"cuda"ターゲットデバイス(cuda, rocm, neuron, cpu, xpu
VLLM_USE_V1TrueV1コードパスを使用
VLLM_WORKER_MULTIPROC_METHOD"fork"マルチプロセスの起動方法(spawn, fork
VLLM_ALLOW_LONG_MAX_MODEL_LENFalseモデル設定より長いmax_model_lenを許可
CUDA_VISIBLE_DEVICESNone使用するGPUデバイス番号

5.2 Attention・カーネル関連

環境変数デフォルト説明
VLLM_ATTENTION_BACKENDNoneAttentionバックエンド(非推奨、v0.14から--attention-backendを使用)
VLLM_USE_TRITON_FLASH_ATTNTrueTriton Flash Attentionを使用
VLLM_FLASH_ATTN_VERSIONNoneFlash Attentionバージョンを強制(2または3
VLLM_USE_FLASHINFER_SAMPLERNoneFlashInferサンプラーを使用
VLLM_FLASHINFER_FORCE_TENSOR_CORESFalseFlashInferでテンサーコアを強制使用
VLLM_USE_TRITON_AWQFalseTriton AWQカーネルを使用
VLLM_USE_DEEP_GEMMFalseDeepGemmカーネルを使用(MoE演算)
VLLM_MLA_DISABLEFalseMLA Attention最適化を無効化

5.3 ログ関連

環境変数デフォルト説明
VLLM_CONFIGURE_LOGGING1vLLMログの自動設定(0で無効化)
VLLM_LOGGING_LEVEL"INFO"デフォルトログレベル
VLLM_LOGGING_CONFIG_PATHNoneカスタムログ設定ファイルパス
VLLM_LOGGING_PREFIX""ログメッセージに付加するプレフィックス
VLLM_LOG_BATCHSIZE_INTERVAL-1バッチサイズログ間隔(秒、-1で無効化)
VLLM_TRACE_FUNCTION0関数呼び出しトレースを有効化
VLLM_DEBUG_LOG_API_SERVER_RESPONSEFalseAPIレスポンスのデバッグログ

5.4 分散処理関連

環境変数デフォルト説明
VLLM_HOST_IP""分散セットアップ用ノードIP
VLLM_PORT0分散通信ポート
VLLM_NCCL_SO_PATHNoneNCCLライブラリファイルパス
NCCL_DEBUGNoneNCCLデバッグレベル(INFO, WARN, TRACE
NCCL_SOCKET_IFNAMENoneNCCL通信用ネットワークインターフェース
VLLM_PP_LAYER_PARTITIONNonePipeline Parallelismのレイヤー分割戦略
VLLM_DP_RANK0Data Parallelプロセスランク
VLLM_DP_SIZE1Data Parallelワールドサイズ
VLLM_DP_MASTER_IP"127.0.0.1"Data ParallelマスターノードIP
VLLM_DP_MASTER_PORT0Data Parallelマスターノードポート
VLLM_USE_RAY_SPMD_WORKERFalseRay SPMDワーカー実行
VLLM_USE_RAY_COMPILED_DAGFalseRay Compiled Graph APIを使用
VLLM_SKIP_P2P_CHECKFalseGPU P2P機能チェックをスキップ

5.5 HuggingFace・外部サービス

環境変数デフォルト説明
HF_TOKENNoneHuggingFace APIトークン
HUGGING_FACE_HUB_TOKENNoneHuggingFace Hubトークン(レガシー)
VLLM_USE_MODELSCOPEFalseModelScopeからモデルを読み込み
VLLM_API_KEYNonevLLM APIサーバー認証キー
VLLM_NO_USAGE_STATSFalse使用統計収集を無効化
VLLM_DO_NOT_TRACKFalseトラッキングをオプトアウト

5.6 キャッシュ・パス

環境変数デフォルト説明
VLLM_CONFIG_ROOT~/.config/vllm設定ファイルルートディレクトリ
VLLM_CACHE_ROOT~/.cache/vllmキャッシュファイルルートディレクトリ
VLLM_ASSETS_CACHE~/.cache/vllm/assetsダウンロード済みアセットのキャッシュパス
VLLM_RPC_BASE_PATHシステムtempIPCマルチプロセッシングパス

5.7 環境変数使用例

# マルチGPU + ログ + HFトークン設定
export CUDA_VISIBLE_DEVICES=0,1,2,3
export HF_TOKEN="hf_xxxxxxxxxxxx"
export VLLM_LOGGING_LEVEL="DEBUG"
export VLLM_WORKER_MULTIPROC_METHOD="spawn"

vllm serve meta-llama/Llama-3.1-70B-Instruct \
  --tensor-parallel-size 4 \
  --gpu-memory-utilization 0.90

# Dockerでの環境変数指定
docker run --runtime nvidia --gpus all \
  -e CUDA_VISIBLE_DEVICES=0,1 \
  -e HF_TOKEN="hf_xxxxxxxxxxxx" \
  -e VLLM_LOGGING_LEVEL="INFO" \
  -e VLLM_WORKER_MULTIPROC_METHOD="spawn" \
  -p 8000:8000 \
  --ipc=host \
  vllm/vllm-openai:latest \
  --model meta-llama/Llama-3.1-8B-Instruct \
  --tensor-parallel-size 2

6. vLLM高度な設定

6.1 マルチGPUセットアップ

Tensor Parallelism(TP): モデルの各レイヤーを複数のGPUに分散します。単一ノードで最もよく使用されるアプローチです。

# TP=4(モデルを4つのGPUに分散)
vllm serve meta-llama/Llama-3.1-70B-Instruct \
  --tensor-parallel-size 4 \
  --gpu-memory-utilization 0.90

Pipeline Parallelism(PP): モデルのレイヤーを複数のGPUに順次配置します。低速なインターコネクト環境で有利です。

# PP=2, TP=2(合計4 GPU、2x2構成)
vllm serve meta-llama/Llama-3.1-70B-Instruct \
  --tensor-parallel-size 2 \
  --pipeline-parallel-size 2

マルチノードセットアップ(Rayを使用):

# マスターノード
ray start --head --port=6379

# ワーカーノード
ray start --address=<master-ip>:6379

# vLLM実行(マスターから)
vllm serve meta-llama/Llama-3.1-405B-Instruct \
  --tensor-parallel-size 8 \
  --pipeline-parallel-size 2 \
  --distributed-executor-backend ray

6.2 量子化の詳細

AWQ(Activation-aware Weight Quantization):

# 事前量子化済みAWQモデルを使用
vllm serve TheBloke/Llama-2-13B-chat-AWQ \
  --quantization awq \
  --max-model-len 4096

# Marlinカーネルで高速化(SM 80以上のGPU)
vllm serve TheBloke/Llama-2-13B-chat-AWQ \
  --quantization awq_marlin

GPTQ(Post-Training Quantization):

# GPTQモデル(ExLlamaV2カーネル自動使用)
vllm serve TheBloke/Llama-2-13B-chat-GPTQ \
  --quantization gptq

# Marlinカーネルを使用
vllm serve TheBloke/Llama-2-13B-chat-GPTQ \
  --quantization gptq_marlin

FP8(8ビット浮動小数点): H100、MI300x以上のGPUでハードウェアアクセラレーションをサポートします。

# 事前量子化済みFP8モデル
vllm serve neuralmagic/Meta-Llama-3.1-8B-Instruct-FP8 \
  --quantization fp8

# 動的FP8量子化(事前量子化不要)
vllm serve meta-llama/Llama-3.1-8B-Instruct \
  --quantization fp8 \
  --kv-cache-dtype fp8

BitsAndBytes 4ビットNF4: キャリブレーションデータなしで即座に量子化できます。

vllm serve meta-llama/Llama-3.1-8B-Instruct \
  --quantization bitsandbytes \
  --load-format bitsandbytes \
  --enforce-eager  # BnBはEagerモードが必要

6.3 LoRAサービング

# LoRAアダプターを有効化
vllm serve meta-llama/Llama-3.1-8B-Instruct \
  --enable-lora \
  --max-loras 4 \
  --max-lora-rank 64 \
  --lora-modules \
    korean-chat=/path/to/korean-lora \
    code-assist=/path/to/code-lora

API呼び出しでLoRAモデルを指定:

from openai import OpenAI

client = OpenAI(base_url="http://localhost:8000/v1", api_key="token")

# 特定のLoRAアダプターを使用
response = client.chat.completions.create(
    model="korean-chat",  # LoRAアダプター名
    messages=[{"role": "user", "content": "Hello!"}],
    temperature=0.7,
    max_tokens=256,
)

6.4 Prefix Caching & Chunked Prefill

Automatic Prefix Caching: 共通のプロンプトプレフィックスに対してKV Cacheを再利用し、TTFTを削減します。多くのリクエストが同じシステムプロンプトを共有する場合に特に効果的です。

# v1ではデフォルトで有効、v0では明示的なフラグが必要
vllm serve meta-llama/Llama-3.1-8B-Instruct \
  --enable-prefix-caching

Chunked Prefill: 長いプロンプトをチャンクに分割し、PrefillとDecodeをインターリーブします。長いプロンプトが短いリクエストのDecodeをブロックするのを防ぎます。

vllm serve meta-llama/Llama-3.1-8B-Instruct \
  --enable-chunked-prefill \
  --max-num-batched-tokens 2048

6.5 構造化出力(Guided Decoding)

# JSON Schemaベースの構造化出力
curl http://localhost:8000/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "meta-llama/Llama-3.1-8B-Instruct",
    "messages": [
      {"role": "user", "content": "Please provide Seoul weather info in JSON"}
    ],
    "response_format": {
      "type": "json_schema",
      "json_schema": {
        "name": "weather_info",
        "schema": {
          "type": "object",
          "properties": {
            "city": {"type": "string"},
            "temperature_celsius": {"type": "number"},
            "condition": {"type": "string"},
            "humidity_percent": {"type": "integer"}
          },
          "required": ["city", "temperature_celsius", "condition"]
        }
      }
    }
  }'

# 正規表現ベースの出力(Completion API)
curl http://localhost:8000/v1/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "meta-llama/Llama-3.1-8B-Instruct",
    "prompt": "Generate a valid email address:",
    "extra_body": {
      "guided_regex": "[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}"
    },
    "max_tokens": 50
  }'

6.6 Dockerデプロイ

# docker-compose.yaml
version: '3.8'

services:
  vllm:
    image: vllm/vllm-openai:latest
    runtime: nvidia
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              count: all
              capabilities: [gpu]
    ports:
      - '8000:8000'
    volumes:
      - ~/.cache/huggingface:/root/.cache/huggingface
    environment:
      - HF_TOKEN=${HF_TOKEN}
      - VLLM_LOGGING_LEVEL=INFO
      - VLLM_WORKER_MULTIPROC_METHOD=spawn
    ipc: host
    command: >
      --model meta-llama/Llama-3.1-8B-Instruct
      --host 0.0.0.0
      --port 8000
      --tensor-parallel-size 2
      --gpu-memory-utilization 0.90
      --max-model-len 8192
      --enable-prefix-caching
    healthcheck:
      test: ['CMD', 'curl', '-f', 'http://localhost:8000/health']
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 120s
# Docker Composeで実行
HF_TOKEN=hf_xxxx docker compose up -d

# ログ確認
docker compose logs -f vllm

6.7 Kubernetesデプロイ

# vllm-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: vllm-llama3
  namespace: ai-serving
  labels:
    app: vllm
spec:
  replicas: 1
  selector:
    matchLabels:
      app: vllm
  template:
    metadata:
      labels:
        app: vllm
    spec:
      containers:
        - name: vllm
          image: vllm/vllm-openai:latest
          ports:
            - containerPort: 8000
              name: http
          args:
            - '--model'
            - 'meta-llama/Llama-3.1-8B-Instruct'
            - '--host'
            - '0.0.0.0'
            - '--port'
            - '8000'
            - '--tensor-parallel-size'
            - '2'
            - '--gpu-memory-utilization'
            - '0.90'
            - '--max-model-len'
            - '8192'
          env:
            - name: HF_TOKEN
              valueFrom:
                secretKeyRef:
                  name: hf-secret
                  key: token
            - name: VLLM_WORKER_MULTIPROC_METHOD
              value: 'spawn'
          resources:
            limits:
              nvidia.com/gpu: '2'
            requests:
              nvidia.com/gpu: '2'
              memory: '32Gi'
              cpu: '8'
          volumeMounts:
            - name: shm
              mountPath: /dev/shm
            - name: model-cache
              mountPath: /root/.cache/huggingface
          readinessProbe:
            httpGet:
              path: /health
              port: 8000
            initialDelaySeconds: 120
            periodSeconds: 10
          livenessProbe:
            httpGet:
              path: /health
              port: 8000
            initialDelaySeconds: 180
            periodSeconds: 30
      volumes:
        - name: shm
          emptyDir:
            medium: Memory
            sizeLimit: 2Gi
        - name: model-cache
          persistentVolumeClaim:
            claimName: model-cache-pvc
      nodeSelector:
        nvidia.com/gpu.product: 'NVIDIA-A100-SXM4-80GB'
---
apiVersion: v1
kind: Service
metadata:
  name: vllm-service
  namespace: ai-serving
spec:
  selector:
    app: vllm
  ports:
    - port: 8000
      targetPort: 8000
      name: http
  type: ClusterIP
---
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: vllm-hpa
  namespace: ai-serving
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: vllm-llama3
  minReplicas: 1
  maxReplicas: 4
  metrics:
    - type: Pods
      pods:
        metric:
          name: vllm_num_requests_running
        target:
          type: AverageValue
          averageValue: '50'

Part 2: Ollama

7. Ollama入門

Ollamaは、ローカル環境で簡単にLLMを実行できるオープンソースツールです。Dockerのように、ollama run llama3.1という1つのコマンドでモデルをダウンロードしてすぐにチャットを開始できます。

7.1 アーキテクチャの特徴

  • GGUFベース: llama.cppのGGUF(GPT-Generated Unified Format)量子化モデルを使用
  • llama.cppエンジン: 内部でllama.cppを推論エンジンとして使用
  • シングルバイナリ: Goサーバー + llama.cpp C++エンジンを単一バイナリとして配布
  • 自動GPUアクセラレーション: NVIDIA CUDA、AMD ROCm、Apple Metalを自動検出してGPUオフロード
  • モデルレジストリ: Docker Hubのようにollama.com/libraryから事前量子化済みモデルをpull/push

7.2 サポートモデル

カテゴリモデルサイズ
Meta Llamallama3.1, llama3.2, llama3.31B~405B
Mistralmistral, mixtral7B~8x22B
Googlegemma, gemma2, gemma32B~27B
Microsoftphi3, phi43.8B~14B
DeepSeekdeepseek-r1, deepseek-v3, deepseek-coder-v21.5B~671B
Qwenqwen, qwen2, qwen2.5, qwen30.5B~72B
コードcodellama, starcoder2, qwen2.5-coder3B~34B
Embeddingnomic-embed-text, mxbai-embed-large, all-minilm-
マルチモーダルllava, bakllava, llama3.2-vision7B~90B

8. Ollamaのインストールと起動

8.1 プラットフォーム別インストール

macOS:

# Homebrew
brew install ollama

# または公式インストールスクリプト
curl -fsSL https://ollama.com/install.sh | sh

Linux:

# 公式インストールスクリプト(推奨)
curl -fsSL https://ollama.com/install.sh | sh

# または手動インストール
curl -L https://ollama.com/download/ollama-linux-amd64 -o /usr/local/bin/ollama
chmod +x /usr/local/bin/ollama

Windows:

公式サイト(ollama.com)からWindowsインストーラーをダウンロードして実行してください。

Docker:

# CPUのみ
docker run -d -v ollama:/root/.ollama -p 11434:11434 \
  --name ollama ollama/ollama

# NVIDIA GPU
docker run -d --gpus=all -v ollama:/root/.ollama -p 11434:11434 \
  --name ollama ollama/ollama

# AMD GPU(ROCm)
docker run -d --device /dev/kfd --device /dev/dri \
  -v ollama:/root/.ollama -p 11434:11434 \
  --name ollama ollama/ollama:rocm

8.2 基本的な使い方

# サーバー起動(バックグラウンドで自動起動されていない場合)
ollama serve

# モデルをダウンロードしてチャット開始
ollama run llama3.1

# タグを指定(サイズ/量子化)
ollama run llama3.1:8b
ollama run llama3.1:70b-instruct-q4_K_M
ollama run qwen2.5:32b-instruct-q5_K_M

# モデルのみダウンロード(実行なし)
ollama pull llama3.1:8b

# ワンラインプロンプト
ollama run llama3.1 "What is PagedAttention?"

9. Ollama CLIコマンド完全リファレンス

9.1 コマンド一覧

コマンド説明主要オプション
ollama serveOllamaサーバーを起動--helpで環境変数を確認
ollama run <model>モデルを実行(未取得時は自動pull)--verbose, --nowordwrap, --format json
ollama pull <model>モデルをダウンロード--insecure
ollama push <model>レジストリにモデルをアップロード--insecure
ollama create <model>Modelfileからカスタムモデルを作成-f <Modelfile>, --quantize
ollama list / ollama lsインストール済みモデルを一覧表示-
ollama show <model>モデルの詳細を表示--modelfile, --parameters, --system, --template, --license
ollama cp <src> <dst>モデルをコピー-
ollama rm <model>モデルを削除-
ollama ps実行中のモデルを一覧表示-
ollama stop <model>実行中のモデルを停止-
ollama signinollama.comにサインイン-
ollama signoutollama.comからサインアウト-

9.2 詳細コマンド例

ollama serve - サーバー起動:

# デフォルト起動(localhost:11434)
ollama serve

# 環境変数でバインドアドレスを変更
OLLAMA_HOST=0.0.0.0:11434 ollama serve

# デバッグモード
OLLAMA_DEBUG=1 ollama serve

ollama run - モデル実行:

# 対話モード
ollama run llama3.1

# ワンラインプロンプト
ollama run llama3.1 "Explain quantum computing"

# JSON形式出力
ollama run llama3.1 "List 3 Korean cities" --format json

# マルチモーダル(画像入力)
ollama run llama3.2-vision "What's in this image? /path/to/image.png"

# 詳細モード(パフォーマンス統計を表示)
ollama run llama3.1 --verbose

# システムプロンプト指定
ollama run llama3.1 --system "You are a Korean translator."

ollama create - カスタムモデル作成:

# Modelfileから作成
ollama create my-model -f ./Modelfile

# GGUFファイルから作成
ollama create my-model -f ./Modelfile-from-gguf

# 量子化変換
ollama create my-model-q4 --quantize q4_K_M -f ./Modelfile

ollama show - モデル情報確認:

# 全情報
ollama show llama3.1

# Modelfileを出力
ollama show llama3.1 --modelfile

# パラメータを確認
ollama show llama3.1 --parameters

# システムプロンプトを確認
ollama show llama3.1 --system

# テンプレートを確認
ollama show llama3.1 --template

ollama ps - 実行中のモデル:

$ ollama ps
NAME              ID            SIZE     PROCESSOR    UNTIL
llama3.1:8b       a]f2e33d4e25  6.7 GB   100% GPU     4 minutes from now
qwen2.5:7b        845dbda0ea48  4.7 GB   100% GPU     3 minutes from now

10. Ollama APIエンドポイント

OllamaはREST APIとOpenAI互換APIの両方を提供します。デフォルトアドレスはhttp://localhost:11434です。

10.1 ネイティブAPIエンドポイント

エンドポイントメソッド説明
/api/generatePOSTテキスト補完の生成
/api/chatPOSTチャット補完の生成
/api/embedPOST埋め込みベクトルの生成
/api/tagsGETローカルモデルの一覧
/api/showPOSTモデルの詳細
/api/pullPOSTモデルのダウンロード
/api/pushPOSTモデルのアップロード
/api/createPOSTカスタムモデルの作成
/api/copyPOSTモデルのコピー
/api/deleteDELETEモデルの削除
/api/psGET実行中のモデルの一覧
/api/versionGETOllamaバージョン情報

10.2 OpenAI互換エンドポイント

エンドポイントメソッド説明
/v1/chat/completionsPOSTOpenAI Chat Completion互換
/v1/completionsPOSTOpenAI Completion互換
/v1/modelsGETモデルリスト(OpenAI形式)
/v1/embeddingsPOSTEmbeddings(OpenAI形式)

10.3 API呼び出し例

Generate(Completion):

# 基本生成
curl http://localhost:11434/api/generate -d '{
  "model": "llama3.1",
  "prompt": "Why is the sky blue?",
  "stream": false
}'

# ストリーミング(デフォルト)
curl http://localhost:11434/api/generate -d '{
  "model": "llama3.1",
  "prompt": "Write a haiku about coding",
  "options": {
    "temperature": 0.7,
    "num_predict": 100
  }
}'

# JSON形式出力
curl http://localhost:11434/api/generate -d '{
  "model": "llama3.1",
  "prompt": "List 3 programming languages as JSON",
  "format": "json",
  "stream": false
}'

Chat(会話):

curl http://localhost:11434/api/chat -d '{
  "model": "llama3.1",
  "messages": [
    {"role": "system", "content": "You are a helpful Korean assistant."},
    {"role": "user", "content": "Recommend tourist spots in Seoul."}
  ],
  "stream": false,
  "options": {
    "temperature": 0.8,
    "top_p": 0.9,
    "num_ctx": 4096,
    "num_predict": 512
  }
}'

Embed(Embeddings):

# 単一テキスト埋め込み
curl http://localhost:11434/api/embed -d '{
  "model": "nomic-embed-text",
  "input": "Hello, world!"
}'

# 複数テキスト埋め込み
curl http://localhost:11434/api/embed -d '{
  "model": "nomic-embed-text",
  "input": ["Hello world", "Goodbye world"]
}'

OpenAI互換API:

# OpenAI形式Chat Completion
curl http://localhost:11434/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "llama3.1",
    "messages": [
      {"role": "user", "content": "Hello!"}
    ],
    "temperature": 0.7,
    "max_tokens": 256
  }'

# モデルリスト
curl http://localhost:11434/v1/models

Pythonからの呼び出し:

import requests

# Generate API
response = requests.post("http://localhost:11434/api/generate", json={
    "model": "llama3.1",
    "prompt": "Explain Docker in Korean",
    "stream": False,
    "options": {
        "temperature": 0.7,
        "num_predict": 512,
    },
})
print(response.json()["response"])

# Chat API
response = requests.post("http://localhost:11434/api/chat", json={
    "model": "llama3.1",
    "messages": [
        {"role": "user", "content": "What is Kubernetes?"},
    ],
    "stream": False,
})
print(response.json()["message"]["content"])
# OllamaをOpenAI SDKで使用
from openai import OpenAI

client = OpenAI(
    base_url="http://localhost:11434/v1",
    api_key="ollama",  # OllamaはAPIキー不要、任意の値で可
)

response = client.chat.completions.create(
    model="llama3.1",
    messages=[
        {"role": "user", "content": "Explain Python's GIL."},
    ],
    temperature=0.7,
    max_tokens=512,
)
print(response.choices[0].message.content)

11. Ollamaパラメータ(Modelfile & API)

11.1 Modelfileの構造

ModelfileはOllamaカスタムモデルを定義します。Dockerfileに似た構造を持っています。

# ベースモデルを指定(必須)
FROM llama3.1:8b

# パラメータ設定
PARAMETER temperature 0.7
PARAMETER top_p 0.9
PARAMETER top_k 40
PARAMETER num_ctx 4096
PARAMETER num_predict 512
PARAMETER repeat_penalty 1.1
PARAMETER stop "<|eot_id|>"
PARAMETER stop "<|end_of_text|>"

# システムプロンプト
SYSTEM """
You are a friendly Korean AI assistant.
You provide accurate and concise answers, explaining with examples when needed.
"""

# チャットテンプレート(Jinja2またはGoテンプレート)
TEMPLATE """
{{- if .System }}<|start_header_id|>system<|end_header_id|>
{{ .System }}<|eot_id|>{{ end }}
{{- range .Messages }}<|start_header_id|>{{ .Role }}<|end_header_id|>
{{ .Content }}<|eot_id|>{{ end }}<|start_header_id|>assistant<|end_header_id|>
"""

# LoRAアダプター(オプション)
ADAPTER /path/to/lora-adapter.gguf

# ライセンス情報(オプション)
LICENSE """
Apache 2.0
"""
ディレクティブ説明必須
FROMベースモデル(モデル名またはGGUFファイルパス)必須
PARAMETERモデルパラメータ設定オプション
TEMPLATEプロンプトテンプレートオプション
SYSTEMシステムプロンプトオプション
ADAPTERLoRA/QLoRAアダプターパスオプション
LICENSEライセンス情報オプション
MESSAGE事前設定された会話履歴オプション

11.2 PARAMETERオプションの詳細

パラメータデフォルト範囲/説明
temperaturefloat0.80.0~2.0。高いほど創造的、低いほど決定的
top_pfloat0.90.0~1.0。Nucleusサンプリング確率閾値
top_kint401~100。上位kトークンのみ考慮
min_pfloat0.00.0~1.0。最小確率フィルタリング
num_predictint-1生成する最大トークン数(-1: 無制限、-2: コンテキスト満了まで)
num_ctxint2048コンテキストウィンドウサイズ(トークン単位)
repeat_penaltyfloat1.1繰り返しペナルティ(1.0で無効)
repeat_last_nint64繰り返しチェック範囲(0: 無効、-1: num_ctx)
seedint0ランダムシード(0は毎回異なる結果)
stopstring-停止文字列(複数指定可能)
num_gpuintautoGPUにオフロードするレイヤー数(0: CPUのみ)
num_threadintautoCPUスレッド数
num_batchint512プロンプト処理バッチサイズ
mirostatint0Mirostatサンプリング(0: 無効、1: Mirostat、2: Mirostat 2.0)
mirostat_etafloat0.1Mirostat学習率
mirostat_taufloat5.0Mirostatターゲットエントロピー
tfs_zfloat1.0Tail-Free Sampling(1.0で無効)
typical_pfloat1.0Locally Typical Sampling(1.0で無効)
use_mlockboolfalseモデルをメモリにロック(スワップ防止)
num_keepint0コンテキストリサイクル時に保持するトークン数
penalize_newlinebooltrue改行トークンにペナルティを適用

11.3 APIでのパラメータ使用

API呼び出しのoptionsフィールドでパラメータを指定します。

curl http://localhost:11434/api/chat -d '{
  "model": "llama3.1",
  "messages": [
    {"role": "user", "content": "Hello"}
  ],
  "options": {
    "temperature": 0.3,
    "top_p": 0.9,
    "top_k": 50,
    "num_ctx": 8192,
    "num_predict": 1024,
    "repeat_penalty": 1.2,
    "seed": 42,
    "stop": ["<|eot_id|>"]
  }
}'

12. Ollama環境変数完全リファレンス

12.1 サーバー・ネットワーク

環境変数デフォルト説明
OLLAMA_HOST127.0.0.1:11434サーバーバインドアドレスとポート
OLLAMA_ORIGINSNoneCORS許可オリジン(カンマ区切り)
OLLAMA_KEEP_ALIVE5mモデルアンロードまでのアイドル時間(5m, 1h, -1=永久)
OLLAMA_MAX_QUEUE512最大キューサイズ(超過時リクエスト拒否)
OLLAMA_NUM_PARALLEL1モデルあたりの同時リクエスト数
OLLAMA_MAX_LOADED_MODELS1(CPU)、GPUs*3同時にロード可能な最大モデル数

12.2 ストレージ・パス

環境変数デフォルト説明
OLLAMA_MODELSOS標準パスモデル保存ディレクトリ
OLLAMA_TMPDIRシステムtemp一時ファイルディレクトリ
OLLAMA_NOPRUNENone起動時の未使用blobクリーンアップを無効化

プラットフォーム別デフォルトモデル保存パス:

OSデフォルトパス
macOS~/.ollama/models
Linux/usr/share/ollama/.ollama/models
WindowsC:\Users\<user>\.ollama\models

12.3 GPU・パフォーマンス

環境変数デフォルト説明
OLLAMA_FLASH_ATTENTION0Flash Attentionを有効化(1に設定)
OLLAMA_KV_CACHE_TYPEf16KV Cacheの量子化タイプ(f16, q8_0, q4_0
OLLAMA_GPU_OVERHEAD0GPUあたりの予約VRAM(バイト)
OLLAMA_LLM_LIBRARYauto特定のLLMライブラリを強制使用
CUDA_VISIBLE_DEVICES全GPU使用するNVIDIA GPUデバイス番号
ROCR_VISIBLE_DEVICES全GPU使用するAMD GPUデバイス番号
GPU_DEVICE_ORDINAL全GPU使用するGPUの順序

12.4 ログ・デバッグ

環境変数デフォルト説明
OLLAMA_DEBUG0デバッグログを有効化(1に設定)
OLLAMA_NOHISTORY0対話モードでreadline履歴を無効化

12.5 コンテキスト・推論

環境変数デフォルト説明
OLLAMA_CONTEXT_LENGTH4096デフォルトコンテキストウィンドウサイズ
OLLAMA_NO_CLOUD0クラウド機能を無効化(1に設定)
HTTPS_PROXY / HTTP_PROXYNoneプロキシサーバー設定
NO_PROXYNoneプロキシバイパスホスト

12.6 環境変数の設定方法

macOS(launchctl):

# 環境変数を設定
launchctl setenv OLLAMA_HOST "0.0.0.0:11434"
launchctl setenv OLLAMA_MODELS "/Volumes/ExternalSSD/ollama/models"
launchctl setenv OLLAMA_FLASH_ATTENTION "1"
launchctl setenv OLLAMA_KV_CACHE_TYPE "q8_0"
launchctl setenv OLLAMA_NUM_PARALLEL "4"
launchctl setenv OLLAMA_KEEP_ALIVE "-1"

# Ollamaを再起動
brew services restart ollama

Linux(systemd):

# systemdサービスオーバーライドを作成
sudo systemctl edit ollama

# エディタで以下を追加:
[Service]
Environment="OLLAMA_HOST=0.0.0.0:11434"
Environment="OLLAMA_MODELS=/data/ollama/models"
Environment="OLLAMA_FLASH_ATTENTION=1"
Environment="OLLAMA_KV_CACHE_TYPE=q8_0"
Environment="OLLAMA_NUM_PARALLEL=4"
Environment="OLLAMA_KEEP_ALIVE=-1"
Environment="OLLAMA_MAX_LOADED_MODELS=3"
Environment="CUDA_VISIBLE_DEVICES=0,1"

# サービスを再起動
sudo systemctl daemon-reload
sudo systemctl restart ollama

Docker:

docker run -d --gpus=all \
  -e OLLAMA_HOST=0.0.0.0:11434 \
  -e OLLAMA_FLASH_ATTENTION=1 \
  -e OLLAMA_KV_CACHE_TYPE=q8_0 \
  -e OLLAMA_NUM_PARALLEL=4 \
  -e OLLAMA_KEEP_ALIVE=-1 \
  -v /data/ollama:/root/.ollama \
  -p 11434:11434 \
  --name ollama \
  ollama/ollama

13. Ollamaの高度な使い方

13.1 Modelfile作成ガイド

韓国語アシスタントモデル:

FROM llama3.1:8b

PARAMETER temperature 0.7
PARAMETER top_p 0.9
PARAMETER num_ctx 4096
PARAMETER num_predict 1024
PARAMETER repeat_penalty 1.15
PARAMETER stop "<|eot_id|>"
PARAMETER stop "<|end_of_text|>"

SYSTEM """
You are a Korean AI assistant well-versed in Korean culture and history.
You always respond accurately and kindly in Korean, using English technical terms alongside when needed.
You provide answers in a structured format.
"""

MESSAGE user Hello, please introduce yourself.
MESSAGE assistant Hello! I'm an AI assistant specialized in Korean. I can help with various topics including Korean culture, history, technology, and more. Feel free to ask me anything!
# モデルを作成
ollama create korean-assistant -f ./Modelfile-korean

# 実行
ollama run korean-assistant "Tell me about the three grand palaces of Seoul"

コードレビューモデル:

FROM qwen2.5-coder:7b

PARAMETER temperature 0.2
PARAMETER top_p 0.85
PARAMETER num_ctx 8192
PARAMETER num_predict 2048

SYSTEM """
You are an expert code reviewer. Analyze code for:
1. Bugs and potential issues
2. Performance improvements
3. Security vulnerabilities
4. Code style and best practices

Provide specific, actionable feedback with corrected code examples.
"""

量子化レベル選択ガイド:

量子化サイズ比品質速度推奨用途
Q2_K約30%低い非常に速いテスト専用
Q3_K_M約37%まずまず速いメモリ制約環境
Q4_0約42%良好速い汎用(デフォルト)
Q4_K_M約45%良好+速い汎用(推奨)
Q5_K_M約53%優秀中程度品質重視
Q6_K約62%非常に優秀中程度高品質が必要な場合
Q8_0約80%最高遅いオリジナルに近い品質
F16100%オリジナル遅いベースライン/ベンチマーク

13.2 GPUアクセラレーション設定

NVIDIA GPU:

# NVIDIAドライバーを確認
nvidia-smi

# 特定のGPUのみを使用
CUDA_VISIBLE_DEVICES=0 ollama serve

# マルチGPU
CUDA_VISIBLE_DEVICES=0,1 ollama serve

AMD GPU(ROCm):

# ROCmドライバーを確認
rocm-smi

# GPUを指定
ROCR_VISIBLE_DEVICES=0 ollama serve

Apple Silicon(Metal):

macOSでは Metal GPUアクセラレーションが自動的に有効化されます。個別の設定は不要です。

# GPU使用状況を確認(ollama psのProcessorカラム)
ollama ps
# NAME           ID            SIZE    PROCESSOR     UNTIL
# llama3.1:8b    a]f2e33d4e25  6.7 GB  100% GPU      4 minutes from now

13.3 Dockerデプロイ

# docker-compose.yaml
version: '3.8'

services:
  ollama:
    image: ollama/ollama
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              count: all
              capabilities: [gpu]
    ports:
      - '11434:11434'
    volumes:
      - ollama_data:/root/.ollama
    environment:
      - OLLAMA_HOST=0.0.0.0:11434
      - OLLAMA_FLASH_ATTENTION=1
      - OLLAMA_KV_CACHE_TYPE=q8_0
      - OLLAMA_NUM_PARALLEL=4
      - OLLAMA_KEEP_ALIVE=24h
    restart: unless-stopped
    healthcheck:
      test: ['CMD', 'curl', '-f', 'http://localhost:11434/api/version']
      interval: 30s
      timeout: 5s
      retries: 3

  # モデル初期化(オプション)
  ollama-init:
    image: curlimages/curl:latest
    depends_on:
      ollama:
        condition: service_healthy
    entrypoint: >
      sh -c "
        curl -s http://ollama:11434/api/pull -d '{\"name\": \"llama3.1:8b\"}' &&
        curl -s http://ollama:11434/api/pull -d '{\"name\": \"nomic-embed-text\"}'
      "

volumes:
  ollama_data:

13.4 マルチモーダルモデルの使用

# LLaVAモデルを実行
ollama run llava "What's in this image? /path/to/photo.jpg"

# Llama 3.2 Vision
ollama run llama3.2-vision "Describe this image in Korean. /path/to/image.png"
import requests
import base64

# 画像をbase64にエンコード
with open("image.jpg", "rb") as f:
    image_base64 = base64.b64encode(f.read()).decode("utf-8")

response = requests.post("http://localhost:11434/api/chat", json={
    "model": "llava",
    "messages": [
        {
            "role": "user",
            "content": "What's in this image?",
            "images": [image_base64],
        }
    ],
    "stream": False,
})
print(response.json()["message"]["content"])

13.5 Tool Calling / Function Calling

OllamaはOpenAI互換のTool Callingをサポートしています。

from openai import OpenAI
import json

client = OpenAI(base_url="http://localhost:11434/v1", api_key="ollama")

tools = [
    {
        "type": "function",
        "function": {
            "name": "get_weather",
            "description": "Get current weather for a city",
            "parameters": {
                "type": "object",
                "properties": {
                    "city": {"type": "string", "description": "City name"},
                    "unit": {
                        "type": "string",
                        "enum": ["celsius", "fahrenheit"],
                    },
                },
                "required": ["city"],
            },
        },
    }
]

response = client.chat.completions.create(
    model="llama3.1",
    messages=[
        {"role": "user", "content": "What's the current weather in Seoul?"}
    ],
    tools=tools,
    tool_choice="auto",
)

message = response.choices[0].message
if message.tool_calls:
    for tool_call in message.tool_calls:
        print(f"Function: {tool_call.function.name}")
        print(f"Arguments: {tool_call.function.arguments}")

Part 3: 比較と実践

14. vLLM vs Ollama比較

14.1 総合比較表

項目vLLMOllama
主な用途本番APIサービング、高スループット推論ローカル開発、プロトタイピング、個人利用
エンジンカスタムエンジン(PagedAttention)llama.cpp
モデル形式HF Safetensors, AWQ, GPTQ, FP8GGUF(量子化済み)
APIOpenAI互換ネイティブ + OpenAI互換
導入難易度中(Python/CUDA環境が必要)非常に簡単(シングルバイナリ)
GPU必須ほぼ必須(NVIDIA/AMD)オプション(CPUで動作可能)
マルチGPUTP + PP(数百GPUまで)自動分散(限定的)
同時処理数百~数千リクエストデフォルト1~4並列
量子化AWQ, GPTQ, FP8, BnBGGUF Q2~Q8, F16
Continuous Batchingサポート非サポート(llama.cppの制限)
PagedAttentionコア技術非サポート
Prefix Cachingサポート(自動)非サポート
LoRAサービングマルチLoRA同時サービングシングルLoRA
構造化出力JSON Schema, Regex, GrammarJSONモード
Speculative Decodingサポート(ドラフトモデル、N-gram)非サポート
ストリーミングサポートサポート
Dockerデプロイ公式イメージ(GPU)公式イメージ(CPU/GPU)
Kubernetes公式ガイド + Production StackコミュニティHelm Chart
メモリ効率非常に高い(4%未満の浪費)高い(GGUF量子化)
ライセンスApache 2.0MIT

14.2 スループット比較(Llama 3.1 8B、RTX 4090)

同時ユーザー数vLLM (tokens/s)Ollama (tokens/s)倍率
1約140約652.2x
5約500約1204.2x
10約800約1505.3x
50約1,200約1508.0x
100約1,500約150(キュー待ち)10.0x

Red Hatのベンチマークでは、同一ハードウェアでvLLMが793 TPS対Ollama 41 TPSと19倍の差を示しました。同時リクエスト数、バッチサイズ、モデルサイズにより変動します。


15. パフォーマンスベンチマーク

15.1 スループット比較

メトリクスvLLMOllama備考
単一リクエストTPS100~140 tok/s50~70 tok/sRTX 4090、Llama 3.1 8B
10同時合計TPS700~900 tok/s120~200 tok/sContinuous Batchingの効果
50同時合計TPS1,000~1,500 tok/s約150 tok/sOllamaはリクエストをキュー
バッチ推論(1Kプロンプト)2,000~3,000 tok/s非サポートvLLMオフライン推論

15.2 レイテンシ比較

メトリクスvLLMOllama備考
TTFT(Time To First Token)50~200 ms100~500 msプロンプト長により変動
TPOT(Time Per Output Token)7~15 ms15~25 ms単一リクエスト基準
P99レイテンシ80~150 ms500~700 ms10同時リクエスト
モデル読み込み時間30~120秒5~30秒GGUFの方が高速読み込み

15.3 メモリ使用量比較(Llama 3.1 8B)

構成vLLM GPUメモリOllama GPUメモリ備考
FP16約16 GBN/AvLLMデフォルト
FP8約9 GBN/AH100のみ
AWQ 4ビット約5 GBN/AvLLM量子化済み
GPTQ 4ビット約5 GBN/AvLLM量子化済み
Q4_K_M(GGUF)N/A約5.5 GBOllamaデフォルト
Q5_K_M(GGUF)N/A約6.2 GB高品質
Q8_0(GGUF)N/A約9 GB最高量子化品質
KV Cache含む(4Kコンテキスト)+0.5~2 GB+0.5~1.5 GBシーケンス数に比例

16. 推奨シナリオ

16.1 個人開発者ローカル環境

推奨: Ollama

# インストールしてすぐに使用
ollama run llama3.1

# VS Code + Continue拡張機能との統合
# settings.jsonでOllamaエンドポイントを設定

理由: シンプルなインストール、CPUで動作、macOS/Windows/Linuxサポート。IDE拡張機能との容易な統合。

16.2 本番APIサービング

推奨: vLLM

vllm serve meta-llama/Llama-3.1-70B-Instruct \
  --tensor-parallel-size 4 \
  --gpu-memory-utilization 0.90 \
  --max-num-seqs 256 \
  --enable-prefix-caching \
  --enable-chunked-prefill \
  --api-key ${API_KEY}

理由: Continuous Batchingによる圧倒的な同時リクエスト処理。PagedAttentionによる高いメモリ効率。成熟したマルチGPUサポート、Kubernetesデプロイ、監視統合。

16.3 エッジ/IoT環境

推奨: Ollama + 高量子化

# 小型モデル + 高量子化
ollama run phi3:3.8b-mini-instruct-4k-q4_0

# またはQwen 0.5B
ollama run qwen2.5:0.5b

理由: シングルバイナリによるシンプルなデプロイ。GGUF量子化で低スペックハードウェアでも動作。CPUのみの推論をサポート。

16.4 大規模バッチ推論

推奨: vLLMオフライン推論

from vllm import LLM, SamplingParams

llm = LLM(
    model="meta-llama/Llama-3.1-8B-Instruct",
    tensor_parallel_size=2,
    gpu_memory_utilization=0.95,
)

# 数千のプロンプトを一括処理
prompts = load_prompts_from_file("prompts.jsonl")  # 10,000以上のプロンプト
sampling_params = SamplingParams(temperature=0.0, max_tokens=512)

outputs = llm.generate(prompts, sampling_params)
save_outputs(outputs, "results.jsonl")

理由: GPUメモリ使用率を最大化するバッチスケジューリング。数千から数万のプロンプトを効率的に処理。

16.5 RAGパイプライン

どちらも可 -- 状況に応じて選択:

# OllamaベースのRAG(開発/小規模)
from langchain_ollama import OllamaLLM, OllamaEmbeddings

llm = OllamaLLM(model="llama3.1")
embeddings = OllamaEmbeddings(model="nomic-embed-text")

# vLLMベースのRAG(本番)
from langchain_openai import ChatOpenAI, OpenAIEmbeddings

llm = ChatOpenAI(
    base_url="http://vllm-server:8000/v1",
    api_key="token",
    model="meta-llama/Llama-3.1-8B-Instruct",
)

17. リクエストトレーシング統合

本番環境でのLLMリクエストの追跡は、デバッグ、監査、パフォーマンス監視に不可欠です。

17.1 vLLMリクエストID追跡

vLLMはOpenAI API互換サーバーで自動的にrequest_idを生成します。カスタムIDを渡すにはextra_bodyを使用します。

from openai import OpenAI
import uuid

client = OpenAI(base_url="http://localhost:8000/v1", api_key="token")

# カスタムrequest_idを渡す
xid = str(uuid.uuid4())

response = client.chat.completions.create(
    model="meta-llama/Llama-3.1-8B-Instruct",
    messages=[{"role": "user", "content": "Hello"}],
    extra_headers={"X-Request-ID": xid},
)

print(f"XID: {xid}")
print(f"Response ID: {response.id}")

17.2 Ollamaリクエスト追跡

OllamaのネイティブAPIは個別のリクエストIDをサポートしていないため、リバースプロキシレベルで処理します。

import requests
import uuid

xid = str(uuid.uuid4())

response = requests.post(
    "http://localhost:11434/api/chat",
    headers={"X-Request-ID": xid},
    json={
        "model": "llama3.1",
        "messages": [{"role": "user", "content": "Hello"}],
        "stream": False,
    },
)

# ログにxidを含める
import logging
logger = logging.getLogger(__name__)
logger.info(f"[xid={xid}] Response: {response.status_code}")

17.3 API GatewayでのX-Request-ID転送

NGINX設定:

upstream vllm_backend {
    server vllm-server:8000;
}

server {
    listen 80;

    location /v1/ {
        # X-Request-IDが未指定の場合は自動生成
        set $request_id $http_x_request_id;
        if ($request_id = "") {
            set $request_id $request_id;
        }

        proxy_pass http://vllm_backend;
        proxy_set_header X-Request-ID $request_id;
        proxy_set_header Host $host;

        # レスポンスヘッダーにX-Request-IDを追加
        add_header X-Request-ID $request_id always;

        # アクセスログにrequest_idを含める
        access_log /var/log/nginx/vllm_access.log combined_with_xid;
    }
}

# ログフォーマット定義
log_format combined_with_xid '$remote_addr - $remote_user [$time_local] '
    '"$request" $status $body_bytes_sent '
    '"$http_referer" "$http_user_agent" '
    'xid="$http_x_request_id"';

17.4 OpenTelemetry統合

# vLLM + OpenTelemetry分散トレーシング
from opentelemetry import trace
from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor

# Tracerの初期化
provider = TracerProvider()
exporter = OTLPSpanExporter(endpoint="http://jaeger:4317")
provider.add_span_processor(BatchSpanProcessor(exporter))
trace.set_tracer_provider(provider)
tracer = trace.get_tracer(__name__)

# LLM呼び出しをSpanでラップ
def call_llm(prompt: str, xid: str) -> str:
    with tracer.start_as_current_span("llm_inference") as span:
        span.set_attribute("xid", xid)
        span.set_attribute("model", "llama-3.1-8b")
        span.set_attribute("prompt_length", len(prompt))

        response = client.chat.completions.create(
            model="meta-llama/Llama-3.1-8B-Instruct",
            messages=[{"role": "user", "content": prompt}],
            extra_headers={"X-Request-ID": xid},
        )

        result = response.choices[0].message.content
        span.set_attribute("response_length", len(result))
        span.set_attribute("tokens_used", response.usage.total_tokens)

        return result

17.5 ログにおけるxid使用パターン

Pythonの例:

import logging
import uuid
from contextvars import ContextVar

# Context Variableでxidを管理
request_xid: ContextVar[str] = ContextVar("request_xid", default="")

class XIDFilter(logging.Filter):
    def filter(self, record):
        record.xid = request_xid.get("")
        return True

# Loggerセットアップ
handler = logging.StreamHandler()
handler.setFormatter(logging.Formatter(
    "%(asctime)s [%(levelname)s] [xid=%(xid)s] %(message)s"
))
handler.addFilter(XIDFilter())

logger = logging.getLogger("llm_service")
logger.addHandler(handler)
logger.setLevel(logging.INFO)

# 使用例
async def handle_request(prompt: str):
    xid = str(uuid.uuid4())
    request_xid.set(xid)

    logger.info(f"Received prompt: {prompt[:50]}...")

    response = await call_llm(prompt, xid)

    logger.info(f"Generated {len(response)} chars")
    return {"xid": xid, "response": response}

Goの例:

package main

import (
    "context"
    "fmt"
    "log/slog"
    "net/http"

    "github.com/google/uuid"
)

type contextKey string
const xidKey contextKey = "xid"

// XIDミドルウェア
func xidMiddleware(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        xid := r.Header.Get("X-Request-ID")
        if xid == "" {
            xid = uuid.New().String()
        }

        ctx := context.WithValue(r.Context(), xidKey, xid)
        w.Header().Set("X-Request-ID", xid)

        slog.Info("request received",
            "xid", xid,
            "method", r.Method,
            "path", r.URL.Path,
        )

        next.ServeHTTP(w, r.WithContext(ctx))
    })
}

// Ollama呼び出し関数
func callOllama(ctx context.Context, prompt string) (string, error) {
    xid := ctx.Value(xidKey).(string)

    slog.Info("calling ollama",
        "xid", xid,
        "prompt_len", len(prompt),
    )

    // ... Ollama API呼び出しロジック ...

    slog.Info("ollama response received",
        "xid", xid,
        "response_len", len(response),
    )

    return response, nil
}

18. 参考文献

vLLM

Ollama

論文・技術リソース

関連プロジェクト

クイズ

Q1: 「vLLM & Ollama完全ガイド: LLMサービングエンジンのセットアップ、パラメータ、環境変数」の主なトピックは何ですか?

vLLM PagedAttentionアーキテクチャとOllamaローカルLLMランタイム環境を包括的に比較・深掘りします。インストール、サーバー起動、API呼び出し、主要CLIオプション、サンプリングパラメータ、環境変数、量子化(AWQ/GPTQ/GGUF)、マルチGPU構成、Dockerデプロイ、パフォーマンスチューニングまで -- すべてのLLMサービング設定を実践例とともに解説します。

Q2: vLLM入門とは何ですか? vLLMはUC Berkeleyで開発された高性能LLM推論・サービングエンジンです。2023年にPagedAttention論文とともに公開されて以来、本番環境LLMサービングのデファクトスタンダードとしての地位を確立しました。2026年3月時点で最新バージョンはv0.16.xで、V1アーキテクチャへの移行が進行中です。 1.1 PagedAttentionのコア原理 従来のLLM推論では、KV CacheはシーケンスごとにGPUメモリ上の連続ブロックに割り当てられます。

Q3: vLLMのインストールと起動の主な手順は何ですか? 2.1 pipインストール 2.2 condaインストール 2.3 Dockerインストール 2.4 基本サーバー起動 config.yamlの例: 2.5 オフラインバッチ推論 サーバーを起動せずに、Pythonコードから直接バッチ推論を実行できます。 2.6 OpenAI互換APIサーバー vLLMサーバーはOpenAI API互換エンドポイントを提供します。

Q4: vLLM CLIオプション完全リファレンスの主な特徴は何ですか? vllm serveに渡すことができる主要なCLIオプションをカテゴリ別にまとめます。完全なリストはvllm serve --helpで確認でき、グループ別にはvllm serve --help=ModelConfigで照会できます。

Q5: vLLMサンプリングパラメータはどのように機能しますか? vLLMはOpenAI API互換パラメータに加え、追加の高度なパラメータをサポートしています。 4.1 パラメータ完全リファレンス 4.2 curlによるAPI呼び出し例 4.3 Python requestsの例 4.4 OpenAI SDKによるStreaming例