<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>GPU加速 on KnightLi的博客</title>
        <link>https://www.knightli.com/zh-tw/tags/gpu%E5%8A%A0%E9%80%9F/</link>
        <description>Recent content in GPU加速 on KnightLi的博客</description>
        <generator>Hugo -- gohugo.io</generator>
        <language>zh-tw</language>
        <lastBuildDate>Sat, 09 May 2026 15:05:41 +0800</lastBuildDate><atom:link href="https://www.knightli.com/zh-tw/tags/gpu%E5%8A%A0%E9%80%9F/index.xml" rel="self" type="application/rss+xml" /><item>
        <title>llama.cpp 多 GPU 性能實測思路：2x V100 16GB 會比單卡 32GB 快嗎？</title>
        <link>https://www.knightli.com/zh-tw/2026/05/09/llama-cpp-multi-gpu-offload-performance/</link>
        <pubDate>Sat, 09 May 2026 15:05:41 +0800</pubDate>
        
        <guid>https://www.knightli.com/zh-tw/2026/05/09/llama-cpp-multi-gpu-offload-performance/</guid>
        <description>&lt;p&gt;大概結論：llama.cpp 多 GPU offload 不是「多一張卡就白撿一倍性能」。如果模型本來能完整放進一張 32GB 顯卡，2x V100 16GB 通常不如單張 32GB 顯卡省心，甚至可能更慢；如果模型單張 16GB 放不下，雙卡的主要價值是「能把模型放進 GPU」，這時收益會很明顯。&lt;/p&gt;
