CodeCarbon を使用してコードの二酸化炭素排出量を測定する
機械学習モデルをトレーニングするたびに、ETL パイプラインを実行するか、バッチ ジョブをスピンします。 夜はエネルギーを消費します。そのエネルギーには実際の炭素コストがかかり、それはどこでいつランニングするかによって異なります。 コード。 ICT セクター全体が以下の責任を負っています。 世界の排出量の 2 ~ 4% CO₂の、世界の航空業界全体のシェアに匹敵します。しかし、 飛行とは異なり、ソフトウェアの排出はほとんどの場合目に見えません。
GPT-3 トレーニングは約 552トンのCO₂、300回の旅行に相当 飛行機でニューヨークとサンフランシスコを往復。 A100 GPU で 10 時間かけて BERT-large を微調整しました。 ドイツ (エネルギーミックス約 381 gCO₂/kWh) は約 1.2kgのCO₂。 同じ訓練をフランスに移した(原子力、約 56 gCO₂/kWh) 177グラム。 同じコードでも、その差はほぼ 7 倍になります。
コードカーボン は、これらの排出量を測定可能にし、 匹敵する。 Python の数行で、あらゆるプロセスの二酸化炭素排出量を追跡できます。 単一の ML 実験から実稼働パイプラインに至るまで、これらのメトリクスを統合します。 MLflow ワークフロー、ESG レポート、CI/CD パイプラインで。
何を学ぶか
- CodeCarbon の内部アーキテクチャ: エネルギーの測定方法と CO₂ 排出量の計算方法
- でセットアップ
EmissionsTrackereOfflineEmissionsTracker - TensorFlow および PyTorch モデルのトレーニング時の追跡
- NVIDIA ハードウェアの CUDA および NVML を使用した GPU 測定
- さまざまなヨーロッパ諸国とグリッド炭素強度の構成
- 実験指標としての排出量のための MLflow との統合
- matplotlib と傾向視覚化のためのプロットを備えたダッシュボード
- AWS、GCP、Azure での排出量を推定するためのクラウド二酸化炭素排出量
- ツールの比較: CodeCarbon vs Eco2AI vs CarbonTracker vs ML CO2 の影響
- 実際のケーススタディ: NLP トレーニングの最適化による排出量の 96% 削減
グリーン ソフトウェア シリーズ: 持続可能なソフトウェアを開発するための 10 の記事
| # | アイテム | 主題 | Stato |
|---|---|---|---|
| 1 | グリーン ソフトウェア財団の原則 | GSF、SCI、8つの基本原則 | 利用可能 |
| 2 | CodeCarbon で二酸化炭素排出量を測定する | 測定、追跡、ダッシュボード | 現在の記事 |
| 3 | Climatiq APIの統合 | GHG プロトコルの計算、スコープ 1 ~ 3 | 利用可能 |
| 4 | カーボンアウェア SDK | タイムシフト、ロケーションシフト | 利用可能 |
| 5 | スコープ 1、2、3: ESG データモデリング | データ構造、計算、集計 | 利用可能 |
| 6 | Kubernetes を使用した GreenOps | カーボンを意識したスケジューリング、インフラストラクチャ | 利用可能 |
| 7 | パイプライン スコープ 3 バリュー チェーン | サプライヤーデータ、監査証跡 | 利用可能 |
| 8 | ESGレポートとCSRD API | 欧州コンプライアンス、自動化 | 利用可能 |
| 9 | 持続可能な建築パターン | ストレージ、キャッシュ、カーボン対応バッチ | 利用可能 |
| 10 | AI とカーボン: ML トレーニングのフットプリント | グリーン AI、トレーニングの最適化 | 利用可能 |
CodeCarbon: アーキテクチャと動作メカニズム
CodeCarbon は、以下の共同作業によって開発されたオープンソースの Python ライブラリです。 ミラ・ケベックAI研究所、カーネギーメロン大学、Comet.ml、BCG GAMMA。 このプロジェクトは、コードエミッションの測定を目的として2020年に誕生しました。 専用のハードウェア機器を必要とせず、あらゆるデータ サイエンティストがアクセスできます。
動作原理は次の基本的な式に基づいています。
コードカーボンセントラルフォーミュラ
CO₂ 排出量 [kg] = 消費エネルギー [kWh] × ネットワークの炭素強度 [kgCO₂/kWh]
消費されるエネルギーはコンポーネントごとに測定されます (GPU + CPU + RAM)。 一方、炭素強度は国/地域ごとに更新されたデータベースから取得されます。 またはオフライン環境用に手動で提供します。
内部測定パイプライン
CodeCarbon はエネルギー消費量を次の間隔でサンプリングします。 15秒 (構成可能) スルー マルチレベルのパイプライン。各サンプリングで CPU、GPU、RAM の瞬間的な電力を測定します。 時間をかけて積分してkWhを取得し、国の排出係数を掛けます。
エネルギー測定の階層
| 成分 | 測定方法 | 精度 | 可用性 |
|---|---|---|---|
| NVIDIA GPU | pynvml 経由の NVML (NVIDIA 管理ライブラリ) | 高 (直接測定) | ドライバーを備えた NVIDIA GPU のみ |
| インテルCPU | pyRAPL による RAPL (実行平均電力制限) | 高 (ハードウェアセンサー) | MSR アクセスを備えた Linux、インテル |
| AMD/ARM CPU | 推定 TDP + 使用率 | 平均(推定) | すべてのシステム |
| ラム | 経験式: 8GBあたり3W | 低~中(推定) | すべてのシステム |
| AMD GPU | ROCm SMI (利用可能な場合) | 高 (直接測定) | ROCmを搭載したAMD GPU |
国別の炭素強度
kWh を kgCO₂ に換算するために、CodeCarbon は排出係数の階層型データベースを使用します。 オンライン モードでは、IP 地理位置情報を介してデータを取得します。オフラインモードでは、 は、240 か国以上の年間平均値を含む内部データベースを使用しています。
ヨーロッパの国別の炭素強度 (2024 年)
| Paese | gCO₂/kWh | 主なエネルギーミックス | ISOコード |
|---|---|---|---|
| ノルウェー | ~28 | 水力発電 (90%) | または |
| フランス | ~56 | 原子力 (70%) | FRA |
| スウェーデン | ~45 | 原子力 + 水力 | スウェーデン |
| スペイン | ~191 | 再生可能エネルギー + ガス | 経験値 |
| イタリア | ~233 | 天然ガス + 再生可能エネルギー | ITA |
| ドイツ | ~381 | ガス + 石炭 + 風力 | DEU |
| ポーランド | ~640 | 石炭(70%) | ポール |
CodeCarbonのセットアップとインストール
CodeCarbon をインストールするには Python 3.7 以降が必要で、PyPI と conda で利用できます。 GPU トラッキングには、NVIDIA ドライバーと pynvml パッケージが必要です。
インストール
# Installazione base
pip install codecarbon
# Con dipendenze per visualizzazione dashboard
pip install codecarbon[viz]
# Per ambienti conda
conda install -c conda-forge codecarbon
# Verifica installazione
python -c "from codecarbon import EmissionsTracker; print('CodeCarbon OK')"
# Controlla quale hardware viene rilevato
python -c "
import pynvml
try:
pynvml.nvmlInit()
count = pynvml.nvmlDeviceGetCount()
for i in range(count):
h = pynvml.nvmlDeviceGetHandleByIndex(i)
print(f'GPU {i}: ', pynvml.nvmlDeviceGetName(h))
pynvml.nvmlShutdown()
except Exception as e:
print(f'GPU non rilevata: {e}')
print('CodeCarbon usera stima TDP per CPU')
"
設定ファイル .codecarbon.config
CodeCarbon は、繰り返しを避けるプロジェクト全体の INI 設定ファイルをサポートしています。
各スクリプトのパラメータ。ファイルを作成する .codecarbon.config プロジェクトルート内:
# .codecarbon.config
[codecarbon]
# Modalità: online (default) o offline
mode = online
# Paese ISO 3166-1 alpha-3 per carbon intensity
country_iso_code = ITA
# Intervallo di campionamento in secondi (default: 15)
measure_power_secs = 15
# File di output CSV
output_file = emissions.csv
# Directory output
output_dir = ./carbon_reports
# Log level: DEBUG, INFO, WARNING, ERROR
log_level = INFO
# Salva su CodeCarbon cloud dashboard (richiede API key)
save_to_api = false
# Modalità di tracking
tracking_mode = process
EmissionsTracker: 3 つの使用モード
from codecarbon import EmissionsTracker
from codecarbon import track_emissions
import time
# ===== MODALITA 1: Context Manager (raccomandato) =====
with EmissionsTracker(
project_name="my-ml-project",
output_dir="./carbon_reports",
country_iso_code="ITA",
log_level="INFO"
) as tracker:
print("Training in corso...")
time.sleep(5) # Simula training
print(f"Emissioni: {tracker.final_emissions:.6f} kgCO2eq")
print(f"Energia: {tracker.final_emissions_data.energy_consumed:.4f} kWh")
# ===== MODALITA 2: Start/Stop Espliciti =====
tracker = EmissionsTracker(
project_name="batch-job",
output_file="batch_emissions.csv",
measure_power_secs=10
)
tracker.start()
print("Preprocessing...")
time.sleep(3)
tracker.flush() # Checkpoint senza fermare il tracking
print("Training...")
time.sleep(5)
emissions = tracker.stop()
print(f"CO2 emessa: {emissions:.6f} kgCO2eq")
# ===== MODALITA 3: Decorator =====
@track_emissions(
project_name="inference-pipeline",
country_iso_code="FRA",
output_dir="./carbon_reports"
)
def run_inference(model, data):
return model.predict(data)
OfflineEmissionsTracker: インターネットのない環境用
HPC クラスター、運用コンテナー、またはインターネット アクセスのないマシンでは、次を使用します。
OfflineEmissionsTracker。 ISO 国コードが必須になります。
from codecarbon import OfflineEmissionsTracker
tracker = OfflineEmissionsTracker(
country_iso_code="ITA", # Obbligatorio in modalità offline
project_name="hpc-training",
output_dir="/results/carbon",
measure_power_secs=30, # Meno frequente per ridurre overhead
log_level="WARNING"
)
tracker.start()
try:
run_training_pipeline()
except Exception as e:
print(f"Errore: {e}")
raise
finally:
# Chiama sempre stop() anche in caso di errore
emissions = tracker.stop()
if emissions:
print(f"[Carbon] {emissions:.4f} kgCO2eq")
# Override carbon intensity manuale (es: data center con energia 100% rinnovabile)
tracker_custom = OfflineEmissionsTracker(
country_iso_code="ITA",
# Specifica intensità carbonica del tuo fornitore (es: 20 gCO2/kWh)
# mediante variabile ambiente CODECARBON_CARBON_INTENSITY=0.020
measure_power_secs=15
)
機械学習プロジェクトにおける排出量の追跡
CodeCarbon の主な使用例は、ML モデルのトレーニング時の追跡です。 PyTorch と TensorFlow/Keras を使用した実際の例を見てみましょう。
フルカーボントラッキングを使用した PyTorch トレーニング
import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import DataLoader, TensorDataset
from codecarbon import EmissionsTracker
import numpy as np
import json
from datetime import datetime
class TextClassifier(nn.Module):
def __init__(self, vocab_size, embed_dim, num_classes):
super(TextClassifier, self).__init__()
self.embedding = nn.Embedding(vocab_size, embed_dim)
self.lstm = nn.LSTM(embed_dim, 128, batch_first=True, bidirectional=True)
self.classifier = nn.Sequential(
nn.Linear(256, 64),
nn.ReLU(),
nn.Dropout(0.3),
nn.Linear(64, num_classes)
)
def forward(self, x):
embedded = self.embedding(x)
lstm_out, _ = self.lstm(embedded)
pooled = lstm_out.mean(dim=1)
return self.classifier(pooled)
def train_with_carbon_tracking(model, train_loader, val_loader, epochs=10, country="ITA"):
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model = model.to(device)
optimizer = optim.AdamW(model.parameters(), lr=2e-4, weight_decay=0.01)
criterion = nn.CrossEntropyLoss()
scheduler = optim.lr_scheduler.CosineAnnealingLR(optimizer, T_max=epochs)
training_history = []
tracker = EmissionsTracker(
project_name=f"text-classifier-{datetime.now().strftime('%Y%m%d_%H%M')}",
output_dir="./carbon_reports",
country_iso_code=country,
log_level="WARNING",
measure_power_secs=15
)
tracker.start()
gpu_name = torch.cuda.get_device_name(0) if torch.cuda.is_available() else "N/A"
print(f"Dispositivo: {device} | GPU: {gpu_name} | Paese: {country}")
for epoch in range(epochs):
# Training
model.train()
train_loss, correct, total = 0.0, 0, 0
for X, y in train_loader:
X, y = X.to(device), y.to(device)
optimizer.zero_grad()
out = model(X)
loss = criterion(out, y)
loss.backward()
torch.nn.utils.clip_grad_norm_(model.parameters(), 1.0)
optimizer.step()
train_loss += loss.item()
correct += out.argmax(1).eq(y).sum().item()
total += y.size(0)
# Validation
model.eval()
val_correct, val_total = 0, 0
with torch.no_grad():
for X, y in val_loader:
X, y = X.to(device), y.to(device)
out = model(X)
val_correct += out.argmax(1).eq(y).sum().item()
val_total += y.size(0)
scheduler.step()
stats = {
"epoch": epoch + 1,
"train_acc": 100. * correct / total,
"val_acc": 100. * val_correct / val_total,
"train_loss": train_loss / len(train_loader),
}
training_history.append(stats)
print(f"Epoch {epoch+1}/{epochs} | "
f"Train: {stats['train_acc']:.2f}% | Val: {stats['val_acc']:.2f}%")
total_emissions = tracker.stop()
em_data = tracker.final_emissions_data
final_val_acc = training_history[-1]["val_acc"]
print(f"\n=== CARBON REPORT ===")
print(f"CO2 totale: {total_emissions:.6f} kgCO2eq")
print(f"Per epoch: {total_emissions / epochs * 1000:.2f} gCO2eq")
if em_data:
print(f"Energia: {em_data.energy_consumed:.4f} kWh")
print(f"Val accuracy: {final_val_acc:.2f}%")
if total_emissions:
print(f"Efficienza: {final_val_acc / (total_emissions * 1000):.2f} acc/gCO2")
results = {
"model": "TextClassifier-BiLSTM",
"epochs": epochs,
"final_val_accuracy": final_val_acc,
"total_co2_kg": total_emissions,
"country": country,
"training_history": training_history
}
with open("./carbon_reports/training_results.json", "w") as f:
json.dump(results, f, indent=2)
return results
if __name__ == "__main__":
X = torch.randint(0, 1000, (2000, 128))
y = torch.randint(0, 3, (2000,))
dataset = TensorDataset(X, y)
train_ds, val_ds = torch.utils.data.random_split(dataset, [1600, 400])
train_loader = DataLoader(train_ds, batch_size=32, shuffle=True)
val_loader = DataLoader(val_ds, batch_size=64)
model = TextClassifier(vocab_size=1000, embed_dim=64, num_classes=3)
train_with_carbon_tracking(model, train_loader, val_loader, epochs=5, country="ITA")
TensorFlow の Keras コールバック
import tensorflow as tf
from tensorflow import keras
from codecarbon import EmissionsTracker
import numpy as np
class CarbonTrackingCallback(keras.callbacks.Callback):
"""Callback Keras che integra CodeCarbon per il reporting per epoch."""
def __init__(self, tracker: EmissionsTracker):
super().__init__()
self.tracker = tracker
def on_epoch_end(self, epoch, logs=None):
logs = logs or {}
val_acc = logs.get('val_accuracy', 0)
print(f"\n [Carbon] Epoch {epoch+1} | Val accuracy: {val_acc:.4f}")
def train_keras_with_carbon():
vocab_size, max_len = 10000, 200
model = keras.Sequential([
keras.layers.Embedding(vocab_size, 128, input_length=max_len),
keras.layers.Bidirectional(keras.layers.LSTM(64, return_sequences=True)),
keras.layers.GlobalMaxPooling1D(),
keras.layers.Dense(64, activation='relu'),
keras.layers.Dropout(0.3),
keras.layers.Dense(1, activation='sigmoid')
])
model.compile(
optimizer=keras.optimizers.Adam(3e-4),
loss='binary_crossentropy',
metrics=['accuracy']
)
X_train = np.random.randint(0, vocab_size, (8000, max_len))
y_train = np.random.randint(0, 2, (8000,))
X_val = np.random.randint(0, vocab_size, (2000, max_len))
y_val = np.random.randint(0, 2, (2000,))
with EmissionsTracker(
project_name="keras-sentiment",
output_dir="./carbon_reports",
country_iso_code="ITA",
log_level="WARNING"
) as tracker:
history = model.fit(
X_train, y_train,
validation_data=(X_val, y_val),
epochs=10,
batch_size=64,
callbacks=[
CarbonTrackingCallback(tracker),
keras.callbacks.EarlyStopping(patience=3, restore_best_weights=True),
keras.callbacks.ReduceLROnPlateau(factor=0.5, patience=2)
],
verbose=1
)
print(f"\nEmissioni totali: {tracker.final_emissions:.6f} kgCO2eq")
print(f"Val accuracy: {max(history.history['val_accuracy']):.4f}")
return model, tracker.final_emissions
train_keras_with_carbon()
GPU トラッキング: NVIDIA NVML による正確な測定
GPU を集中的に使用するワークロードの場合、CodeCarbon は次を使用します。 pynvml、の Python バインディング NVIDIA Management Library (NVML)、直接消費電力をワット単位で測定します。 これは利用可能な最も正確な方法であり、解像度は 1 ~ 5 ワットです。
import pynvml
from codecarbon import EmissionsTracker
import torch
def inspect_gpu_power():
"""Ispezione diretta del consumo GPU con NVML (come fa CodeCarbon internamente)."""
pynvml.nvmlInit()
count = pynvml.nvmlDeviceGetCount()
print(f"GPU rilevate: {count}")
for i in range(count):
h = pynvml.nvmlDeviceGetHandleByIndex(i)
name = pynvml.nvmlDeviceGetName(h)
power_w = pynvml.nvmlDeviceGetPowerUsage(h) / 1000 # mW -> W
limit_w = pynvml.nvmlDeviceGetEnforcedPowerLimit(h) / 1000
mem = pynvml.nvmlDeviceGetMemoryInfo(h)
print(f" GPU {i}: {name}")
print(f" Consumo: {power_w:.1f}W / {limit_w:.0f}W (TDP)")
print(f" VRAM: {mem.used / 1e9:.1f}GB / {mem.total / 1e9:.1f}GB")
pynvml.nvmlShutdown()
def train_on_gpu_with_tracking():
"""Training su GPU con tracking dettagliato del consumo."""
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
tracker = EmissionsTracker(
project_name="gpu-intensive-run",
output_dir="./carbon_reports",
country_iso_code="ITA",
gpu_ids=[0], # Monitora solo GPU 0
measure_power_secs=5, # Alta frequenza per run brevi
log_level="DEBUG" # Mostra dettagli misurazione
)
tracker.start()
print(f"Dispositivo: {device}")
# Workload GPU intensivo: matrix multiplication
for step in range(100):
a = torch.randn(256, 1024, device=device)
b = torch.randn(1024, 1024, device=device)
c = torch.matmul(a, b)
loss = c.mean()
loss.backward()
if step % 25 == 0:
print(f"Step {step}/100 | Loss: {loss.item():.4f}")
emissions = tracker.stop()
data = tracker.final_emissions_data
print(f"\n=== GPU CARBON REPORT ===")
print(f"Emissioni: {emissions:.6f} kgCO2eq")
if data:
print(f"Energia: {data.energy_consumed:.4f} kWh")
return emissions
inspect_gpu_power()
train_on_gpu_with_tracking()
GPU トラッキングの制限
- CUDA のみを備えた NVIDIA: AMD GPU には ROCm が必要です。 Intel Arcはサポートされていません
- 特権のない Docker コンテナ: NVML はドライバーにアクセスできない可能性があります。
フラグを追加します
--privilegedまたはマウント/dev/nvidia* - クラウド VM: EC2/GCE/Azure では、NVML インスタンスは実際の消費量を公開しない可能性があります。 クラウドの推定にはクラウド二酸化炭素排出量を使用する
- CPU 上の RAPL: Linux では、へのアクセスが必要です
/sys/class/powercap/; macOS および Windows では TDP 推定値を使用します - 全体的な精度: 最近の研究 (2025 年) によると、推定ツールは 最大 40% のエラーが発生する可能性があります。データを絶対的な尺度ではなく、桁として使用する
MLflow との統合: 実験指標としての排出量
CodeCarbon と MLflow を統合すると、メトリクスと一緒に CO₂ 排出量を記録できるようになります モデルの(精度、損失、F1)。二酸化炭素排出量がモデル選択基準となる まさに予測パフォーマンスと同じです。
import mlflow
import mlflow.pytorch
from codecarbon import EmissionsTracker
import torch
import torch.nn as nn
from datetime import datetime
def train_with_mlflow_carbon(
model_config: dict,
train_loader,
val_loader,
country: str = "ITA",
experiment_name: str = "carbon-aware-experiments"
):
"""Training con logging doppio: MLflow per metriche, CodeCarbon per CO2."""
mlflow.set_experiment(experiment_name)
with mlflow.start_run(run_name=f"run-{datetime.now().strftime('%H%M%S')}") as run:
# Log iperparametri
mlflow.log_params({
"model_type": model_config.get("type", "unknown"),
"learning_rate": model_config.get("lr", 1e-3),
"batch_size": model_config.get("batch_size", 32),
"epochs": model_config.get("epochs", 10),
"country": country
})
# Avvia tracking CO2
tracker = EmissionsTracker(
project_name=f"mlflow-{run.info.run_id[:8]}",
output_dir="./carbon_reports",
country_iso_code=country,
log_level="WARNING"
)
tracker.start()
# Training loop
model = build_model(model_config)
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model = model.to(device)
opt = torch.optim.Adam(model.parameters(), lr=model_config.get("lr", 1e-3))
crit = nn.CrossEntropyLoss()
epochs = model_config.get("epochs", 10)
best_val_acc = 0.0
for epoch in range(epochs):
# Train
model.train()
train_loss, correct, total = 0.0, 0, 0
for X, y in train_loader:
X, y = X.to(device), y.to(device)
opt.zero_grad()
out = model(X)
loss = crit(out, y)
loss.backward()
opt.step()
train_loss += loss.item()
correct += out.argmax(1).eq(y).sum().item()
total += y.size(0)
# Validation
model.eval()
val_c, val_t = 0, 0
with torch.no_grad():
for X, y in val_loader:
X, y = X.to(device), y.to(device)
val_c += model(X).argmax(1).eq(y).sum().item()
val_t += y.size(0)
train_acc = correct / total
val_acc = val_c / val_t
best_val_acc = max(best_val_acc, val_acc)
mlflow.log_metrics({
"train_accuracy": train_acc,
"val_accuracy": val_acc,
"train_loss": train_loss / len(train_loader),
}, step=epoch)
# Log metriche CO2 al termine del training
total_emissions = tracker.stop()
em_data = tracker.final_emissions_data
carbon_metrics = {
"co2_kg": total_emissions or 0.0,
"best_val_accuracy": best_val_acc,
"carbon_efficiency": best_val_acc / (total_emissions * 1000) if total_emissions else 0.0,
}
if em_data:
carbon_metrics["energy_kwh"] = em_data.energy_consumed or 0.0
mlflow.log_metrics(carbon_metrics)
mlflow.set_tags({
"carbon_tracked": "true",
"country": country,
"hardware": "gpu" if torch.cuda.is_available() else "cpu"
})
mlflow.pytorch.log_model(model, "model")
print(f"\n=== Run {run.info.run_id} ===")
print(f"Best Val Acc: {best_val_acc:.4f}")
print(f"CO2 emessa: {total_emissions:.6f} kgCO2eq")
print(f"Carbon Efficiency: {carbon_metrics['carbon_efficiency']:.2f} acc/gCO2")
return {
"run_id": run.info.run_id,
"best_val_acc": best_val_acc,
"co2_kg": total_emissions,
"carbon_efficiency": carbon_metrics["carbon_efficiency"]
}
def build_model(config: dict) -> nn.Module:
h = config.get("hidden_size", 128)
return nn.Sequential(
nn.Linear(config.get("input_size", 784), h),
nn.ReLU(),
nn.Dropout(0.3),
nn.Linear(h, config.get("num_classes", 10))
)
mlflow-emissions-sdk: ネイティブ統合
Dataroots は、CodeCarbon へのネイティブ サポートを備えた MLflow を拡張する専用パッケージを開発しました。
クラスを提供する EmissionsTrackerMlflow 排出量を自動的に記録します
MLflow 実行のライフサイクル内。
pip install mlflow-emissions-sdk
from mlflow_emissions_sdk.tracker import EmissionsTrackerMlflow
import mlflow
with mlflow.start_run():
with EmissionsTrackerMlflow(country_iso_code="ITA") as tracker:
# Le emissioni vengono loggato automaticamente su MLflow
run_training()
# Metriche disponibili nel run MLflow dopo il context manager
ダッシュボードと排出量の視覚化
CodeCarbon は、すべての測定値を含む CSV ファイルを生成します。カスタムダッシュボードを構築できる 傾向を分析し、実験を比較し、ESG レポートを作成するには、plotly または matplotlib を使用します。
出力されるCSVの構造
CodeCarbon CSVの主なフィールド
| 分野 | ユニット | 説明 |
|---|---|---|
timestamp |
ISO8601 | 測定の瞬間 |
project_name |
- | プロジェクト名 |
duration |
secondi | 合計追跡期間 |
emissions |
kgCO₂eq | 総排出量 |
cpu_energy |
kWh | CPUのエネルギー |
gpu_energy |
kWh | GPU エネルギー |
ram_energy |
kWh | RAMエネルギー |
energy_consumed |
kWh | 総エネルギー (CPU+GPU+RAM) |
carbon_intensity |
kgCO₂/kWh | 使用される炭素強度 |
country_name |
- | 処刑された国 |
gpu_model |
- | GPU モデルが検出されました |
Plotly を使用したダッシュボードと Matplotlib を使用した静的レポート
import pandas as pd
import plotly.graph_objects as go
from plotly.subplots import make_subplots
import matplotlib.pyplot as plt
def load_emissions_data(csv_path: str = "./carbon_reports/emissions.csv") -> pd.DataFrame:
df = pd.read_csv(csv_path)
df['timestamp'] = pd.to_datetime(df['timestamp'])
df['emissions_g'] = df['emissions'] * 1000 # kgCO2 -> gCO2
df['duration_min'] = df['duration'] / 60
return df
def create_plotly_dashboard(df: pd.DataFrame, output_path: str = "./carbon_dashboard.html"):
fig = make_subplots(
rows=2, cols=2,
subplot_titles=[
"Emissioni CO2 per Run (gCO2eq)",
"Breakdown Energetico Medio",
"Emissioni per Progetto (Totale)",
"CO2 Cumulativa nel Tempo"
],
specs=[
[{"type": "bar"}, {"type": "pie"}],
[{"type": "bar"}, {"type": "scatter"}]
]
)
# 1. Bar chart emissioni per run
fig.add_trace(
go.Bar(x=df['project_name'], y=df['emissions_g'],
name="CO2 (g)", marker_color='#e74c3c',
text=df['emissions_g'].round(3), textposition='auto'),
row=1, col=1
)
# 2. Pie chart breakdown energetico
breakdown = {
'CPU': df['cpu_energy'].mean(),
'GPU': df['gpu_energy'].fillna(0).mean(),
'RAM': df['ram_energy'].mean()
}
fig.add_trace(
go.Pie(labels=list(breakdown.keys()), values=list(breakdown.values()),
marker_colors=['#3498db', '#e67e22', '#2ecc71']),
row=1, col=2
)
# 3. Emissioni aggregate per progetto
proj = df.groupby('project_name')['emissions_g'].sum().reset_index()
fig.add_trace(
go.Bar(x=proj['project_name'], y=proj['emissions_g'],
marker_color='#9b59b6'),
row=2, col=1
)
# 4. Trend cumulativo
df_s = df.sort_values('timestamp')
fig.add_trace(
go.Scatter(x=df_s['timestamp'], y=df_s['emissions_g'].cumsum(),
mode='lines+markers', line=dict(color='#e74c3c', width=2),
fill='tozeroy', fillcolor='rgba(231,76,60,0.1)'),
row=2, col=2
)
fig.update_layout(
title="CodeCarbon Dashboard: Carbon Footprint del Progetto",
height=700, showlegend=False, template="plotly_dark"
)
fig.write_html(output_path)
print(f"Dashboard salvata in: {output_path}")
return fig
def create_matplotlib_report(df: pd.DataFrame, output_dir: str = "./carbon_reports"):
fig, axes = plt.subplots(2, 2, figsize=(14, 10))
fig.suptitle("Carbon Footprint Report - CodeCarbon", fontsize=16, fontweight='bold')
colors = ['#27ae60', '#2ecc71', '#a8e6cf', '#dcedc1']
# 1. Emissioni per progetto
proj = df.groupby('project_name')['emissions_g'].sum()
axes[0,0].bar(range(len(proj)), proj.values, color=colors[0])
axes[0,0].set_xticks(range(len(proj)))
axes[0,0].set_xticklabels(proj.index, rotation=30, ha='right', fontsize=9)
axes[0,0].set_ylabel("CO2 emessa (gCO2eq)")
axes[0,0].set_title("Emissioni per Progetto")
# 2. Breakdown energetico
ev = [df['cpu_energy'].mean()*1000, df['gpu_energy'].fillna(0).mean()*1000,
df['ram_energy'].mean()*1000]
axes[0,1].pie(ev, labels=['CPU','GPU','RAM'], autopct='%1.1f%%', colors=colors)
axes[0,1].set_title("Breakdown Energetico Medio")
# 3. Emissioni vs durata
axes[1,0].scatter(df['duration_min'], df['emissions_g'],
c=colors[0], alpha=0.7, s=80, edgecolors='white')
axes[1,0].set_xlabel("Durata run (minuti)")
axes[1,0].set_ylabel("Emissioni (gCO2eq)")
axes[1,0].set_title("Emissioni vs Durata Run")
# 4. Cumulativo
cumulative = df.sort_values('timestamp')['emissions_g'].cumsum()
axes[1,1].fill_between(range(len(cumulative)), cumulative, alpha=0.3, color=colors[0])
axes[1,1].plot(range(len(cumulative)), cumulative, color=colors[0], linewidth=2)
axes[1,1].set_xlabel("Numero run")
axes[1,1].set_ylabel("CO2 Cumulativa (gCO2eq)")
axes[1,1].set_title("Andamento Emissioni Cumulativo")
plt.tight_layout()
plt.savefig(f"{output_dir}/carbon_report.png", dpi=150, bbox_inches='tight')
plt.savefig(f"{output_dir}/carbon_report.pdf", bbox_inches='tight')
print("Report salvato in carbon_report.png e .pdf")
return fig
if __name__ == "__main__":
df = load_emissions_data("./carbon_reports/emissions.csv")
create_plotly_dashboard(df)
create_matplotlib_report(df)
クラウドの二酸化炭素排出量: クラウドのワークロード排出量
CodeCarbon は、コードが実行されるマシン上のローカル排出量を測定します。分散ワークロードの場合 クラウドでは、補完的なツールが必要です。 クラウド二酸化炭素排出量 (CCF)、 元々は ThoughtWorks によって開発されたオープンソース プロジェクト。
CodeCarbon とクラウドの二酸化炭素排出量
| 特性 | コードカーボン | クラウドの二酸化炭素排出量 |
|---|---|---|
| メインターゲット | ローカル/オンプレミスコード | パブリッククラウド上のワークロード |
| データソース | ハードウェア ダイレクト (NVML、RAPL) | 課金 API クラウド プロバイダー |
| クラウドプロバイダー | あらゆるハードウェア | AWS、GCP、Azure |
| リアルタイム | はい (15 ~ 30 秒) | いいえ (請求データの遅延) |
| 粒度 | プロセスごと、GPU ごと | アカウントごと、リージョンごと、サービスごと |
| 強化カーボン (スコープ 3) | No | あり(製造見積り) |
| ウェブダッシュボード | CSV+カスタム | React ダッシュボードが付属 |
# Setup Cloud Carbon Footprint
git clone https://github.com/cloud-carbon-footprint/cloud-carbon-footprint.git
cd cloud-carbon-footprint
# Crea file .env da template
cp packages/cli/.env.template packages/cli/.env
# Configurazione AWS (aggiungi in .env):
# AWS_TARGET_ACCOUNT_ID=123456789012
# AWS_REGIONS=eu-west-1,eu-central-1
# AWS_USE_BILLING_DATA=true
# Configurazione GCP (aggiungi in .env):
# GCP_PROJECT_ID=my-project
# GCP_BIG_QUERY_TABLE=billing_export.gcp_billing_export_v1_*
npm install
# Stima emissioni dell'ultimo mese
npx ts-node packages/cli/src/index.ts \
--startDate 2025-02-01 \
--endDate 2025-02-28 \
--groupBy month \
--cloudProviderToSeed AWS
# Output in emissions.json con breakdown per servizio e regione
ツールの比較: CodeCarbon と代替ツール
コード二酸化炭素排出量測定ツールの状況は急速に進化しています。 ここでは、2025 年に最も使用されているオプションの技術的な比較を示します。
完全な比較
| 楽器 | GPU | オフライン | MLフロー | 正確さ | メンテナンス |
|---|---|---|---|---|---|
| コードカーボン | エヌビディア (NVML) | Sì | SDK経由 | 中~高 | アクティブ (2025) |
| エコ2AI | 限定 | Sì | No | 平均 | 2023年 |
| カーボントラッカー | Sì | 部分的 | No | 平均 | 2022年 |
| ML CO2 への影響 | 尊重する | 該当なし | No | 低い(推定) | ウェブツール |
| PyRAPL | No | Sì | No | 高 (インテル CPU) | 2021年 |
| カーボンアウェア SDK | 該当なし | No | No | 該当なし (シフト) | アクティブ (GSF) |
選択のガイドライン
- コードカーボン: ローカルまたはオンプレミスのハードウェアで Python で ML トレーニングを行うための主要な選択肢です。 優れた NVIDIA GPU サポート、MLflow 統合、大規模なコミュニティ。
- クラウドの二酸化炭素排出量: クラウド インフラストラクチャの炭素コスト分析用。 CodeCarbon を補完するものであり、代替品ではありません。
- ML CO2 影響計算ツール: トレーニングを開始する前に簡単に見積もりを行うための Web ツール。 計画段階でハードウェアとクラウド領域を選択するのに役立ちます。
- カーボンアウェア SDK (GSF): 排出量を測定するのではなく、時間/場所によって排出量を最小限に抑えます。 シフトする。 CodeCarbon と組み合わせて使用すると、完全な戦略が得られます。
GitHub Actions との CI/CD の統合
系統的な測定は自動化すると真に役立ちます。 ここでは、炭素予算を適用して CodeCarbon を GitHub Actions ワークフローに統合する方法を説明します。
# .github/workflows/carbon-tracking.yml
name: Carbon Footprint Tracking
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
carbon-audit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Install dependencies
run: |
pip install codecarbon pandas
pip install -r requirements.txt
- name: Run training with carbon tracking
run: |
python scripts/train.py \
--country ITA \
--output-dir ./carbon_reports \
--epochs 5
env:
CODECARBON_LOG_LEVEL: WARNING
- name: Enforce carbon budget
run: |
python - <<'PYEOF'
import pandas as pd
import sys
df = pd.read_csv('./carbon_reports/emissions.csv')
total_g = df['emissions'].sum() * 1000
BUDGET_G = 100.0 # Budget massimo per run CI
print(f"Emissioni: {total_g:.2f}g | Budget: {BUDGET_G}g")
if total_g > BUDGET_G:
print(f"BUDGET SUPERATO: {total_g:.2f}g > {BUDGET_G}g")
sys.exit(1)
print(f"OK: {total_g/BUDGET_G*100:.1f}% del budget usato")
PYEOF
- name: Upload carbon reports
uses: actions/upload-artifact@v4
if: always()
with:
name: carbon-reports-${{ github.run_id }}
path: ./carbon_reports/
retention-days: 90
- name: Comment PR with carbon summary
if: github.event_name == 'pull_request'
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
const csv = fs.readFileSync('./carbon_reports/emissions.csv', 'utf8');
const lines = csv.trim().split('\n');
const headers = lines[0].split(',');
const last = lines[lines.length - 1].split(',');
const idx = headers.indexOf('emissions');
const g = parseFloat(last[idx]) * 1000;
await github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: `### Carbon Report\n| Metrica | Valore |\n|---|---|\n| CO2 | ${g.toFixed(3)} gCO2eq |\n| Paese | ITA (233 gCO2/kWh) |`
});
炭素予算と SCI (ソフトウェア炭素強度)
from codecarbon import EmissionsTracker
from dataclasses import dataclass
@dataclass
class CarbonBudget:
project_name: str
max_co2_per_run_g: float
max_co2_monthly_kg: float
def check_run(self, emissions_kg: float) -> bool:
g = emissions_kg * 1000
if g > self.max_co2_per_run_g:
print(f"BUDGET SUPERATO: {g:.2f}g > {self.max_co2_per_run_g}g")
return False
pct = g / self.max_co2_per_run_g * 100
print(f"Budget: {pct:.1f}% usato ({g:.2f}g / {self.max_co2_per_run_g}g)")
return True
BUDGETS = {
"research": CarbonBudget("research", max_co2_per_run_g=500, max_co2_monthly_kg=10),
"production": CarbonBudget("production", max_co2_per_run_g=50, max_co2_monthly_kg=2),
"ci": CarbonBudget("ci", max_co2_per_run_g=100, max_co2_monthly_kg=5),
}
def calculate_sci(emissions_kg: float, energy_kwh: float,
functional_unit: float, unit_desc: str = "prediction") -> dict:
"""
Calcola SCI (Software Carbon Intensity) secondo la specifica GSF:
SCI = CO2eq / R (functional unit)
"""
sci = emissions_kg / max(functional_unit, 1e-9)
return {
"sci": sci,
"sci_unit": f"kgCO2eq/{unit_desc}",
"co2_kg": emissions_kg,
"energy_kwh": energy_kwh,
"equiv_km_car": emissions_kg * 4.44, # ~225 gCO2/km
"equiv_iphone_charges": int(emissions_kg / 0.000008), # ~8 Wh per ricarica
}
def run_with_budget(training_fn, budget_name="production", country="ITA"):
budget = BUDGETS.get(budget_name, BUDGETS["research"])
with EmissionsTracker(
project_name=budget.project_name,
country_iso_code=country,
output_dir="./carbon_reports"
) as tracker:
result = training_fn()
em_kg = tracker.final_emissions
en_kwh = tracker.final_emissions_data.energy_consumed if tracker.final_emissions_data else 0
budget.check_run(em_kg)
n_preds = result.get("num_predictions", 1)
sci = calculate_sci(em_kg, en_kwh, n_preds)
print(f"SCI: {sci['sci']*1e6:.2f} microgCO2eq/prediction")
print(f"Equivalente a {sci['equiv_km_car']:.3f} km in auto")
return sci
実際のケーススタディ: CodeCarbon を使用した NLP トレーニングの最適化
NLP チームは製品レビューに関する感情分類モデルをトレーニングしていました イタリア語で。目標は、90% 以上の精度を達成することでした。 CodeCarbonを導入する前に、 二酸化炭素排出量の観点からは、トレーニングプロセスは完全に不透明でした。
初期状況 (ベースライン)
ベースライン構成
| パラメータ | ベースライン値 | 最適化された価値 |
|---|---|---|
| モデル | BERT-large-uncased (340M パラメータ) | DistilBERT 多言語 (6,600 万パラメータ) |
| ハードウェア | 1x NVIDIA A100 80GB | 1x NVIDIA A100 80GB |
| データセンター地域 | ドイツ (381 gCO₂/kWh) | フランス (56 gCO₂/kWh) |
| エポック | 20 (早期停止なし) | 早期停止、エポック 9 での収束 |
| バッチサイズ | 16 (A100 30% 使用) | 128 (A100 92% 使用) |
| 混合精度 | いいえ (FP32) | はい (FP16) |
| 値の精度 | 91.2% | 90.7% |
| トレーニング期間 | ~4.5時間 | ~36分 |
CodeCarbon で測定した結果
二酸化炭素排出量の比較: ベースラインと最適化
| メトリック | ベースライン | 最適化された | 削減 |
|---|---|---|---|
| CO2排出量 | 1,723 kgCO₂eq | 0.061kgCO₂当量 | -96.5% |
| 消費エネルギー | 4.52kWh | 1.09kWh | -75.9% |
| トレーニング期間 | 4.5時間 | 36分 | -86.7% |
| 値の精度 | 91.2% | 90.7% | -0.5% (許容範囲) |
| GPU使用率 | ~30% | ~92% | +62pp |
| クラウド費用の見積もり | ~$13.50 | ~1.80ドル | -86.7% |
の削減 排出量の96.5% わずか -0.5% の精度で、次のことが証明されます。 ほとんどの場合、ML ソフトウェアの二酸化炭素排出量は大幅に増加する可能性があります。 モデルの品質を犠牲にすることなく削減されます。最も重要な教訓: 最適化する前に測定する.
ML 排出量を削減するための 5 つの介入 (影響の大きい順)
- 場所の移動 (ドイツ→フランス): 主な寄与 -85% 排出。 電力網の炭素強度は、最も影響力のある要因です。 フランス (原子力、約 56 gCO₂/kWh) とドイツ (約 381 gCO₂/kWh) では差が生じる 他のすべてが等しい場合の 7x。
- 早期停止: 平均持続時間 -55%。 ML トレーニングの大部分は収束します 設定されたエポック数よりもはるかに早いです。 3 ~ 5 の忍耐力で早期に停止すると、不必要なエポックが排除されます。
- モデル サイズの縮小 (BERT-large → DistilBERT): パラメーターが -80%、時間が -60%。 精製されたモデルまたはより小規模なモデルは、多くの場合、わずかな計算量で同等の精度を達成します。
- 混合精度 FP16: GPU エネルギー -30 ~ 50%。 NVIDIA A100 GPU、RTX 3090+ FP16 上 ハードウェアで高速化され、行列乗算演算の消費量がほぼ半分になります。
- 最適なバッチ サイズ: 同じエポックの期間が -75%。 最適なバッチサイズ 利用可能な VRAM を使用すると、GPU 使用率が最大化され、総トレーニング時間が短縮されます。
体系的な炭素追跡のベストプラクティス
推奨されるプロジェクト構造
project/
├── .codecarbon.config # Configurazione globale
├── carbon_reports/ # Output CodeCarbon
│ ├── emissions.csv # Dati grezzi
│ ├── carbon_report.png # Report grafico
│ └── unified_report.json # Report locale + cloud
├── scripts/
│ ├── train.py # Training con EmissionsTracker
│ ├── evaluate.py # Evaluation con tracker
│ └── carbon_report.py # Genera dashboard
├── .github/workflows/
│ └── carbon-tracking.yml # CI/CD con carbon budget
└── Makefile
# make train - training con tracking
# make carbon-check - verifica budget
# make carbon-report - genera dashboard
命名規則と環境変数からの設定
import os
from datetime import datetime
from codecarbon import EmissionsTracker
def create_tracker(model: str, exp_type: str, dataset: str, country: str = None) -> EmissionsTracker:
"""
Naming convention: {model}-{type}-{dataset}-{timestamp}
Es: distilbert-finetuning-imdb-it-20250309_1430
"""
ts = datetime.now().strftime('%Y%m%d_%H%M')
project_name = f"{model}-{exp_type}-{dataset}-{ts}"
country_code = country or os.environ.get('CODECARBON_COUNTRY', 'ITA')
return EmissionsTracker(
project_name = project_name,
country_iso_code= country_code,
output_dir = os.environ.get('CODECARBON_OUTPUT_DIR', './carbon_reports'),
log_level = os.environ.get('CODECARBON_LOG_LEVEL', 'WARNING'),
measure_power_secs = int(os.environ.get('CODECARBON_INTERVAL', '15'))
)
# Utilizzo
with create_tracker("distilbert", "finetuning", "imdb-it", country="FRA"):
fine_tune_model()
避けるべきアンチパターン
- 前処理を追跡しない: トークン化とデータ拡張により消費される可能性があるのは、 重要な CPU。完全なフットプリントを取得するには、追跡に必ず前処理を含めてください。
- 異なる国間の実行を比較します。 CO₂ 排出量は比較できません 異なる炭素強度を持つ国々での実行の間に直接実行されます。 kWh で正規化するか、 すべてのベンチマークに対して固定の国。
- .codecarbon.config をバージョン管理しないでください。 トラッカーの設定は次のようにする必要があります。 開発者間での測定の再現性を確保するために、リポジトリ内でバージョン管理されます。
-
例外が発生した場合はトラッカーを停止します。 常に try/finally ブロックを使用する
またはコンテキスト マネージャーがそれを確認します。
tracker.stop()にも呼び出されます クラッシュの場合、部分的なデータは保持されます。 - CSV を最終エンドポイントとして扱います。 CSV が出発点です。 分析パイプラインを構築して実用的な洞察を抽出し、実験を比較します。
CodeCarbon データを使用した炭素会計と ESG レポート
CodeCarbon によって測定された排出量は、コードの最適化に役立つだけではありません。 ESGレポートとコンプライアンスのための貴重なデータを表す CSRD指令(企業の持続可能性報告指令)を課す 欧州の大企業は2025年から2026年にかけてデジタル排出量を報告する予定。 この文脈において、CodeCarbon は開発ツールであるだけでなくガバナンス ツールとしても機能します。
GHG プロトコル (温室効果ガス プロトコル) フレームワークでは、排出量が次の 3 つの範囲に分類されます。 スコープ1 (直接排出、例: ディーゼル発電機)、 スコープ2 (購入電力量、CodeCarbon 排出量を含む) e スコープ3 (バリュー チェーン、例: クラウド ベンダーやハードウェア製品)。 CodeCarbon は主に、計算ワークロードに関連するスコープ 2 排出量をカバーします。
四半期ESGレポートのデータ集計
import pandas as pd
import json
from datetime import datetime, timedelta
from pathlib import Path
def generate_esg_report(
emissions_csv: str = "./carbon_reports/emissions.csv",
report_period: str = "Q1-2025",
company_name: str = "MyTechCompany SRL",
output_path: str = "./esg_report.json"
) -> dict:
"""
Genera un report ESG strutturato dai dati CodeCarbon.
Compatibile con CSRD / GHG Protocol Scope 2.
"""
df = pd.read_csv(emissions_csv)
df['timestamp'] = pd.to_datetime(df['timestamp'])
df['emissions_g'] = df['emissions'] * 1000
# Statistiche aggregate
total_co2_kg = df['emissions'].sum()
total_energy_kwh = df['energy_consumed'].sum()
num_experiments = len(df)
avg_co2_per_run_g = df['emissions_g'].mean()
max_co2_run_g = df['emissions_g'].max()
# Breakdown per progetto
project_breakdown = (
df.groupby('project_name')
.agg(
total_co2_kg=('emissions', 'sum'),
total_energy_kwh=('energy_consumed', 'sum'),
num_runs=('emissions', 'count'),
avg_duration_min=('duration', lambda x: (x / 60).mean())
)
.reset_index()
.to_dict(orient='records')
)
# Equivalenze per comunicazione executive
equiv_km_car = total_co2_kg * 4.44 # km in auto media (225 gCO2/km)
equiv_flights = total_co2_kg / 255 # volo Roma-Milano ~255 gCO2 per passeggero
equiv_trees_days = total_co2_kg / 0.022 # giorni assorbimento di un albero (~22 gCO2/giorno)
# Intensità carbonica media pesata
if total_energy_kwh > 0:
weighted_intensity = (df['emissions'] * 1000 / df['energy_consumed']).mean()
else:
weighted_intensity = 0.0
report = {
"report_metadata": {
"generated_at": datetime.now().isoformat(),
"report_period": report_period,
"company": company_name,
"standard": "GHG Protocol - Scope 2 (Market-based)",
"tool": "CodeCarbon v2.x",
"boundary": "Computational workloads (ML training, batch jobs)"
},
"summary": {
"total_co2_kg": round(total_co2_kg, 4),
"total_co2_tco2eq": round(total_co2_kg / 1000, 6),
"total_energy_kwh": round(total_energy_kwh, 4),
"num_tracked_runs": num_experiments,
"avg_co2_per_run_g": round(avg_co2_per_run_g, 3),
"max_co2_single_run_g": round(max_co2_run_g, 3),
"avg_carbon_intensity": round(weighted_intensity, 4)
},
"equivalences": {
"km_car_equivalent": round(equiv_km_car, 1),
"flights_equivalent": round(equiv_flights, 2),
"tree_absorption_days": round(equiv_trees_days, 1)
},
"project_breakdown": project_breakdown,
"scope_classification": {
"scope": 2,
"category": "Purchased electricity for owned operations",
"methodology": "Activity-based (hardware power measurement)",
"data_quality": "High (direct measurement via NVML/RAPL)"
}
}
with open(output_path, 'w') as f:
json.dump(report, f, indent=2, default=str)
print(f"=== Report ESG {report_period} ===")
print(f"CO2 totale: {total_co2_kg:.4f} kgCO2eq")
print(f"Energia: {total_energy_kwh:.4f} kWh")
print(f"Equivalente a: {equiv_km_car:.1f} km in auto")
print(f"Run tracciati: {num_experiments}")
print(f"Report in: {output_path}")
return report
# Genera report per Q1 2025
report = generate_esg_report(
emissions_csv="./carbon_reports/emissions.csv",
report_period="Q1-2025",
company_name="Acme AI SRL",
output_path="./esg_carbon_q1_2025.json"
)
削減目標と科学に基づいた目標 (SBTi)
Science Based Targets イニシアチブ (SBTi) に参加する企業は、削減に取り組んでいます。 パリ協定の気候目標に沿った排出量。 ICT排出量については、 これは通常、年間の削減を意味します 4~7%。 CodeCarbon を使用すると、これらの目標に向けた進捗状況を自動的に追跡できます。
import pandas as pd
from datetime import datetime
def track_reduction_progress(
emissions_csv: str,
baseline_year: int,
target_reduction_pct: float = 5.0, # 5% riduzione annuale
) -> dict:
"""
Traccia il progresso verso gli obiettivi di riduzione SBTi.
"""
df = pd.read_csv(emissions_csv)
df['timestamp'] = pd.to_datetime(df['timestamp'])
df['year'] = df['timestamp'].dt.year
annual_emissions = df.groupby('year')['emissions'].sum().to_dict()
baseline_emissions = annual_emissions.get(baseline_year, 0)
current_year = datetime.now().year
current_emissions = annual_emissions.get(current_year, 0)
years_elapsed = current_year - baseline_year
target_reduction_factor = (1 - target_reduction_pct / 100) ** years_elapsed
target_emissions = baseline_emissions * target_reduction_factor
actual_reduction_pct = 0.0
on_track = False
if baseline_emissions > 0:
actual_reduction_pct = (baseline_emissions - current_emissions) / baseline_emissions * 100
on_track = current_emissions <= target_emissions
return {
"baseline_year": baseline_year,
"baseline_emissions_kg": round(baseline_emissions, 4),
"current_year": current_year,
"current_emissions_kg": round(current_emissions, 4),
"target_emissions_kg": round(target_emissions, 4),
"target_annual_reduction_pct": target_reduction_pct,
"actual_reduction_pct": round(actual_reduction_pct, 2),
"on_track": on_track,
"annual_history": {str(k): round(v, 4) for k, v in annual_emissions.items()}
}
# Utilizzo: verifica se il team e' in linea con gli obiettivi SBTi
progress = track_reduction_progress(
emissions_csv="./carbon_reports/emissions.csv",
baseline_year=2024,
target_reduction_pct=5.0
)
status = "IN LINEA" if progress['on_track'] else "SOTTO TARGET"
print(f"Obiettivi SBTi: {status}")
print(f"Riduzione attuale: {progress['actual_reduction_pct']:.1f}%")
print(f"Target annuale: {progress['target_annual_reduction_pct']:.1f}%")
CodeCarbon と CSRD: 知っておくべきこと
CSRD指令(企業持続可能性報告指令)は欧州企業に義務付けています。 従業員数500名以上(2025年~)、その後従業員数250名以上(2026年~) ESRS基準(欧州持続可能性報告基準)に従ってGHG排出量を報告すること。 デジタル リリースの場合:
- ESRS E1 (気候変動): スコープ 1、2、および 3 の排出量の開示が必要 GHGプロトコル手法を使用。 CodeCarbon は計算操作のスコープ 2 をカバーします。
- 重要性: ICT 排出量が重大な場合(比較して有意な量) 会社合計に)報告する必要があります。テクノロジー企業の場合、これはほぼ常に当てはまります。
- 監査証跡: CodeCarbon CSV は検証のための詳細な監査証跡を提供します 第三者による報告は、ESG レポートの信頼性にとって不可欠な要件です。
- 保証: CSRD は、限定的 (2025 年以降) かつ合理的な (2028 年以降) の保証を要求します。 CodeCarbon データの品質 (直接測定と推定) は非常に重要です。
結論: 測定は最初のステップです
CodeCarbon はコード カーボン トラッキングを学術的な演習から実践的なものに変えました 具体的でアクセスしやすいエンジニアリング。 10 行未満の Python を使えば、どんなデータ サイエンティストでも o ML エンジニアは、自分の仕事が環境に与える影響の測定と定量化を開始できます。
ケーススタディでは、 CO₂ 排出量の 96.5% 精度はわずか -0.5% です。これは例外的なケースではなく、通常のことです。 最適化されていない構成から始めます。ほとんどの ML トレーニングには大きなマージンがあります 測定を開始するまで目に見えない炭素最適化の結果。
より持続可能なソフトウェアへの道は 3 つの段階に従います。
- 測定: CodeCarbon をすべてのワークフローに統合します。炭素予算を定義します。 測定可能なベースラインを作成します。排出量を精度と同じくらい可視化します。
- 最適化する: データを使用して二酸化炭素のボトルネックを特定します。場所移動、 モデル サイズ、バッチ サイズ、および混合精度が最も効果的な手段です。
- 防ぐ: 炭素追跡を CI/CD に統合します。炭素収支をタイプ別に定義する 実験の。 Carbon Aware SDK を使用して、位置/時間のシフトを自動化します。
シリーズの次の記事では、詳しく説明します。 Climatiq API、ツール GHG プロトコル排出量 (スコープ 1、2、および 3) を計算できるようにする補完的な機能です。 REST API。ESG レポートを自動化するためにアプリケーションのバックエンドに計算を統合します。







