CUDA 元件
Kernel 負責執行平行工作;CUDA graph 記錄 kernel 與其他裝置操作,以便高效重播;driver 是連接硬體的低階介面;runtime 則是供開發者啟動 kernel 與管理記憶體的 application programming interface(API)。CUDA 程式通常以 C++ 撰寫,再編譯成主機端與裝置端程式碼。
4
依據 benchmark 與 profiling 選擇 runtime 和 kernel。
10 分鐘閱讀
印刷頁: 93–116
推論軟體是一座逐層提高抽象、逐層減少直接控制的階梯。Compute Unified Device Architecture(CUDA)kernel 決定工作如何接觸 NVIDIA 硬體;framework 描述 tensor 程式與序列化方式;inference engine 把最佳化 kernel、scheduling、batch、cache 及分散式設定包成可部署服務;協調層再管理多個 worker。實作時應從能滿足需求的最高層開始,只有量測證明某個能力缺口或昂貴瓶頸存在,才往下一層深入,且每次改動都要回到符合正式流量形狀的負載驗證。
把每一層看成一份介面契約:硬體公開指令與記憶體,CUDA 啟動具體 kernel,PyTorch 等 framework 描述 graph 與 tensor,檔案格式保存 weights 或執行 graph,engine 選擇實作並 scheduling 請求,orchestrator 則把工作 route 到不同 replica。效能工程要問的是哪一份契約擋住下一步,然後只改動能解決問題的最窄一層,避免為了單一瓶頸而接管所有下層複雜度。
硬體先承載 CUDA kernel,PyTorch 與模型格式建立在 CUDA 之上,inference engine 再組合最佳化服務,而 Dynamo 位於最上層協調分散式部署中的多個 engine。
新模型發布的第一天,最容易看見整個堆疊的相依關係。Reference library 可能已能下載 config 與 weights,也能用簡單程式跑出正確結果,但正式 engine 尚未理解新的 attention 形式;接著 engine 的 nightly build 可能支援 graph,最關鍵的最佳化 kernel 卻只針對舊 GPU;再往下,driver 或 CUDA 版本也可能與 container 內其他套件衝突。不要把單一「可載入」視為正式支援,而要沿著檔案格式、模型定義、framework operation、kernel、engine、driver 與硬體一路畫出完整支援鏈。先找到第一組輸出正確、負載穩定、可重現的組合,把版本及映像固定下來,再從這個可信基點最佳化。若為了 day-zero 支援採用 prerelease 套件,也要準備回退路徑,並把升級後的相容性與品質測試納入交付條件。
選 inference engine 要先排除不符合硬限制的候選:模型架構與 modality 是否支援、accelerator 與精度是否有 kernel、授權是否符合產品、必要的 continuous batching、quantization、cache、speculation、parallelism 與 disaggregation 路徑是否存在。接著比較營運適配度,包括官方 container、設定表面、記錄與監控、升級節奏、除錯工具,以及團隊是否能承擔它的複雜度。只有通過這兩層篩選的 engine,才值得用完全相同的模型版本、流量分布與品質套件做 head-to-head benchmark。支援面廣的選項可能以較短時間上線,深度專門化的選項可能以更高工程成本換取更多容量。最終比較應把延遲目標下的吞吐量、GPU 數量、維護投入與故障風險換算成服務成本,而不是用一張脫離約束的峰值圖表宣布冠軍。
有效的效能實驗是一個封閉循環。先固定環境、隨機種子能固定的部分與基線設定,再重播接近正式環境的序列長度、抵達間隔、concurrency 分布、temperature 與 prefix 重複。先看端到端 percentile latency、吞吐量、錯誤與品質;只有結果不足以解釋時,才深入 profiler,把時間歸因到 CPU、GPU、memory copy、kernel 或 interconnect。一次改一個 kernel 或參數,執行足夠次數,確認改善超過正常波動,也沒有讓輸出品質或記憶體安全退步。之後再與其他預定最佳化合併測試,因為各自有效的設定可能共同爭用資源。最後 shadow 正式流量,證明合成測試結論仍成立。這份循環留下可重現證據,也讓 dependency 更新後能判斷是重新調校、維持舊版或安全回退。
Kernel fusion 清楚展示抽象邊界為何影響效能。兩個單獨看都很快的 kernel,如果中間必須產生大型 tensor、寫回 video random-access memory(VRAM)後立刻重讀,組合起來仍可能受頻寬限制。規則清楚的 graph 可由 compiler 自動融合;成熟 engine 可能依 shape 與 GPU 選擇已知 fused plugin;少見架構則可能需要 framework 貢獻者依 profiler 證據手寫實作。越往低層修改,就要負責越廣的相容矩陣:矩陣形狀、精度、alignment、GPU 世代、錯誤輸入與未來版本都要測。保留正確的 unfused fallback,讓不支援的組合仍可服務;再以真實 scheduling、batch 與多請求負載確認端到端收益。只有局部記憶體流量減少確實轉成使用者延遲或系統容量改善,fused path 才值得長期維護。
分散式 orchestrator 應該回答已量測的需求,而不是因為架構圖看起來完整就加入。若多個 replica 之間有大量 prefix 可重用,協調層可把請求送到持有相符 cache 的 worker;若 prefill 與 decode 的負載曲線不同,它可以獨立擴縮兩組資源;若模型工作真的跨越節點,也需要統一管理 topology 與狀態。缺少這些需求時,直接使用 inference engine 會少一層 queue、網路 hop、版本相容與故障模式。評估協調層不能只測穩態峰值,還要製造不均勻流量、cache cold start、worker 中斷、擴縮轉換與下游變慢,觀察 routing 是否維持延遲目標、狀態是否遺失、queue 是否無界增長。只有這些動態情境下的收益大於操作成本,新的抽象層才成立。
每一個最佳化決策都要保存成可查核證據:原始假設、完整 dependency 與硬體版本、模型 revision、traffic generator 設定、原始分布而非只有平均值、品質結果、profile trace、選定參數、被淘汰方案及 rollback trigger。軟體迭代很快,半年後 engine 預設值、compiler 能力或 kernel 支援可能已經改變;沒有紀錄時,團隊無法分辨某個手動 plugin 是已失去必要性的 workaround,還是仍在保護重要限制,也容易把一次過時 benchmark 變成口耳相傳的定律。升級前重跑同一套 evidence package,比單純確認服務能啟動更能揭露效能與品質退步;發生事故時,完整決策記錄也讓團隊能快速回到最後一組已知安全設定。
Kernel 負責執行平行工作;CUDA graph 記錄 kernel 與其他裝置操作,以便高效重播;driver 是連接硬體的低階介面;runtime 則是供開發者啟動 kernel 與管理記憶體的 application programming interface(API)。CUDA 程式通常以 C++ 撰寫,再編譯成主機端與裝置端程式碼。
Basic Linear Algebra Subprograms(BLAS)是 cuBLAS 矩陣原語的基礎,cuDNN 則涵蓋神經網路運算。CUTLASS 與 CuTe 提供可組合的 template,FlashInfer 提供推論 kernel。多數團隊應先讓 engine 自動選擇,或插入經過驗證的現成 kernel;只有關鍵路徑長期穩定、量測收益足以支付維護成本時,才值得手寫新實作。
針對某一 GPU 世代、記憶體配置或矩陣形狀調校的 kernel,換到另一代可能無法利用新資源,甚至不能執行。自動編譯器與 engine 能處理常見路徑;手動 plugin 則必須同時證明相容範圍、正確性、fallback 與實際效益。
2026 年 1 月版快照:PyTorch 是主要可程式化 framework。Safetensors 把不含可執行程式的 weights 與架構分開保存,Open Neural Network Exchange(ONNX)則可把 weights 和執行 graph 包在一起交給可攜式 runtime,但能否匯出仍取決於操作與資料結構支援。
2026 年 1 月版快照:Hugging Face transformers 與 diffusers 適合查看模型定義、設定、下載工具、notebook,以及釐清輸入輸出行為;面對正式流量時,通常仍要使用編譯後的 PyTorch 程式或具備 scheduling 與記憶體管理的 serving engine。
2026 年 1 月版快照:vLLM 著重易採用與廣泛模型支援;SGLang 著重可替換元件,以及 mixture of experts(MoE)與 diffusion 路徑;TensorRT-LLM 著重深度 NVIDIA 最佳化,但設定成本較高。這是一張當時的地圖,不能取代目前版本的實測。
2026 年 1 月版快照:Dynamo 協調 engine,以支援 cache-aware routing、prefill 與 decode 分離,以及 multi-node 工作。大型模型與高流量可能從中受益;小型服務若沒有足夠 cache 重用或獨立 worker pool,額外分散式層反而只是負擔。
2026 年 1 月版快照:SGLang GenAI-Bench 與 NVIDIA GenAI-Perf 針對生成式模型流量,Locust 則提供一般 concurrency 負載。Eval dataset 可同時提供寫實輸入與品質抽查,但請求分布仍必須對齊正式環境。
2026 年 1 月版快照:PyTorch Profiler 涵蓋 framework 步驟,NVIDIA Nsight Systems 追蹤 CPU、GPU 與 interconnect 活動,Nsight Compute 則分析單一 kernel。選擇能解釋 benchmark 結果的最窄範圍即可。
unfused 讀取與第一個 kernel 會導向中間結果來回,穿過 video random-access memory(VRAM);fused path 讀取則經過單一 fused kernel,直接到最終寫入。
TTFT
依輸入長度與負載切分,才能看見 queueing 與 prefill 的變化。
TPS
要連同 batch 與 concurrency 量報告,不能只列脫離服務條件的最大值。
tokens/s 與 requests/s
同時說明達到該吞吐量時遵守的延遲限制。
ms 與 trace 占比
用 profile 尋找昂貴運算、記憶體搬移、launch 空檔或主機端工作。
GB
修改編譯或 kernel 時,分開追蹤模型、cache、workspace 與暫時配置。
eval 分數
把接近正式用途的評估輸入同時當成 benchmark 流量與最佳化退步護欄。
支援面廣的 engine 減少實作時間並涵蓋許多模型;當模型、硬體與流量足夠穩定,專用或更低階路徑才可能用較大的工程投入換得更高效能。
編譯器能替一般操作自動選 kernel 並融合,custom kernel 則處理少見或高度調校路徑。Plugin 也可能切斷編譯器的全局視野,並擴大版本與硬體相容工作。
Safetensors 讓序列化單純、安全,執行由程式定義;ONNX 能攜帶 graph 跨 runtime,但複雜模型特性可能因匯出規格不支援而失敗。
中小型部署直接使用 engine 較簡單;只有 cache routing、獨立 worker pool 或 multi-node 協調能實質改善大型服務時,分散式協調層才值得它的額外成本。
小型均勻負載能快速回饋,卻可能獎勵錯誤設定;符合正式分布的測試耗時較長,但能避免序列、負載、cache 與參數不一致誤導決策。
第 93-101 頁
抽象堆疊、CUDA、kernel library、選擇與融合。
第 101-105 頁
Framework、編譯、序列化格式、可攜 runtime 與參考 library。
第 105-111 頁
2026 年 1 月版的 serving engine 能力與定位。
第 111-112 頁
2026 年 1 月版的分散式協調方式與規模門檻。
第 112-114 頁
代表性負載、benchmark 工具與實驗紀律。
第 114-116 頁
Profiling 範圍、工具與從量測回到實作的循環。