iT邦幫忙

2026 iThome 鐵人賽

DAY 15
0
AI Engineering

從 4,343 筆職缺到 AI Engineer:MLOps × GenAI Engineering 雙主軸實戰系列 第 15

Day 15:AI 平臺與成本治理——損益平衡點與 GPU 利用率

  • 分享至 

  • xImage
  •  

前七天,我們一路處理模型如何可靠地上線、持續部署、監控,以及出問題時怎麼發現。今天換一個主管通常更有感的問題:

這套 AI 系統,到底花多少錢?

模型能活著還不夠,還要活得起。如果工程師只能回答「這樣架構比較漂亮」,很難推動決策;但如果能回答:「這個方案每月多花多少?」、「GPU 利用率提升後,可以少買幾張卡?」、「租雲端和買地端的成本交叉點在哪?」對話就完全不同了。

今天要解決的問題

先看兩個很常見的情境。

場景一
主管:「我們要不要買 GPU?一直租雲端好貴。」
工程師:「呃……我算一下?」
然後這個問題被擱置了三個月。

場景二
主管:「上季買的四張 A100,用得如何?」
工程師:「都有在用啊。」
主管:「利用率多少?」
工程師:「……」

這兩題沒有放諸四海皆準的答案,但有一套可以量化的決策方式。

今天就處理兩個數字:

  1. 成本平衡點:什麼使用量下,租雲端與買地端的成本開始交叉?
  2. GPU 利用率與單位成本:買下來的卡,到底有多少時間真的在工作?這些工作又產生多少價值?

📊 職缺訊號

「AI/ML 平臺與基礎設施」是這次 MLOps 職缺中最高頻的任務訊號之一,占 58.5%

不過 JD 的層次差異很大:初階可能寫「維護 GPU 環境」,資深職缺則會出現「規劃 AI 運算資源」、「容量管理」、「平臺工程」與「成本最佳化」。

分水嶺不只是會不會架環境,而是能不能把技術選擇轉成容量、成本與風險的決策。


一、現象:GPU 的錢是怎麼燒掉的

GPU 成本的損益平衡點與利用率

圖 15-1:GPU 成本治理的兩個關鍵視角。左圖比較雲端 On-Demand 與地端的成本曲線;右圖以模擬資料呈現不同使用方式可能造成的 GPU 忙碌程度差異。圖中數字僅用來說明分析方法,不代表產業平均值。

左圖:租還是買?

假設一張 GPU 的完整地端分攤成本如下:

地端設備與導入成本:30,000
攤提:36 個月
機房、網路與冷卻:150 / 月
維運人力分攤:200 / 月
電力變動成本:0.25 / GPU 小時

雲端 On-Demand:
3.00 / GPU 小時

這組示範參數下:

地端固定成本
= 30,000 ÷ 36 + 150 + 200
≈ 1,183 / 月

成本平衡點
= 1,183 ÷ (3.00 − 0.25)
≈ 430 GPU 小時 / 月

如果用一個月 730 小時計算:

430 ÷ 730 ≈ 59%

也就是說,在這組假設下,大約每月使用 430 GPU 小時,或單張卡約 59% 的時間使用程度附近,兩條成本曲線開始交叉。

低於這個區域,雲端 On-Demand 可能比較有利;長期穩定高於這個區域,地端才逐漸展現成本優勢。但先記住**這只是第一版 TCO 試算,不是採購結論。**因為正式評估還要考慮雲端折扣、硬體故障、容量彈性、高可用、搬遷成本與合規限制。

右圖:真正容易被忽略的是「買了之後有沒有用好」

以下數字是模擬情境

使用方式 平均 GPU-Util 可能發生的情況
互動式 Notebook 12% Jupyter 長時間佔有 GPU,但真正運算時間零碎
排程訓練,未集中佇列 34% Job 之間存在大量空檔
排程訓練,有 Queue/Scheduler 71% 工作可以接續執行,減少閒置
線上推論,無動態批次 23% 每次處理少量 Request
線上推論,有 Dynamic Batching 68% 在延遲 SLO 允許下提高吞吐

