第5部 どうやってモデルを動かすのか第6章

推論ランタイムとは何か

モデルファイルは、それだけでは何もしてくれません。読み込み、計算し、1文字ずつ返事を出す係が推論ランタイムです。llama.cpp や vLLM がどんな仕事をしているのかを、内側からのぞきます。

約13分で読めます2026年10月改訂

このページの内容(11項目)
  1. モデルは「楽譜」、ランタイムは「演奏者」
  2. ランタイムが毎回やっている5つの仕事
  3. 速さは2種類ある: プリフィルとデコード
  4. KVキャッシュ: 毎回読み直さないための議事録
  5. ランタイムの中の層: エンジン・バックエンド・ハードウェア
  6. 1人用と大勢用: ローカル型とサーバ型
  7. ランタイム・ラッパー・画面: 混ざりやすい用語の整理
  8. どれを選ぶ? ざっくりした目安
  9. 次に読む章
  10. さらに深く学ぶ
  11. 出典・参考

5GBのモデルファイルをダブルクリックしても、何も起きません。

Hugging Face から苦労してダウンロードした .gguf や .safetensors。中身は数十億個の数字が並んでいるだけで、自分から動き出すことはありません。CDの音楽データが、プレーヤーなしでは音にならないのと同じです。

この「数字の山」を読み込み、あなたの質問を計算にかけ、返事を1トークンずつ取り出してくれるソフトウェア。それが推論ランタイムです。この章では、llama.cpp も vLLM も Ollama も、根っこではみんな同じ仕事をしていることを確かめていきます。

モデルは「楽譜」、ランタイムは「演奏者」

ひとことで言うと

推論ランタイム(inference runtime)は、モデルファイルを読み込み、入力から出力を計算して返すソフトウェアです。モデルが「何を計算するか」を決め、ランタイムが「どう速く・少ないメモリで計算するか」を担当します。

ここでいう推論(inference)は、学習済みの重みを使って答えを出すことです。重みを変える「学習」とは別のイベントで、推論のあいだモデルの中身は一切変わりません(第1章)。

モデルファイルは楽譜、推論ランタイムは演奏者です。同じ楽譜でも、ピアニストが変われば演奏のテンポも、必要な練習量(メモリ)も変わります。ただし楽譜そのもの、つまり「どの音を鳴らすか」はどの演奏者でも同じです。

だから「同じモデルなのに、アプリによって速さが全然違う」ということが起きます。速さの差はモデルではなく、ほとんどがランタイムと、その下で使っているハードウェアの差です。

