Ollama 多顯卡使用筆記:顯存疊加、GPU 選擇和常見誤區

整理 Ollama 多顯卡使用中的關鍵資訊:什麼時候會跨 GPU 載入模型、如何用 CUDA_VISIBLE_DEVICES / ROCR_VISIBLE_DEVICES 限制顯卡、顯存是否能疊加、不同 GPU 能不能混用,以及 Docker、PCIe 頻寬和效能方面的常見誤區。

折騰 Ollama 本地推理時,經常會遇到類似問題:我現在有一張顯卡,主機板還有空 PCIe 槽,再加幾張 GPU 對 Ollama 有幫助嗎?多顯卡是否必須同型號?顯存能不能疊加?會不會像訓練框架那樣多卡並行加速?

這篇整理一下 Ollama 多顯卡的實際行為。重點先說結論:

  • Ollama 支援多 GPU。
  • 多 GPU 最大價值通常是讓更大的模型放進總顯存,而不是線性提升 token/s。
  • 預設策略下,如果模型能完整放進某一張 GPU,Ollama 傾向於放在單卡上。
  • 如果模型無法完整放進單張 GPU,Ollama 會把模型分布到可用 GPU 上。
  • 不同型號 GPU 可以被 Ollama 看到並使用,但效能和分配效果不一定理想。
  • 不需要 SLI / NVLink 才能用多卡。
  • 想限制 Ollama 使用哪些 GPU,需要用 CUDA_VISIBLE_DEVICESROCR_VISIBLE_DEVICESGGML_VK_VISIBLE_DEVICES

官方行為:先單卡,放不下再多卡

Ollama FAQ 裡對多 GPU 載入邏輯說得比較直接:載入新模型時,Ollama 會估算模型所需 VRAM,並和目前可用顯存比較。如果模型能完整放進某一張 GPU,它會載入到那張 GPU 上;如果單張 GPU 放不下,才會分布到所有可用 GPU 上。

這個策略的原因是效能。單卡載入通常能減少推理時跨 PCIe 匯流排的資料傳輸,因此往往更快。

所以不要把 Ollama 的多 GPU 理解成「有幾張卡就自動幾倍加速」。更準確的理解是:

  • 小模型能進單卡:通常單卡跑。
  • 大模型單卡放不下:跨多卡分層載入。
  • 顯存仍不夠:一部分會落到系統記憶體,速度會明顯下降。

可以用下面命令確認模型到底載入到了哪裡:

1
ollama ps

輸出裡的 PROCESSOR 會顯示類似:

1
2
3
100% GPU
48%/52% CPU/GPU
100% CPU

如果看到 48%/52% CPU/GPU,說明已經有一部分在系統記憶體裡了。此時多加 GPU 或換更大顯存的卡,通常比繼續依賴 CPU/RAM 更有意義。

多 GPU 不是簡單疊算力

本地大模型推理和遊戲裡的 SLI 不是一回事。Ollama 多卡時,更常見的是把模型的不同層或張量放到不同裝置上。這樣可以用多張卡的顯存裝下更大的模型,但推理過程中仍然可能需要裝置之間傳遞資料。

因此,多 GPU 帶來的收益通常分兩種:

  • 顯存收益:更容易裝下大模型,或者避免落到 CPU/RAM。
  • 效能收益:只有在原本單卡裝不下或嚴重混 CPU 時,提升才會很明顯。

如果一個 8B 或 14B 模型本來就能完整放進單張 3090,強行拆到兩張卡不一定更快,甚至可能因為跨卡傳輸變慢。Ollama 官方預設「能單卡就單卡」的策略,就是為了避免這類不必要的跨 PCIe 開銷。

Ollama 多 GPU 不依賴 SLI。多張普通 PCIe GPU 只要驅動和 Ollama 能識別,就可以被調度。

NVLink 或更高 PCIe 頻寬可能對某些跨卡場景有幫助,但它不是 Ollama 多 GPU 的前提條件。很多二手 GPU 伺服器或工作站,靠普通 PCIe 多卡也能跑。

真正要注意的是 PCIe 頻寬。x1x4x8x16 的差異會影響模型載入到顯存的速度;如果頻繁切換大模型,PCIe 鏈路會更容易成為瓶頸。模型載入完成後,生成階段受 PCIe 的影響通常會小一些,但跨卡分層仍然可能帶來額外開銷。