這張表容易被誤讀,所以要補充一個重要觀念。

GPU-Util 不等於「用了多少 GPU 算力」

nvidia-smi 顯示的 GPU-Util,主要反映的是取樣期間內 GPU 是否有 Kernel 正在執行。因此:GPU-Util = 60%,想表達的是:

如果工作負載相近,平均 GPU-Util 從 12% 提高到 60%,代表同一批硬體有機會承載顯著更多工作。

能不能真的得到五倍吞吐,還要看:CPU 與資料載入瓶頸、Memory bandwidth、模型大小、Batch Size、多卡通訊、I/O 及 Latency SLO 等。

買新卡之前,先確認既有 GPU 是否長時間閒置;如果能提高資源使用效率,可能先把原本沒用到的容量找回來。

💡 真正值得放進履歷的是「量化改善」,不是漂亮的範例數字

如果真的做過 GPU 資源治理,可以寫成:

「透過 Job Queue 與資源調度,將平均 GPU-Util 從 X% 提升至 Y%,同時將平均排隊時間降低 Z%,單次訓練成本下降 N%。」

這比只寫「熟悉 Kubernetes、CUDA、A100」更能顯示你知道平臺工程真正要解決什麼問題。

二、原理:損益平衡點怎麼算

損益平衡點公式不複雜,難的是誠實地代入參數

雲端月成本  = 每小時單價 × 每月使用時數
地端月成本  = (硬體成本 ÷ 攤提月數) + 機房與電力 + 維運人力分攤
              + 每小時電力成本 × 使用時數

損益平衡時數 = 地端固定成本 ÷ (雲端每小時單價 − 地端每小時變動成本)

三個最常被低估的地端成本:

  1. 維運人力:有人要顧機器、修驅動、處理故障。這通常是最大的隱藏成本。
  2. 閒置損失:地端的卡不用也在折舊,雲端不用就不付錢。所以地端只有在高利用率下才划算
  3. 升級風險:三年攤提期內出現新一代卡,你的卡會相對貶值。

兩個常被低估的雲端成本:

  1. 資料傳出費用(egress):大量資料進出時很可觀。
  2. 周邊服務:儲存、網路、託管服務的費用常常和 GPU 本身差不多。

🏭 台灣情境的特殊考量

半導體、金融與醫療業經常在利用率遠低於平衡點時仍選擇地端。這不是算錯,而是計算式裡要加上「合規成本」——資料不能出境、不能上公有雲,這時候「划不划算」不再只是 GPU 小時的比較。做這類評估時,要先問清楚有沒有硬性的合規限制,再開始算數字。

三、動手:兩個可以直接跑的計算

3.1 成本平衡點試算

"""gpu_cost.py —— 把假設攤開來算,而不是憑感覺決定。"""

# ── 示範參數,請換成自己的實際數字 ──
CLOUD_HOURLY = 3.0
# 分攤到單張 GPU 的完整伺服器、網路與導入 CAPEX
ONPREM_CAPEX = 30_000
AMORTIZE_MONTHS = 36
FACILITY_MONTHLY = 150
OPS_MONTHLY = 200
POWER_HOURLY = 0.25
fixed = (
    ONPREM_CAPEX / AMORTIZE_MONTHS
    + FACILITY_MONTHLY
    + OPS_MONTHLY
)
breakeven_hours = fixed / (
    CLOUD_HOURLY - POWER_HOURLY
)
print(f"地端月固定成本:{fixed:.0f}")
print(
    f"成本平衡:約每月 {breakeven_hours:.0f} GPU 小時"
    f"(相當於 {breakeven_hours / 730:.0%})"
)

for util in (0.2, 0.4, 0.6, 0.8):
    hours = 730 * util
    cloud = CLOUD_HOURLY * hours
    onprem = fixed + POWER_HOURLY * hours
    winner = "地端" if onprem < cloud else "雲端"
    print(
        f"利用程度 {util:.0%}:"
        f"雲端 {cloud:>7.0f} / "
        f"地端 {onprem:>7.0f}"
        f" → {winner}成本較低"
    )