&lt;h2 id=&#34;先分清-split-mode&#34;&gt;先分清 split mode
&lt;/h2&gt;&lt;p&gt;llama.cpp 的多 GPU 主要圍繞 &lt;code&gt;--split-mode&lt;/code&gt; 和 &lt;code&gt;--tensor-split&lt;/code&gt; 使用。實際討論性能時，先要區分幾種模式：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;layer&lt;/code&gt;：按層切分到不同 GPU，兼容性較好，也是多數人優先嘗試的方式。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;tensor&lt;/code&gt;：把張量計算拆到多張 GPU 上，更接近並行計算，但更依賴 GPU 之間的互聯頻寬和後端支援。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;row&lt;/code&gt;：舊的行切分方式，在不少場景裡仍能看到，但新部署通常不建議優先從它開始。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;簡單說，&lt;code&gt;layer&lt;/code&gt; 更像「把不同樓層放在不同卡上」，單 token 生成時不一定能讓兩張卡同時滿負載；&lt;code&gt;tensor&lt;/code&gt; 更像「同一層兩張卡一起算」，理論上更能並行，但跨卡通訊會成為關鍵瓶頸。&lt;/p&gt;
&lt;h2 id=&#34;單卡-32gb-能放下時雙-16gb-不一定更快&#34;&gt;單卡 32GB 能放下時：雙 16GB 不一定更快
&lt;/h2&gt;&lt;p&gt;如果模型和 KV cache 能完整放進一張 32GB 顯卡，那麼單卡通常更穩，也常常更快。對 1x V100 32GB 和 2x V100 16GB 這類同代硬體來說，後者未必能贏。&lt;/p&gt;
&lt;p&gt;比較保守的預期是：2x V100 16GB 可能比單張 V100 32GB 慢 10% 到 40%，尤其是單人聊天、Continue Agent、程式碼問答這類一次主要生成一個回答的場景。&lt;/p&gt;
&lt;p&gt;原因不複雜：多 GPU 不是簡單合併顯存。按層切分時，推理會在不同 GPU 之間流轉，單 token 生成階段經常是部分 GPU 等另一部分 GPU；按張量切分時，兩張卡可以一起算，但中間結果需要跨卡同步，互聯頻寬和延遲會直接影響吞吐。&lt;/p&gt;
&lt;p&gt;所以如果你的選擇是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;1x V100 32GB&lt;/li&gt;
&lt;li&gt;2x V100 16GB&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;並且目標模型單張 32GB 已經能完整放下，那麼單張 32GB 往往是更舒服的選擇。&lt;/p&gt;
&lt;h2 id=&#34;單卡-16gb-放不下時雙卡價值很大&#34;&gt;單卡 16GB 放不下時：雙卡價值很大
&lt;/h2&gt;&lt;p&gt;另一種情況完全不同：模型單張 16GB 放不下，但兩張 16GB 合起來可以放下。&lt;/p&gt;
&lt;p&gt;這時雙卡的價值就很直接：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;單張 16GB：可能需要大量 CPU offload，速度明顯變慢。&lt;/li&gt;
&lt;li&gt;2x 16GB：權重盡量留在 GPU 上，速度可能比 CPU/GPU 混跑快很多。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;這種場景下，2x V100 16GB 不一定比單張 32GB 快，但它可能比「單張 16GB 加大量系統記憶體 offload」快幾倍。也就是說，雙卡的第一價值不是加速，而是避免模型被迫落到更慢的系統記憶體裡。&lt;/p&gt;
&lt;h2 id=&#34;v100-pcie-和-v100-sxm2-差別很大&#34;&gt;V100 PCIe 和 V100 SXM2 差別很大
&lt;/h2&gt;&lt;p&gt;多 GPU 推理最容易被忽略的是互聯。&lt;/p&gt;
&lt;p&gt;如果是 V100 SXM2，並且機器裡有 NVLink，跨卡通訊頻寬高很多。NVIDIA 的 V100 資料裡，NVLink 互聯最高可到 300GB/s。這種環境下，&lt;code&gt;tensor&lt;/code&gt; 或更高 batch 的場景才更有機會接近甚至超過單卡表現。&lt;/p&gt;
&lt;p&gt;如果是 V100 PCIe，情況就保守得多。V100 PCIe 的互聯主要走 PCIe Gen3，資料裡標的 interconnect bandwidth 是 32GB/s。這個頻寬和 NVLink 不是一個量級，所以雙卡經常出現「顯存夠了，但速度沒有翻倍」的情況。&lt;/p&gt;
&lt;p&gt;因此判斷 2x V100 16GB 值不值得，不能只看顯存相加是 32GB，還要看它們是 PCIe 版還是 SXM2/NVLink 版。&lt;/p&gt;
&lt;h2 id=&#34;怎麼選更實際&#34;&gt;怎麼選更實際
&lt;/h2&gt;&lt;p&gt;如果模型能放進單張 32GB 顯卡，優先選單卡。它的延遲、穩定性和調參成本通常更好。&lt;/p&gt;
&lt;p&gt;如果模型單張 16GB 放不下，而兩張 16GB 能放下，雙卡值得用。此時重點是讓權重盡量留在 GPU，而不是期待性能線性翻倍。&lt;/p&gt;
&lt;p&gt;如果是 V100 PCIe 雙卡，優先嘗試 &lt;code&gt;--split-mode layer&lt;/code&gt;，把目標放在「能穩定跑」和「少走 CPU」上。&lt;/p&gt;
&lt;p&gt;如果是 V100 SXM2/NVLink，才更值得測試 &lt;code&gt;tensor&lt;/code&gt; 相關模式，尤其是 prefill、大 batch 或併發請求場景。&lt;/p&gt;
&lt;h2 id=&#34;什麼時候買-2x16gb什麼時候買-1x32gb&#34;&gt;什麼時候買 2x16GB，什麼時候買 1x32GB
&lt;/h2&gt;&lt;p&gt;如果你只服務一個人，主要做聊天、程式碼補全、Continue Agent、長上下文問答，並且目標模型能放進 32GB，那麼 1x32GB 通常更值得。它少了跨卡調度，延遲更穩定，排查問題也簡單。&lt;/p&gt;
&lt;p&gt;如果你已經有一張 16GB 卡，想用較低成本擴到能跑 30B、32B 或更高量化模型，2x16GB 就有意義。它不一定讓 token/s 翻倍，但可以把原本必須 CPU offload 的權重留在 GPU 上。&lt;/p&gt;
&lt;p&gt;如果你準備重新採購，優先級可以這樣排：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;單模型、單使用者、重視回應延遲：優先 1x32GB。&lt;/li&gt;
&lt;li&gt;模型單卡放不下、預算有限：可以考慮 2x16GB。&lt;/li&gt;
&lt;li&gt;有 NVLink 或 SXM2 機器：2x16GB 的可玩性明顯高於普通 PCIe 雙卡。&lt;/li&gt;
&lt;li&gt;未來想跑更長上下文：不要只看權重大小，還要預留 KV cache 顯存。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;layer-split-和-tensor-split-怎麼用&#34;&gt;layer split 和 tensor split 怎麼用
&lt;/h2&gt;&lt;p&gt;實用建議是：先用 &lt;code&gt;layer&lt;/code&gt;，再測 &lt;code&gt;tensor&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;layer&lt;/code&gt; 適合作為預設起點。它按層分配模型，兼容性較好，對 PCIe 雙卡更友好。缺點是生成階段可能更像流水線，某些時刻只有一張卡在忙，另一張卡在等。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;tensor&lt;/code&gt; 更適合互聯頻寬好的機器，例如 V100 SXM2/NVLink。它把同一層的部分計算拆到多張卡上，理論上更有並行空間，但跨卡同步更頻繁。如果是 PCIe 雙卡，&lt;code&gt;tensor&lt;/code&gt; 可能會被通訊開銷吃掉收益。&lt;/p&gt;
&lt;p&gt;實際測試時可以從這幾組開始：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;llama-bench -m model.gguf -ngl &lt;span class=&#34;m&#34;&gt;99&lt;/span&gt; --split-mode layer --tensor-split 1,1
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;llama-bench -m model.gguf -ngl &lt;span class=&#34;m&#34;&gt;99&lt;/span&gt; --split-mode tensor --tensor-split 1,1
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;llama-bench -m model.gguf -ngl &lt;span class=&#34;m&#34;&gt;99&lt;/span&gt; --split-mode layer --tensor-split 1,0
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;第三條不是為了長期使用，而是給單卡結果做一個參照。這樣才能看出雙卡到底是更快，還是只是把顯存壓力分攤出去了。&lt;/p&gt;
&lt;h2 id=&#34;prefill-和-decode-為什麼表現不同&#34;&gt;prefill 和 decode 為什麼表現不同
&lt;/h2&gt;&lt;p&gt;本地大模型性能通常要分成兩個階段看：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;prefill&lt;/code&gt;：處理輸入 prompt，典型指標是 &lt;code&gt;pp512&lt;/code&gt; 這類 prompt processing 吞吐。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;decode&lt;/code&gt;：逐 token 生成回答，典型指標是 &lt;code&gt;tg128&lt;/code&gt; 這類 token generation 吞吐。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;prefill&lt;/code&gt; 更像大批量矩陣計算，batch 較大時更容易把 GPU 餵飽，也更可能從多 GPU 並行裡受益。&lt;code&gt;decode&lt;/code&gt; 是一個 token 接一個 token 生成，batch 小、同步頻繁，跨卡通訊和調度延遲更容易暴露出來。&lt;/p&gt;
&lt;p&gt;所以你可能會看到一種結果：雙卡的 &lt;code&gt;pp512&lt;/code&gt; 更好，但 &lt;code&gt;tg128&lt;/code&gt; 沒明顯提升，甚至更慢。對聊天和 Agent 來說，使用者體感更接近 &lt;code&gt;tg128&lt;/code&gt;；對長文件導入、批量預填充、併發服務來說，&lt;code&gt;pp512&lt;/code&gt; 也很重要。&lt;/p&gt;
&lt;h2 id=&#34;kv-cache-會不會成為第二個顯存瓶頸&#34;&gt;KV cache 會不會成為第二個顯存瓶頸
&lt;/h2&gt;&lt;p&gt;會。很多人只算模型權重，忘了 KV cache。&lt;/p&gt;
&lt;p&gt;模型權重決定「能不能載入模型」，KV cache 決定「能不能開足上下文」。上下文越長、併發越高、batch 越大，KV cache 佔用越明顯。你可能遇到這種情況：模型本體能放進 32GB，但一開 32K 或 64K 上下文，顯存又不夠了。&lt;/p&gt;
&lt;p&gt;判斷時至少要留出幾塊顯存餘量：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;KV cache&lt;/li&gt;
&lt;li&gt;CUDA graph 或後端執行時開銷&lt;/li&gt;
&lt;li&gt;prompt batch 和 ubatch&lt;/li&gt;
&lt;li&gt;系統桌面、驅動和其它程序佔用&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果你用的是 2x16GB，顯存不是一個完全等價的 32GB 大池子。某些緩衝區、KV cache 或中間張量仍然會受單卡剩餘顯存影響。測試長上下文時，最好直接用目標 &lt;code&gt;--ctx-size&lt;/code&gt; 和目標併發數測，而不是只看模型能不能啟動。&lt;/p&gt;
&lt;h2 id=&#34;用-llama-bench-做自己的雙卡測試&#34;&gt;用 llama-bench 做自己的雙卡測試
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;llama-bench&lt;/code&gt; 比直接聊天更適合做硬體對比，因為它會把 prompt processing 和 token generation 拆成可比較的指標。官方 README 的預設示例就是：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;llama-bench -m model.gguf
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;對雙 V100，可以至少測這幾組：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;8
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# 單卡基線&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;CUDA_VISIBLE_DEVICES&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt; llama-bench -m model.gguf -ngl &lt;span class=&#34;m&#34;&gt;99&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# 雙卡 layer split&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;CUDA_VISIBLE_DEVICES&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;0,1 llama-bench -m model.gguf -ngl &lt;span class=&#34;m&#34;&gt;99&lt;/span&gt; --split-mode layer --tensor-split 1,1
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# 雙卡 tensor split&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;CUDA_VISIBLE_DEVICES&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;0,1 llama-bench -m model.gguf -ngl &lt;span class=&#34;m&#34;&gt;99&lt;/span&gt; --split-mode tensor --tensor-split 1,1
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;重點看兩列：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;pp512&lt;/code&gt;：prompt processing，長輸入和批量預填充更相關。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;tg128&lt;/code&gt;：token generation，單人聊天和 Agent 體感更相關。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;測試時盡量固定模型、量化格式、上下文、batch、驅動版本和 llama.cpp 版本。每組多跑幾次，取中位數，比只看一次結果可靠。最後再用真實工作流跑一遍，例如 Continue Agent、OpenAI-compatible server 或你自己的 RAG 請求，因為 benchmark 好看不代表互動體驗一定更好。&lt;/p&gt;
&lt;h2 id=&#34;一句話結論&#34;&gt;一句話結論
&lt;/h2&gt;&lt;p&gt;2x V100 16GB 的優勢主要是顯存容量，而不是必然的生成速度。模型單卡能放下時，單張 32GB 往往更快、更穩；模型單卡放不下時，雙 16GB 的價值就很大，因為它能避免大量 CPU offload。至於能不能更快，關鍵看 split mode、batch、模型大小，以及兩張 V100 之間到底是 PCIe 還是 NVLink。&lt;/p&gt;
&lt;p&gt;參考資料：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/ggml-org/llama.cpp/blob/master/tools/server/README.md&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;llama.cpp server README&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.mintlify.com/ggml-org/llama.cpp/concepts/backends&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;llama.cpp Compute Backends&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.nvidia.com/en-gb/data-center/tesla-v100/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;NVIDIA Tesla V100&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://images.nvidia.com/content/technologies/volta/pdf/tesla-volta-v100-datasheet.pdf&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;NVIDIA V100 Datasheet&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        
    </channel>
</rss>