flowchart TD
  A["モデルファイル
重み・トークナイザ"] --> R["推論ランタイム"] P["あなたの入力
プロンプト"] --> R R --> H["CPU・GPUで計算"] H --> R R --> O["返事
1トークンずつ"]
図1: ランタイムは、モデルと入力を受け取り、ハードウェアで計算させて返事を出す

ランタイムが毎回やっている5つの仕事

「こんにちは」と送ってから返事が出るまでに、ランタイムの中ではだいたい次の順番で処理が進みます。どのランタイムでも骨格は同じです。

  1. 読み込み(ロード) — モデルファイルの重みをメモリ(RAMやGPUのVRAM)に載せます。大きなモデルほど時間がかかるので、多くのランタイムは一度載せたら一定時間そのまま置いておきます。
  2. 前処理 — 会話をモデルが学習時に見た書式(チャットテンプレート)に整え、トークナイザで数字の列(トークンID)に変換します。
  3. 計算(フォワードパス) — トークン列をモデルに通し、「次に来るトークン」の確率分布を出します。ここが一番重い処理です。
  4. サンプリング — 確率分布から1つのトークンを選びます。温度(temperature)や top-p はここで効きます(第2章)。
  5. 後処理と出力 — 選んだトークンを文字に戻して画面に流し、3〜5を「終わりの記号」が出るまで繰り返します。
flowchart TD
  L["1 ロード
重みをメモリへ"] --> T["2 前処理
テンプレートとトークン化"] T --> F["3 計算
次トークンの確率"] F --> S["4 サンプリング
1つ選ぶ"] S --> D["5 文字に戻して表示"] D --> E{"終わりの記号?"} E -- "いいえ" --> F E -- "はい" --> Z["返事完成"]
図2: 3〜5のループを何百回も回して、1つの返事ができあがる

チャット画面で文字がパラパラと流れてくるのは、演出ではなくこのループの結果です。1周ごとに1トークンずつしか決まらないので、出てきた順に表示しているのです。

速さは2種類ある: プリフィルとデコード

ひとことで言うと

入力を読むプリフィル(prefill)と、返事を1トークンずつ書くデコード(decode)は、同じモデルでも詰まりどころが違います。

プリフィルでは、入力されたトークンをまとめて一気に計算できます。並列に計算できる量が多いので、GPUの計算性能(FLOPS)が効きます。長い文書を貼り付けたときに「最初の1文字が出るまで」待たされるのは、このプリフィルの時間です。

デコードは1トークンずつしか進めません。1トークン作るたびに、モデルの重み全体と、これまでの文脈の情報をメモリから読み出す必要があります。計算そのものは少ないのに読み出しが多いので、効くのはメモリ帯域(1秒あたりに運べるデータ量)です。

プリフィルデコード
やること入力をまとめて読む返事を1トークンずつ書く
主な制約計算性能メモリ帯域
体感で現れる場所最初の1文字までの待ち時間文字が流れる速さ
よく見る指標TTFT(最初のトークンまでの時間)トークン/秒

デコードの速さの上限は「メモリ帯域 ÷ 1トークンで読み出す重みの量」でざっくり見積もれます。量子化で重みを小さくすると速くなり、MoE(第26章)では使う専門家の分だけ読めばよいので速くなる——その理由が数字で見えます。

Apple シリコンの Mac がローカルLLMで人気なのは、CPUとGPUが同じ大容量メモリを共有でき、帯域も比較的広いからです。ハードウェアの話は第17章でくわしく扱います。

KVキャッシュ: 毎回読み直さないための議事録

デコードのたびに、文章の最初から全部計算し直していたら大変です。そこでランタイムは、計算済みのトークンについて attention で使う中間結果(Key と Value)を保存しておきます。これが KVキャッシュ(KV cache)です。

KVキャッシュは「会議の議事録」です。新しく発言するたびに会議を最初から再生するのではなく、議事録を見返して続きを話す。おかげで速くなりますが、会議が長くなるほど議事録は分厚くなり、置き場所(メモリ)を取ります。

KVキャッシュの大きさは、文脈の長さ(コンテキスト長)と、同時にさばく会話の数にほぼ比例します。モデルの重みが載っても、長い文脈を使うとKVキャッシュでメモリがあふれる、ということがよく起きます。下で実際に見積もってみてください。

KVキャッシュをどう置き、どう使い回すかは、ランタイムの腕の見せどころです。サーバ向けの vLLM が有名になったのも、このKVキャッシュの管理方法(PagedAttention)がきっかけでした(第9章、第15章)。

ランタイムの中の層: エンジン・バックエンド・ハードウェア

ランタイムの内側も、何層かに分かれています。上の層ほど「人に近く」、下の層ほど「チップに近い」と考えるとわかりやすいです。

flowchart TD
  A["アプリ・API
チャット画面やHTTPサーバ"] --> B["推論エンジン
スケジュールとKVキャッシュ管理"] B --> C["計算ライブラリ
ggml・PyTorchなど"] C --> D["バックエンド
CUDA・Metal・Vulkanなど"] D --> E["ハードウェア
CPU・GPU・NPU"]
図3: ランタイムの層構造。名前の切り方はプロジェクトによって少しずつ違う

推論エンジン inference engine

リクエストを受け取り、どの順番で計算するか(スケジューリング)、KVキャッシュをどう置くかを決める中核部分。「ランタイム」とほぼ同じ意味で使われることも多い言葉です。

バックエンド backend

行列の掛け算などを、特定のハードウェアで実際に実行する部分。NVIDIA GPU なら CUDA、Mac なら Metal、幅広いGPU向けには Vulkan、といった具合です。llama.cpp の README には CUDA、Metal、Vulkan、HIP(AMD)、SYCL(Intel)など十数種類のバックエンドが並んでいます2026年10月時点。

たとえば llama.cpp は自前の計算ライブラリ ggml の上に作られ、vLLM は PyTorch の上に作られています。同じ「NVIDIA GPU で動く」でも、通っている道がまったく違うわけです。

1人用と大勢用: ローカル型とサーバ型

ランタイムは大きく2つの系統に分かれます。手元のPCで1人が使うことを重視するローカル型と、データセンターで大勢のリクエストをさばくサーバ型です。

ローカル型は「家庭用のコーヒーメーカー」。どの家のキッチンにも置けて、1杯ずつおいしく淹れられることが大事です。サーバ型は「カフェの業務用マシン」。行列ができても、1時間に何百杯も出せることが大事です。

ローカル型サーバ型
代表例llama.cpp、MLX(mlx-lm)vLLM、SGLang、TensorRT-LLM
主な目標小さなメモリで動く、どこでも動く多人数で合計の処理量を最大に
よく使う形式GGUF、MLX形式safetensors(Hugging Face形式)
得意な場所ノートPC、Mac、ゲーミングPCデータセンターのGPUサーバ

サーバ型の鍵はバッチ処理です。デコードはメモリの読み出しが詰まりどころでした。そこで、何人分もの会話をまとめて1回の読み出しで計算すれば、同じ時間でずっと多くのトークンを作れます。リクエストが来るたびにバッチへ出し入れする「連続バッチ処理(continuous batching)」は、いまのサーバ型ランタイムの基本装備です。

とはいえ境界はゆるやかです。llama.cpp に付属するサーバ(llama-server)も複数ユーザーの並列処理や連続バッチ処理に対応していますし、vLLM も CPU や Apple シリコン向けのプラグインを持っています2026年10月時点。「どちらを主戦場として設計されたか」の違いだと考えてください。

ランタイム・ラッパー・画面: 混ざりやすい用語の整理

「Ollama は推論ランタイムですか?」という質問は、答えるのが意外とむずかしいものです。Ollama は内部で llama.cpp などのエンジンを使い、モデルのダウンロードや管理、APIサーバの機能をかぶせています。このような道具はラッパー(包むもの)と呼ばれることがあります。

呼び方役割例
エンジン・ランタイム実際に計算するllama.cpp、vLLM、SGLang、MLX
ラッパー・管理ツールエンジンを包み、ダウンロードや設定を楽にするOllama、LM Studio
サーバ・APIHTTP経由で他のアプリから使えるようにするllama-server、vllm serve
フロントエンド人が触るチャット画面Open WebUI、各アプリの画面

ひとつの製品が複数の役割を兼ねることも普通です。LM Studio は画面・管理・APIサーバを1つにまとめ、計算は llama.cpp や MLX に任せています。ローカル向けの道具の整理は第8章で続けます。

もう一歩深く

多くのランタイムは OpenAI の Chat Completions API と同じ形のHTTP APIを用意しています(OpenAI互換API)。おかげで、アプリ側は接続先のURLを変えるだけで、クラウドのAPIから手元のランタイムへ乗り換えられます。llama-server や Ollama、vLLM などは Anthropic の Messages API 互換の窓口も持つようになりました2026年10月時点。

どれを選ぶ? ざっくりした目安

flowchart TD
  Q["誰が使う?"] --> A["自分1人・手元のPC"]
  Q --> B["チームや大勢・GPUサーバ"]
  A --> A1["まず触りたい
Ollama・LM Studio"] A --> A2["細かく調整したい
llama.cpp・mlx-lm"] B --> B1["汎用で始める
vLLM・SGLang"] B --> B2["NVIDIAで攻める
TensorRT-LLM"]
図4: 最初の選び方の目安。迷ったら上の段から試す

最初の一歩なら、まず Ollama や LM Studio で「手元で動く」体験をするのがおすすめです。慣れてきたら、その中で動いている llama.cpp を直接触ると、ランタイムの設定がどう速さやメモリに効くのかが見えてきます。

よくある誤解

モデルが同じなら、どのアプリで動かしても速さは同じ

速さとメモリ使用量はランタイムとハードウェアでかなり変わる。変わらないのは「何を計算するか」のほう

推論中、AIは会話から学習して賢くなっている

推論では重みは変わらない。前の会話を覚えているように見えるのは、それまでのやりとりを毎回入力に含めているから

GPUの計算性能が高ければ、文字が流れる速さも必ず上がる

1人で使うときのデコード速度は主にメモリ帯域で決まる。計算性能が効くのは主にプリフィル

確認クイズ

Q1. 長い資料を貼り付けたら、最初の1文字が出るまで時間がかかった。主にどの段階の時間?

プリフィルです。入力をまとめて読み込み、KVキャッシュを作っている時間で、主に計算性能に左右されます。返事が流れ始めてからの速さはデコードの領分です。

Q2. KVキャッシュを保存しておく一番の目的は?

  • モデルの重みを圧縮するため
  • 過去のトークンの計算をやり直さずに済ませるため
  • 会話からモデルを学習させるため

KVキャッシュは「議事録」。計算済みの Key と Value を取っておき、次のトークンを作るときに使い回します。そのぶん、文脈が長いほどメモリを使います。

Q3. 大勢のリクエストをまとめて計算する「バッチ処理」が、サーバで特に効くのはなぜ?

  • まとめると計算結果が正確になるから
  • 1回の重みの読み出しで、何人分ものトークンを作れるから
  • まとめるとモデルが小さくなるから

デコードは重みの読み出しが詰まりどころ。読み出しを何人分にも分け合えるので、合計の処理量(スループット)が大きく伸びます。

この章のまとめ

  • 推論ランタイムは、モデルファイルを読み込み、入力から返事を計算するソフトウェア
  • 処理は「ロード→前処理→計算→サンプリング→出力」で、後半を1トークンずつ繰り返す
  • 入力を読むプリフィルは計算性能、返事を書くデコードはメモリ帯域が効く
  • KVキャッシュは速さのための「議事録」。文脈が長いほどメモリを食う
  • ローカル型は「どこでも小さく」、サーバ型は「大勢を効率よく」を目指している

次に読む章

さらに深く学ぶ

この章の内容をもう一歩掘り下げるための原典です。

第6章の論文・資料をすべて見る →

出典・参考

  1. llama.app Docs, “Prefill vs. Decode” — プリフィルは計算律速、デコードはメモリ帯域律速、バッチでスループットが上がる理由(2026年10月確認)
  2. ggml-org/llama.cpp(GitHub) — README の対応バックエンド一覧(2026年10月確認)
  3. llama.cpp HTTP Server README — 並列デコード、連続バッチ処理、OpenAI/Anthropic互換API(2026年10月確認)
  4. Kwon et al., “Efficient Memory Management for Large Language Model Serving with PagedAttention” (2023), arXiv:2309.06180 — vLLM と PagedAttention の論文
  5. vllm-project/vllm(GitHub) — 連続バッチ処理、対応ハードウェアとプラグイン(2026年10月確認)
  6. ollama/ollama(GitHub) — README の「Supported backends」に llama.cpp を記載(2026年10月確認)