在這組示範值下,大約會得到:

地端月固定成本:1183
成本平衡:約每月 430 GPU 小時(相當於 59%)

這段程式真正的價值,是它逼你把假設攤開來,主管如果問:「為什麼你算出 430?」,你可以回答:

維運人力我先抓 200 / 月。
如果改成 500,平衡點會往右移。

如果雲端有承諾用量折扣,
Cloud Hourly 降低,平衡點也會改變。

把直覺地回應變成我們一起調整假設,再看決策怎麼變。

3.2 量測真實的 GPU 利用率

先從簡單的 nvidia-smi 開始。

# 快速查看
# 注意 GPU-Util 與 Memory Usage 是不同概念
nvidia-smi \
  --query-gpu=index,utilization.gpu,memory.used,memory.total \
  --format=csv \
  -l 5

但單次快照幾乎沒有意義,至少要收集一段時間:

nvidia-smi \
  --query-gpu=timestamp,index,utilization.gpu,memory.used \
  --format=csv,noheader,nounits \
  -l 5 > gpu_usage.csv

請注意過度稀疏的取樣很容易低估短時間運算,所以此範例不採60秒進行數據採集,否則很容易取得0而低估。

接著分析:

"""分析 GPU 取樣資料,找出值得調查的閒置區段。"""

import pandas as pd

df = pd.read_csv(
    "gpu_usage.csv",
    names=[
        "timestamp",
        "index",
        "util",
        "memory_mib"
    ]
)
df["util"] = pd.to_numeric(df["util"])
df["memory_mib"] = pd.to_numeric(df["memory_mib"])
df["mem_gb"] = df["memory_mib"] / 1024

print(
    f"平均 GPU-Util:"
    f"{df.util.mean():.1f}%"
)
print(
    f"GPU-Util < 5% 的時間比例:"
    f"{(df.util < 5).mean():.1%}"
)
print(
    f"GPU-Util > 80% 的時間比例:"
    f"{(df.util > 80).mean():.1%}"
)

suspected_idle = (
    (df.util < 5)
    &
    (df.mem_gb > 2)
).mean()

print(
    "顯存已配置、但 GPU 活動偏低的時間:"
    f"{suspected_idle:.1%}"
    "  ← 值得進一步調查"
)

最後這個數字很實用,但要注意:

顯存被占用
+
GPU-Util 很低

不代表一定有人浪費 GPU。

它也可能是:

Inference Server 讓模型常駐 VRAM
CUDA Context
Model Cache
等待下一批 Request
CPU / DataLoader Bottleneck

所以它應該被解讀成:

「這段時間值得進一步調查。」

接下來再搭配:

Process
Job Owner
Queue
Pod
模型服務型態

判斷到底發生什麼事。

如果已經進入正式 Production,通常也不會靠一支 nvidia-smi Shell Script 長期撐著。

比較完整的做法會是:

GPU
 ↓
NVIDIA DCGM Exporter
 ↓
Prometheus
 ↓
Grafana

這樣才能把 GPU 指標納入原本的 Observability Stack。

四、一個常見的平臺導入順序

如果目前最大的痛點是重複部署與 GPU 閒置,可以從這個順序開始

內部 ML 平臺的自助服務架構

圖 15-2:內部 ML 平臺的自助服務架構(示意架構)。平臺工程的目標是把重複的工作變成使用者能自己完成的入口。

平臺建設的順序建議(依投報率):

順序 做什麼 為什麼是這個順序
1 自助部署(一個指令/一次點擊上線) 頻率最高的重複工作
2 資源配額與佇列 直接解決利用率問題(12% → 71%)
3 共用的監控與日誌 每個團隊自己做會做出七套
4 自助訓練環境 頻率較低,且需求差異大
5 特徵存放區、模型市集等進階功能 通常是過早的最佳化

