Ollamaは、モデル読み込み時のメモリ負担とリクエストの待ち時間を減らすプレビュー版を公開した。CPUとメモリを共有する統合グラフィックスの利用者はモデル読み込みの失敗を減らす変更を、複数のリクエストを受けるサービス運営者は生成リクエストを同時処理する機能を確認できる。
1. 読み込みの失敗と生成の待ち時間にそれぞれ対応
2026年11月10日に公開されたv0.40.17-rc0は、モデルを読み込む段階とリクエストを処理する段階のボトルネック、つまり処理を遅らせる主な箇所をそれぞれ見直した。同じメモリを共有するグラフィックスの読み込み問題と、複数のリクエストが重なったときの待ち時間を狙った変更だ。
統合グラフィックス側では、モデルデータが同じメモリ予算、つまりデバイスが使用できるメモリ上限を重複して占有する問題を減らす。MLX側では、1つのリクエストが終わるまで次を待たせる代わりに、複数のリクエストが計算資源を共有するようにした。
2. Vulkan統合グラフィックスはメモリマップで読み込む
従来の読み込み方式は、CPU側に残るモデルデータをVulkanのホストバッファという領域に置く。この領域も、モデルが学習した数値情報である重みと同じデバイスメモリ予算を使うため、統合グラフィックスではメモリ使用量が約2倍になり、読み込みに失敗し得るとOllamaの変更提案は説明した。報告された症状には、メモリの固定割り当て失敗とWindowsのAMD環境でのエラーが含まれた。
OllamaはVulkan統合グラフィックスを検出するとmmapを自動選択し、メモリマップ方式で読み込むようにした。OSのキャッシュを経由しない読み取り方式であるダイレクトI/Oでもホストバッファを回避できないため、読み込み経路自体を変えた。対象はCPUとメモリを共有する統合グラフィックスだ。
以下は変更された関数の原文の一部だ。
// appendLoadModeArgs selects llama-server's single model loading mode. Integrated
// GPUs share memory with the CPU: Linux CUDA/ROCm use direct I/O to skip the page
// cache, while Vulkan uses mmap because non-mmap loads place CPU-resident tensors
// in a host buffer drawn from the same device budget as the weights.
func appendLoadModeArgs(params []string, opts api.Options, gpus []ml.DeviceInfo) []string {
for _, g := range gpus {
if !g.Integrated {
continue
}
if strings.EqualFold(g.Library, "Vulkan") {3. MLXが複数の生成リクエストを同時処理
MLXモデルでは、OLLAMA_NUM_PARALLELで同時に処理する生成リクエスト数を設定できる。デフォルトは1リクエストで、値を増やすとアクティブなリクエストごとに追加のメモリが必要になる。設定を2にすると、2つのリクエストが同時に来た際、順番待ちのリクエストも早くトークンを受け取り始められる。
複数のリクエストは、まとめて計算できる部分を一括処理するが、再利用するデータを一時保存するキャッシュと応答の流れはリクエストごとに分けて維持する。1つのリクエストの入力をすべて処理してから次へ進む代わりに、モデルに入力する指示や文脈であるプロンプトを2048トークンずつに分け、応答生成と交互に処理する方式だ。利用者による設定例は次のとおりだ。
OLLAMA_NUM_PARALLEL=2同社発表の性能測定は、モデルの数値を縮小してメモリを節約するNVFP4量子化を適用したモデルをApple M5 Maxで実行した結果で、値は秒単位の中央値だ。2つのクライアントが同時にリクエストした条件で、ベースラインは逐次処理し、変更版はリクエストを交互に処理した。以下の表は、待機中リクエストが応答を受け取り始めるまでの時間と、両方のリクエストが完了するまでの時間を示す。
表:同時リクエストの応答開始と全体の完了時間
条件:NVFP4、p4096/g256、Apple M5 Max; OLLAMA_NUM_PARALLEL=2; 2つのクライアントが同時送信; ベースラインはmainの逐次処理、変更版は交互処理
単位:秒(中央値)
| モデル | 2番目の開始・ベースライン | 2番目の開始・変更版 | 全完了・ベースライン | 全完了・変更版 |
|---|---|---|---|---|
| Gemma 4 12B | 7.45 | 4.69 | 9.57 | 10.19 |
| Qwen 3.8 27B | 13.84 | 9.90 | 17.23 | 20.07 |
| Nemotron 3.5 Lightning 30B-A3B | 3.31 | 1.65 | 4.99 | 4.93 |
この条件では、3モデルすべてで待機中リクエストの応答開始が早まった。両リクエストの全体の完了時間はGemmaとQwenで延び、Nemotronではほぼ同じだった。単一リクエストの性能はベースラインに近い水準だと変更提案は説明した。
4. 応答待ち時間と処理コストのトレードオフ
同時処理は、待機中リクエストに早く応答する代わりに、最初のリクエストが使っていたグラフィックスの計算資源を分け合う。生成内容を事前に予測して高速化する手法も、複数のリクエストが実行されている間は停止する。運営者が得る利点は待ち時間の短縮で、その代償はリクエストごとのメモリ増加と、一部モデルでの全体の完了時間の増加だ。
リクエストごとに分けたキャッシュでは、リクエストが休止中もメモリが占有され、入力の共通の先頭部分が重複保存される。開発陣は、キャッシュ保持予算の共有、未使用メモリの回収、共通入力の再利用を今後の改善として計画した。
今回のリリースはプレビュー版で、測定結果は表に示したモデル・設定・ハードウェアの条件に対応する。
v0.40.17-rc0は共有メモリ環境の読み込み負担を減らし、MLXの待機中リクエストに早く応答する道を開くが、同時生成ではメモリと全体の完了時間のコストも併せて検討する必要がある。
