AI 能耗主張怎麼比?用工作任務試算表檢驗

以相同任務、IT 與設施輸入電表、通過審查的件數及電網係數檢驗 AI 耗能主張;另列訓練分攤。附全數虛構的試算範例。

Separate energy meters for training, inference and facility overhead

「每次 AI 查詢耗多少電」還不足以拿來比較採購方案。先問清楚是哪一種任務、電表裝在哪裡、失敗與重試算不算,以及數字涵蓋哪一段用電與排放。以下用一份小型試算表檢驗客服流程:助理擬寫回覆,審查者對照政策把關;只有回覆通過審查、沒有不安全或缺乏依據的內容,才算完成任務。下列讀數全為虛構,僅供示範算法,並非 Meydo 的量測、供應商實績或電網資料。

先定義可檢驗的主張

讓每個候選方案處理相同的十件代表性客服案件,其中包含一件棘手的升級處理案件。固定模型、提示詞、檢索資料、硬體、地區、軟體版本、回覆長度規則和延遲上限。所有嘗試與重試都要計入耗電,但計算單位應是通過審查的已完成任務,不是 API 呼叫次數。記錄審查標準和失敗案例:回覆變短卻漏掉升級處理,不能算節能。MLCommons 對 MLPerf Power 的說明也把功率量測與工作負載、效能及準確度/品質目標放在一起;本試算並不是 MLPerf 提交結果。

要求附時間戳記的 IT 輸入端電表紀錄(伺服器,以及可歸屬的網路與儲存設備)、若有明確專用邊界則提供對應的設施輸入端紀錄、兩個邊界的閒置基準、請求與品質判定紀錄,以及每個時段的地點與時間。單看 GPU 遙測資料,量測範圍更窄。IEA 對資料中心用電組成的說明區分伺服器、儲存、網路、冷卻及其他基礎設施;資料中心總用電量不能直接換算成通用的「每次 AI 查詢」數字。

用這組示意資料動手算

表中所有輸入值都是虛構的。A 與 B 各在同一個假設電網地區,連續運行三段、每段十分鐘。「設施輸入」是示意的專用設施等效輸入電表,包含額外開銷;不是單台伺服器的插座讀數,也不是實際的主機代管帳單。各時段假設閒置基準為 IT 100 W、設施輸入 130 W。排放係數只是示意用的電網平均係數,單位為 kg CO2e/kWh,並非經查證的地區資料。

方案時段IT 功率(W)設施輸入功率(W)電網排放係數(kg CO2e/kWh)
A11602050.4
A21802300.5
A31401850.3
B11501900.4
B21501900.5
B31501900.3

每列的耗電量(kWh)=功率(W)×(10/60 小時)÷ 1,000,再加總三列。計算依地點估算的運轉排放量時,應將每列的設施輸入總耗電量乘上該時段對應的係數,再加總;不能把總耗電量乘以最「乾淨」時段的係數。這裡的時段係數只是工程比較的示意值,不是溫室氣體盤查方法,也不能證明負載使電網發生變化。GHG Protocol 現行範疇二指引處理企業盤查中的外購電力與合約工具:地點基礎方法採用電網平均供電係數,市場基礎方法則反映符合條件的合約資訊。無論是供應商的憑證,還是單獨一個地點基礎估值,都不能證明某次查詢在那個時段實際使用了零碳電力。

依這組示意數字,A 的 IT 耗電量為 0.080 kWh、設施輸入總耗電量約 0.103 kWh,12 次嘗試中有 8 件通過;B 分別為 0.075 kWh、0.095 kWh,11 次嘗試中有 9 件通過。因此,每件通過任務的設施輸入總耗電量,A 約為 13 Wh,B 約為 11 Wh;按時段配對的示意地點基礎排放估值,每件約為 5.3 與 4.2 g CO2e。這只是虛構輸入值的算術結果,並非真實供應商之間可量測到的差異。

只有在另外標明增量問題時,才扣除閒置基準:A 的增量 IT 耗電量為 0.030 kWh、增量設施輸入耗電量約 0.038 kWh;B 則為 0.025 與 0.030 kWh。不能把增量數字說成維持共享服務可用的全部耗電量,也不能把年度設施 PUE 套在十分鐘作業上,冒充實測時段值。The Green Grid 對 PUE 的定義是資料中心總耗電量除以 IT 設備耗電量;此處虛構專用邊界配對得到的設施/IT 短時段比值(約 1.29 與 1.27),不是經認證的場址 PUE,也不能據此將共享資料中心用電分攤給這項工作負載。

要重複檢查算術,請將以下程式存為 energy-worksheet.py,使用 Python 標準函式庫執行 python energy-worksheet.py。程式會拒絕通過件數為零,以及設施輸入功率低於 IT 功率的不合理讀數。所有數字仍屬虛構;要提出真實主張,必須有經校準、時間同步的讀數及記載清楚的歸屬方法。

"""Illustrative, synthetic meter worksheet; not a benchmark or inventory.
Run: python energy-worksheet.py
Replace every input with measured, timestamp-aligned observations before using on a vendor claim.
"""
from decimal import Decimal as D