三個常見的成本最佳化槓桿:
先提醒一件事:GPU 利用率是手段,不是終點。

一張 GPU 跑到 95% 不代表成本治理成功。如果吞吐沒有增加、訓練時間沒有縮短,或只是讓更多沒有價值的工作塞滿 GPU,那只是把浪費跑得更勤快。

因此利用率最好和至少一個單位經濟指標一起看,例如:

每次訓練成本每 1,000 次推論成本Time-to-Result,以及線上服務的 Throughput / SLO

  1. 提高利用率:在工作負載可近似線性整併的情況下,從 12% 提升到 60%,理論上相當於把同一張卡的有效使用程度提高到約五倍。
  2. 右尺寸化(用對卡:推論不需要訓練級的卡):常見的浪費是「拿 A100 跑一個 1B 小模型」。
  3. Spot/競價執行個體(可省 60–90%):若工作負載穩定,Committed Use/Savings Plan 會把雲端成本曲線往下移;若工作可中斷,Spot 又會形成另一條成本曲線。因此實務評估不是只有「租或買」兩個選項,Spot 帶來的效果也納入考慮。

    Spot/競價資源:非常適合可 checkpoint、可重啟的訓練與 Batch 工作。線上推論若有高可用需求,不宜把全部容量押在 Spot;但如果已有 On-Demand 基礎容量、多副本、自動補位與 graceful drain,仍可讓部分推論容量使用 Spot 降低成本。

⚠️ 成本治理最容易做錯的一件事:只砍不看

如果單純為了省錢把 GPU 數量砍半,結果訓練排隊時間從 2 小時變成 2 天,資料科學家的產出直接腰斬。GPU 成本要和「等待成本」一起看:工程師等待的時間也是錢,而且通常更貴。

評估時可先量測「排隊等待時間」這個指標,再決定要不要砍。成本治理的目標是消除浪費,不是減少資源。


今日小結

  • 先救利用率,再急著買卡,但不要把 GPU-Util 當成唯一 KPI。
  • 雲端與地端不能只比 GPU 標價,要看完整 TCO
  • 雲端還有 On-Demand、Commitment 與 Spot 等不同 Capacity Model。
  • 合規與資安有時是 Constraint,不是單純增加一筆「合規成本」。
  • 顯存被占用 + GPU-Util 很低 只能視為值得調查的訊號,不能直接判定有人浪費。
  • Spot 很適合可中斷訓練,但不是所有線上推論都一律不能使用。
  • 平臺沒有固定建設順序,應該先解決最頻繁、最昂貴、最容易出錯的重複工作
  • GPU 成本要和等待成本一起看。

最後一句話:

成本治理的目標,不是把 GPU 利用率拉到 100%,也不是單純少買幾張卡;而是在可靠性與效能要求下,用最低的單位成本完成真正有價值的工作。

限制與提醒

本文的成本模型刻意簡化,用來理解成本曲線與決策方法。正式採購或雲端遷移評估仍應納入完整 TCO、折扣方案、容量彈性、HA、硬體故障、遷移成本,以及法規與資安限制。

明天預告

主軸一結束。明天開始八天的主軸二:生成式 AI 應用與代理系統

從 Day 16 起,我們換一種焦慮:不再擔心半夜被叫起來,而是擔心使用者覺得它是"快樂寶貝"。第一站是所有 LLM 應用的地基——從 Prompt 到 Context Engineering,以及那個決定你系統上限的觀念:輸入視窗是一份要編列的預算

走主軸一的讀者,明天起可以略讀,Day 24 我們會合流。但建議您至少看 Day 18 與 Day 21——那是您未來要支撐的系統長什麼樣。

延伸閱讀


上一篇
Day 14:監控與漂移 — 模型無聲壞掉的那 14 天
下一篇
Day 16:從 Prompt 到 Context Engineering — 輸入視窗是一份預算
系列文
從 4,343 筆職缺到 AI Engineer:MLOps × GenAI Engineering 雙主軸實戰18
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言