比較穩的建議是:

  • 能用 x16 / x8 就不要用礦卡 x1 轉接。
  • 大模型頻繁切換時,PCIe 頻寬更重要。
  • 如果模型長期常駐顯存,PCIe 頻寬瓶頸會相對不明顯。
  • 多卡機器要重點看主機板 PCIe 拓撲和 CPU 直連通道。

如何限制 Ollama 使用哪些 NVIDIA GPU

NVIDIA 多卡環境下,用 CUDA_VISIBLE_DEVICES 控制 Ollama 能看到哪些卡。

臨時執行:

1
CUDA_VISIBLE_DEVICES=0,1 ollama serve

只讓 Ollama 用第二張卡:

1
CUDA_VISIBLE_DEVICES=1 ollama serve

強制不用 NVIDIA GPU,可以給一個無效 ID:

1
CUDA_VISIBLE_DEVICES=-1 ollama serve

官方文件提醒,數字 ID 的順序可能變化,更可靠的是用 GPU UUID。先查看 UUID:

1
nvidia-smi -L

輸出類似:

1
2
GPU 0: NVIDIA GeForce RTX 3090 (UUID: GPU-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)
GPU 1: NVIDIA GeForce RTX 3070 (UUID: GPU-yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy)

然後指定 UUID:

1
CUDA_VISIBLE_DEVICES=GPU-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx ollama serve

如果 Ollama 是 Linux systemd 服務安裝的,需要寫到服務環境變數裡:

1
sudo systemctl edit ollama.service

加入:

1
2
[Service]
Environment="CUDA_VISIBLE_DEVICES=0,1"

然後重載並重啟:

1
2
sudo systemctl daemon-reload
sudo systemctl restart ollama

AMD 和 Vulkan 的選擇變數

AMD ROCm 環境下,用 ROCR_VISIBLE_DEVICES 控制可見 GPU:

1
ROCR_VISIBLE_DEVICES=0,1 ollama serve

如果要強制不用 ROCm GPU,也可以用無效 ID:

1
ROCR_VISIBLE_DEVICES=-1 ollama serve

Ollama 官方 GPU 文件還提到,如果用實驗性的 Vulkan 支援,可以透過 GGML_VK_VISIBLE_DEVICES 選擇 Vulkan GPU:

1
OLLAMA_VULKAN=1 GGML_VK_VISIBLE_DEVICES=0 ollama serve

如果 Vulkan 裝置有問題,可以停用:

1
GGML_VK_VISIBLE_DEVICES=-1 ollama serve

AMD 多卡比 NVIDIA 更容易遇到驅動、ROCm 版本、GFX 版本支援的問題。官方文件中也提到 Linux 下 ROCm 驅動版本、HSA_OVERRIDE_GFX_VERSION 等相容性處理。多張不同代 AMD 卡混用時,先確認每張卡是否單獨可用,再考慮多卡。

Docker 裡怎麼暴露多張 GPU

如果用 Docker 跑 Ollama,NVIDIA 環境通常需要先安裝 nvidia-container-toolkit,然後用 --gpus 暴露裝置。

暴露全部 GPU:

1
2
3
4
5
6
docker run -d \
  --gpus=all \
  -v ollama:/root/.ollama \
  -p 11434:11434 \
  --name ollama \
  ollama/ollama

只暴露指定 GPU:

1
2
3
4
5
6
docker run -d \
  --gpus '"device=0,1"' \
  -v ollama:/root/.ollama \
  -p 11434:11434 \
  --name ollama \
  ollama/ollama

也可以結合環境變數:

1
2
3
4
5
6
7
docker run -d \
  --gpus=all \
  -e CUDA_VISIBLE_DEVICES=0,1 \
  -v ollama:/root/.ollama \
  -p 11434:11434 \
  --name ollama \
  ollama/ollama

如果容器裡 nvidia-smi 看不到卡,Ollama 也不可能用到 GPU。先排查 Docker GPU passthrough,再排查 Ollama。

OLLAMA_SCHED_SPREAD 是什麼

在一些多 GPU 配置討論裡,會看到 OLLAMA_SCHED_SPREAD=1OLLAMA_SCHED_SPREAD=true。它和 Ollama 的調度策略有關,常被用於希望模型或請求更分散地利用多張 GPU 的場景。

可以這樣設定:

1
OLLAMA_SCHED_SPREAD=1 ollama serve

或者 systemd:

1
2
[Service]
Environment="OLLAMA_SCHED_SPREAD=true"

不過它不是萬能開關。開啟後並不等於 token/s 線性增長,也可能因為多個模型同時載入、顯存估算、上下文長度和 KV cache 增長導致 OOM。官方 FAQ 的核心策略仍然是:如果單 GPU 能完整容納模型,單 GPU 通常更高效;單 GPU 放不下時才跨多 GPU。

所以建議把 OLLAMA_SCHED_SPREAD 當成進階調度實驗項,而不是多卡必開項。先理解預設行為,再根據實際 ollama ps、日誌和 nvidia-smi 觀察結果調整。

怎麼觀察多卡是否真的用上

常用觀察命令:

1
ollama ps
1
watch -n 0.5 nvidia-smi

查看 Ollama 服務日誌:

1
journalctl -u ollama -f

如果使用 Docker:

1
docker logs -f ollama

你需要關注:

  • Ollama 是否發現相容 GPU。
  • 模型是否顯示 100% GPU 或 CPU/GPU 混合。
  • 每張卡顯存是否有占用。
  • 載入模型時是否多卡顯存同時增長。
  • 生成時 token/s 是否比 CPU/RAM 混跑明顯改善。
  • 是否頻繁 OOM 或卸載模型。

如果只看 GPU 利用率,很容易誤判。LLM 推理時 GPU 利用率不一定長期滿載,尤其是多卡、低 batch、小上下文、慢 CPU 或慢 PCIe 環境下。

常見誤區

誤區 1:兩張 12GB 顯卡等於一張 24GB 顯卡

不完全等價。多卡可以讓模型跨裝置放置,但跨卡存取有額外開銷。它能解決「放不下」的問題,不一定等價於單張大顯存卡的速度和穩定性。

誤區 2:不同型號顯卡不能混用

不一定。只要驅動、計算能力和執行庫都支援,Ollama 可以看到多張 GPU。但混用時,速度通常受較慢卡、較小顯存和 PCIe 拓撲影響。最穩的多卡配置仍然是同型號、同顯存、同代驅動支援良好的卡。

誤區 3:多卡一定比單卡快

不一定。如果模型能完整放進單張快卡,單卡可能更快。多卡主要適合大模型、長上下文、單卡顯存不夠的情況。

不需要。普通 PCIe 多卡也能被 Ollama 使用。NVLink 不是前提。

誤區 5:加 GPU 後不用重啟服務

不一定。Linux systemd 服務、Windows 背景應用、Docker 容器都可能需要重啟,才能重新識別裝置和環境變數。

選卡建議

如果目標是 Ollama 本地推理,優先級大致是:

  1. 單卡顯存越大越省心。
  2. 同型號多卡比混合多卡更容易排錯。
  3. PCIe 通道越完整,載入大模型越舒服。
  4. 老卡要先確認 CUDA compute capability 或 ROCm 支援。
  5. 多卡電源、散熱和機箱風道要提前算清楚。

對於預算有限的二手平台:

  • 雙 3090 仍然是很常見的大顯存方案。
  • P40 / M40 這類老 Tesla 顯存大,但功耗、散熱、驅動和效能都要權衡。
  • 4070 / 4070 Ti 這類新卡能效好,但單卡顯存容量限制更明顯。
  • 多張 8GB 老卡能折騰,但不建議為了大模型長期使用。

小結

Ollama 多顯卡支援可以理解成「顯存擴展優先,效能加速其次」。如果模型能完整放進一張 GPU,預設單卡通常更快;如果單卡放不下,多卡可以把模型分布到多張 GPU 上,避免大量落到 CPU/RAM,從而讓大模型變得可用。

實際配置時,先用 ollama ps 看模型載入位置,再用 nvidia-smi 或 ROCm 工具觀察顯存占用。需要限制 GPU 時,NVIDIA 用 CUDA_VISIBLE_DEVICES,AMD ROCm 用 ROCR_VISIBLE_DEVICES,Vulkan 用 GGML_VK_VISIBLE_DEVICES。如果在 Docker 中執行,先確保容器層面能看到 GPU。

多卡不是魔法。它能幫你裝下更大的模型,但不保證線性加速。真正穩定好用的路線,仍然是盡量選大顯存單卡或同型號多卡,並把驅動、PCIe、電源、散熱和模型量化一起考慮。

參考連結

记录并分享
使用 Hugo 建立
主題 StackJimmy 設計