# Every number below is invented for arithmetic demonstration only. One row = ten minutes.
HOURS = D(1) / D(6)
IDLE_IT_W = D(100)       # separately observed idle at same meter boundary
IDLE_WALL_W = D(130)     # illustrative facility-equivalent idle, not a real facility meter
TRAINING_KWH = D(2)      # hypothetical attributable training energy, excluded from operational result
EXPECTED_LIFETIME_SUCCESSES = D(10000)  # hypothetical allocation denominator
# kg CO2e/kWh: illustrative location/time average factors; NOT certified grid data.
ROWS = {
    'A': [(D(160), D(205), D('0.4')), (D(180), D(230), D('0.5')), (D(140), D(185), D('0.3'))],
    'B': [(D(150), D(190), D('0.4')), (D(150), D(190), D('0.5')), (D(150), D(190), D('0.3'))],
}
# Same ten evaluated cases per option; attempts include failures/retries; only accepted tasks count.
COUNTS = {'A': (D(12), D(8)), 'B': (D(11), D(9))}

def calculate(rows, attempts, successes):
    if not rows or successes <= 0 or attempts < successes:
        raise ValueError('Nonempty rows and valid attempts/successes required')
    if any(it < 0 or wall < it or ef < 0 for it, wall, ef in rows):
        raise ValueError('Invalid meter boundary or emissions factor')
    it_kwh = sum((it * HOURS / 1000 for it, _, _ in rows), D(0))
    wall_kwh = sum((wall * HOURS / 1000 for _, wall, _ in rows), D(0))
    idle_it = IDLE_IT_W * HOURS * len(rows) / 1000
    idle_wall = IDLE_WALL_W * HOURS * len(rows) / 1000
    emissions_kg = sum((wall * HOURS / 1000 * ef for _, wall, ef in rows), D(0))
    return dict(it_kwh=it_kwh, wall_kwh=wall_kwh,
                incremental_it_kwh=it_kwh-idle_it,
                incremental_wall_kwh=wall_kwh-idle_wall,
                wall_it_ratio_not_pue=wall_kwh/it_kwh,
                location_kg=emissions_kg,
                wall_wh_per_success=wall_kwh*1000/successes,
                location_g_per_success=emissions_kg*1000/successes,
                conditional_training_wh_per_success=TRAINING_KWH*1000/EXPECTED_LIFETIME_SUCCESSES)

if __name__ == '__main__':
    for name, rows in ROWS.items():
        attempts, successes = COUNTS[name]
        result = calculate(rows, attempts, successes)
        print(f'{name}: {int(attempts)} attempts, {int(successes)} accepted tasks')
        for key, value in result.items():
            print(f'  {key}: {value.quantize(D("0.0001"))}')
    # Negative controls: do not silently divide by zero or accept mismatched boundaries.
    for bad_rows, attempts, successes in [(ROWS['A'], D(1), D(0)), ([(D(200), D(100), D('0.4'))], D(1), D(1))]:
        try:
            calculate(bad_rows, attempts, successes)
        except ValueError:
            pass
        else:
            raise AssertionError('Invalid input accepted')
    print('Input guards: PASS')

分開計算訓練、推論與碳排帳

表格只涵蓋推論期間的運轉用電,包含重試。若供應商還要將模型訓練分攤到產品,應另外索取訓練作業的耗電量、歸屬比例,以及預期整個使用期間成功完成的任務數。再假設可歸屬的訓練用電為 2 kWh,分攤至一萬件通過任務,每件增加 0.2 Wh;若只完成一千件,每件則增加 2 Wh。這兩種分母在本例都未經觀測。微調、實驗、儲存、硬體製造的隱含排放、設施以外的網路及客戶裝置,都未計入,除非另行量測或界定範圍。模型若由多個客戶共用,必須說明分攤規則,不能把整次訓練全算在單一試點頭上。

若供應商提出企業範疇二主張,應要求同時提供地點基礎與市場基礎數字,以及係數年份、電網地理範圍、工具類型、憑證註銷和相關品質標準的證據。不要把市場基礎的「再生能源」數字填入試算表代表實際電網的係數欄。GHG Protocol 的2015 年範疇二指引仍是現行盤查依據;其 2025 年公開徵詢草案提議更細緻的地點係數選擇,以及對部分合約工具採用逐小時配對,相關可行性安排與豁免仍在討論。這些擬議的逐小時規則不是現行強制要求。本例按時段估算地點基礎排放,只是可選的分析角度,不代表符合草案規範,也不是邊際避免排放量的計算。

依證據做選擇,不只挑最小的分子

在這個虛構試點中,B 的設施輸入總耗電量較少,也多一件通過任務;前提是兩者都達到相同的安全與延遲門檻,B 才看起來較合適。但若 A 能處理 B 漏掉的高風險升級案件,或 B 較短的回覆把工作轉嫁給審查者,A 多用一些電也可能值得。請在一般流量與高負載下重測,呈現延遲分布和失敗類型,並用多天重複測試的信賴區間,而非把極小樣本當成排名。

拿不到設施輸入資料時,應公布僅涵蓋 IT 的耗電量,另列明確假設的設施額外開銷範圍;不要將假設 PUE 標成「實測設施用電」。缺少時間戳記、地區係數或合約證據,就將相應排放欄位留為未知並說明原因。若閒置讀數波動大或場址與他人共用,應同時列出總量與增量分攤的敏感度範圍,說明可能與其他租戶重疊。若沒有任何任務通過,就不存在有限的「每件成功任務」數值;改為報告耗電量與失敗件數。也要問:觀察期拉長後,選擇會不會反轉?

可稽核的供應商資料請求應包含:電表原始時間序列與校準/邊界說明、可對應的請求 ID、重試及品質判定、版本與地區、排放係數來源與核算方法,以及排除項目和不確定性。若評估對象是裝置而非資料中心,電表位置、散熱與電池邊界都得重定義;可參考 Meydo Journal 對裝置端 AI 硬體的討論。不要將資料中心設施輸入/PUE 欄位直接套用到手機。