CodeCarbon ile kodunuzun karbon ayak izini ölçme
Bir makine öğrenimi modelini her eğittiğinizde, bir ETL işlem hattını çalıştırır veya bir toplu işi döndürürsünüz geceleri enerji tüketirsiniz. Bu enerjinin gerçek bir karbon maliyeti vardır ve bu, nerede ve ne zaman koştuğunuza bağlıdır kod. Bir bütün olarak BİT sektörü sorumludur. Küresel emisyonların %2-4'ü CO₂Bu, tüm küresel havacılık endüstrisinin payı ile karşılaştırılabilecek bir paydır. Ama bir Uçuşun aksine, yazılım emisyonları neredeyse her zaman görünmez.
GPT-3 eğitimi yaklaşık olarak üretildi 552 ton CO₂300 seyahate eşdeğer uçakla New York-San Francisco gidiş-dönüş. A100 GPU'da 10 saat boyunca BERT-large'in ince ayarı Almanya (enerji karışımı ~381 gCO₂/kWh) yaklaşık 1,2 kg CO₂. Aynı eğitim Fransa'ya taşındı (nükleer, ~56 gCO₂/kWh) yalnızca üretim yapıyor 177 gram. Aynı kod için fark neredeyse 7 kattır.
KodKarbon bu emisyonları ölçülebilir hale getiren açık kaynaklı bir araçtır ve karşılaştırılabilir. Birkaç satır Python ile herhangi bir sürecin karbon ayak izini takip edebilirsiniz. Tek makine öğrenimi deneyinden üretim hattına kadar hesaplamalı ve bu ölçümleri entegre edin MLflow iş akışlarınızda, ESG raporlarınızda ve CI/CD işlem hatlarınızda.
Ne Öğreneceksiniz
- CodeCarbon'un iç mimarisi: enerjiyi nasıl ölçer ve CO₂ emisyonlarını nasıl hesaplar?
- Şununla kurulum:
EmissionsTrackereOfflineEmissionsTracker - TensorFlow ve PyTorch modellerini eğitirken izleme
- NVIDIA donanımı için CUDA ve NVML ile GPU ölçümü
- Farklı Avrupa ülkeleri ve şebeke karbon yoğunluğu için konfigürasyon
- Deney ölçümleri olarak emisyonlar için MLflow ile entegrasyon
- Trend görselleştirmesi için matplotlib ve komplo içeren kontrol paneli
- AWS, GCP ve Azure'da emisyonları tahmin etmek için Bulut Karbon Ayak İzi
- Araç karşılaştırması: CodeCarbon vs Eco2AI vs CarbonTracker vs ML CO2 Etkisi
- Gerçek örnek olay: Emisyonlarda %96 azalma sağlayan NLP eğitim optimizasyonu
Yeşil Yazılım Serisi: Sürdürülebilir Yazılım Geliştirmeye Yönelik 10 Makale
| # | Öğe | Ders | Durum |
|---|---|---|---|
| 1 | Yeşil Yazılımın Temel İlkeleri | GSF, SCI, 8 temel prensip | Mevcut |
| 2 | CodeCarbon ile Karbon Ayak İzinizi Ölçme | Ölçüm, takip, kontrol paneli | Güncel makale |
| 3 | Climatiq API'yi entegre edin | Sera Gazı Protokolü hesaplamaları, Kapsam 1-3 | Mevcut |
| 4 | Karbon Bilinçli SDK | Zamanın değişmesi, yerin değişmesi | Mevcut |
| 5 | Kapsam 1, 2 ve 3: ÇSY Veri Modellemesi | Veri yapısı, hesaplamalar, toplama | Mevcut |
| 6 | Kubernetes ile GreenOps | Karbon bilinçli planlama, altyapı | Mevcut |
| 7 | Boru Hattı Kapsam 3 Değer Zinciri | Tedarikçi verileri, denetim takibi | Mevcut |
| 8 | ESG Raporlaması ve CSRD API'si | Avrupa uyumluluğu, otomasyon | Mevcut |
| 9 | Sürdürülebilir Mimari Desenler | Depolama, önbellek, karbona duyarlı toplu iş | Mevcut |
| 10 | Yapay Zeka ve Karbon: ML Eğitim Ayak İzi | Yeşil yapay zeka, eğitim optimizasyonu | Mevcut |
CodeCarbon: Mimari ve İşletim Mekanizması
CodeCarbon, aralarındaki işbirliğiyle geliştirilen açık kaynaklı bir Python kütüphanesidir. Mila Quebec Yapay Zeka Enstitüsü, Carnegie Mellon Üniversitesi, Comet.ml ve BCG GAMMA. Proje 2020 yılında kod emisyonlarının ölçümünü yapmak amacıyla doğdu. özel donanım ekipmanı gerektirmeden herhangi bir veri bilimcinin erişimine açıktır.
Çalışma prensibi temel bir formüle dayanmaktadır:
KodKarbon Merkezi Formülü
yayılan CO₂ [kg] = Tüketilen enerji [kWh] × Ağın karbon yoğunluğu [kgCO₂/kWh]
Tüketilen enerji bileşen bileşen ölçülür (GPU + CPU + RAM), karbon yoğunluğu ülkeye/bölgeye göre güncellenen veri tabanlarından alınırken veya çevrimdışı ortamlar için manuel olarak sağlanır.
Dahili Ölçüm Hattı
CodeCarbon her yıl enerji tüketimini örnekliyor 15 saniye (yapılandırılabilir) aracılığıyla çok seviyeli bir boru hattı. Her örneklemede CPU, GPU ve RAM'in anlık gücünü ölçer, kWh elde etmek için zamanla entegre olun ve ülkenin emisyon faktörüyle çarpın.
Enerji Ölçüm Hiyerarşisi
| Bileşen | Ölçüm Yöntemi | Kesinlik | Kullanılabilirlik |
|---|---|---|---|
| NVIDIA GPU'lar | Pynvml (NVIDIA Yönetim Kütüphanesi) aracılığıyla NVML | Yüksek (doğrudan ölçüm) | Yalnızca sürücülü NVIDIA GPU'lar |
| Intel CPU | pyRAPL aracılığıyla RAPL (Çalışan Ortalama Güç Limiti) | Yüksek (donanım sensörleri) | MSR erişimli Linux, Intel |
| AMD/ARM CPU'lar | Tahmini TDP + kullanım yüzdesi | Ortalama (tahmin) | Tüm sistemler |
| Veri deposu | Ampirik formül: 8 GB başına 3 W | Düşük-Orta (tahmin) | Tüm sistemler |
| AMD GPU'lar | ROCm SMI (varsa) | Yüksek (doğrudan ölçüm) | ROCm'li AMD GPU |
Ülkelere Göre Karbon Yoğunluğu
CodeCarbon, kWh'yi kgCO₂'ye çevirmek için hiyerarşik bir emisyon faktörleri veritabanı kullanır. Çevrimiçi modda, verileri IP konum belirleme yoluyla alın. Çevrimdışı modda, 240'tan fazla ülke için yıllık ortalama değerleri içeren dahili bir veritabanı kullanır.
Avrupa Ülkelerine Göre Karbon Yoğunluğu (2024)
| Köy | gCO₂/kWh | Ana Enerji Karışımı | ISO kodu |
|---|---|---|---|
| Norveç | ~28 | Hidroelektrik (%90) | VEYA |
| Fransa | ~56 | Nükleer (%70) | ARASINDA |
| İsveç | ~45 | Nükleer + Hidro | SWE |
| İspanya | ~191 | Yenilenebilir Enerji + Gaz | EXP |
| İtalya | ~233 | Doğal gaz + Yenilenebilir kaynaklar | İTA |
| Almanya | ~381 | Gaz + Kömür + Rüzgar | DEÜ |
| Polonya | ~640 | Kömür (%70) | POL |
CodeCarbon Kurulumu ve Kurulumu
CodeCarbon'u yüklemek Python 3.7+ gerektirir ve PyPI ve conda'da mevcuttur. GPU takibi için NVIDIA sürücülerine ve pynvml paketine ihtiyacınız var.
Kurulum
# 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')
"
Yapılandırma Dosyası .codekarbon.config
CodeCarbon, tekrarlamayı önleyen, proje çapında bir INI yapılandırma dosyasını destekler
her komut dosyasındaki parametreler. Dosya oluştur .codecarbon.config proje kökünde:
# .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: Üç Kullanım Modu
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: İnternet Olmayan Ortamlar İçin
HPC kümelerinde, üretim konteynerlerinde veya internet erişimi olmayan makinelerde şunu kullanın:
OfflineEmissionsTracker. ISO ülke kodu zorunlu hale geliyor.
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
)
Makine Öğrenimi Projelerinde Emisyonların Takibi
CodeCarbon'un birincil kullanım durumu, makine öğrenimi modellerini eğitirken izleme yapmaktır. PyTorch ve TensorFlow/Keras ile pratik örnekler görelim.
Tam Karbon Takibi ile PyTorch Eğitimi
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 için Keras geri araması
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 İzleme: NVIDIA NVML ile Hassas Ölçüm
GPU yoğun iş yükleri için CodeCarbon şunları kullanır: pynvml, Python bağlaması Doğrudan güç tüketimini watt cinsinden ölçmek için NVIDIA Yönetim Kitaplığı (NVML). Bu, 1-5 watt çözünürlükle mevcut en hassas yöntemdir.
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 İzlemenin Sınırlamaları
- Yalnızca CUDA'lı NVIDIA: AMD GPU'lar ROCm gerektirir; Intel Arc desteklenmiyor
- Ayrıcalıklı olmayan Docker kapsayıcıları: NVML'nin sürücülere erişimi olmayabilir;
bayrağı ekle
--privilegedveya montaj/dev/nvidia* - Bulut VM'leri: EC2/GCE/Azure'da NVML örnekleri gerçek tüketimi ortaya çıkarmayabilir; bulut tahminleri için Bulut Karbon Ayak İzini kullanın
- CPU'da RAPL: Linux'ta erişim gerektirir
/sys/class/powercap/; macOS ve Windows'ta TDP tahminini kullanın - Genel Doğruluk: Son araştırmalar (2025), tahmin araçlarının %40'a varan hatalara sahip olabilirler; Verileri mutlak bir ölçü olarak değil, büyüklük sırası olarak kullanın
MLflow ile Entegrasyon: Deney Metrikleri Olarak Emisyonlar
CodeCarbon'u MLflow ile entegre etmek, ölçümlerin yanı sıra CO₂ emisyonlarını da kaydetmenize olanak tanır modelin (doğruluk, kayıp, F1). Karbon ayak izi model seçim kriteri haline geliyor tam olarak tahmin performansı gibi.
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: Yerel Entegrasyon
Dataroots, MLflow'u CodeCarbon'a yerel destekle genişleten özel bir paket geliştirdi.
sınıfı sağlamak EmissionsTrackerMlflow Emisyonları otomatik olarak kaydeden
bir MLflow çalıştırmasının yaşam döngüsünde.
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
Kontrol Paneli ve Emisyon Görselleştirmesi
CodeCarbon tüm ölçümleri içeren bir CSV dosyası oluşturur. Özel kontrol panelleri oluşturabilirsiniz Trendleri analiz etmek, deneyleri karşılaştırmak ve ESG raporları hazırlamak içinplotly veya matplotlib ile.
Çıkış CSV'sinin Yapısı
CodeCarbon CSV'nin ana alanları
| Alan | Birim | Tanım |
|---|---|---|
timestamp |
ISO8601 | Ölçüm anı |
project_name |
- | Proje adı |
duration |
saniye | Toplam izleme süresi |
emissions |
kgCO₂eş | Toplam emisyonlar |
cpu_energy |
kWh | CPU enerjisi |
gpu_energy |
kWh | GPU enerjisi |
ram_energy |
kWh | RAM enerjisi |
energy_consumed |
kWh | Toplam Enerji (CPU+GPU+RAM) |
carbon_intensity |
kgCO₂/kWh | Kullanılan karbon yoğunluğu |
country_name |
- | İcra ülkesi |
gpu_model |
- | GPU modeli algılandı |
Matplotlib ile Plotly ve Statik Raporlu Kontrol Paneli
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)
Bulut Karbon Ayak İzi: Bulut İş Yükü Emisyonları
CodeCarbon, kodun çalıştığı makinedeki yerel emisyonları ölçer. Dağıtılmış iş yükleri için bulutta tamamlayıcı bir araca ihtiyacınız var: Bulut Karbon Ayak İzi (CCF), Başlangıçta ThinkWorks tarafından geliştirilen açık kaynaklı proje.
CodeCarbon vs Bulut Karbon Ayak İzi
| karakteristik | KodKarbon | Bulut Karbon Ayak İzi |
|---|---|---|
| Ana hedef | Yerel / şirket içi kod | Genel bulutta iş yükü |
| Veri kaynağı | Doğrudan Donanım (NVML, RAPL) | Faturalandırma API'si bulut sağlayıcıları |
| Bulut sağlayıcıları | Herhangi bir donanım | AWS, GCP, Azure |
| Gerçek zamanlı | Evet (15-30 sn) | Hayır (gecikmeli faturalandırma verileri) |
| Parçalılık | İşlem başına, GPU başına | Hesap başına, bölge başına, hizmet başına |
| Gömülü karbon (Kapsam 3) | No | Evet (üretim tahmini) |
| Web kontrol panelleri | CSV + özel | React kontrol paneli dahildir |
# 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
Araç Karşılaştırması: CodeCarbon ve Alternatifler
Kod karbon ayak izi ölçüm araçlarının kapsamı hızla gelişiyor. İşte 2025'te en çok kullanılan seçeneklerin teknik bir karşılaştırması.
Tam Karşılaştırma
| Enstrüman | GPU | Çevrimdışı | ML akışı | Kesinlik | Bakım |
|---|---|---|---|---|---|
| KodKarbon | NVIDIA (NVML) | Sì | SDK aracılığıyla | Orta-Yüksek | Aktif (2025) |
| Eco2AI | Sınırlı | Sì | No | Ortalama | 2023 |
| Karbon Takipçisi | Sì | Kısmi | No | Ortalama | 2022 |
| ML CO2 Etkisi | Saygı | Yok | No | Düşük (tahmin) | Web araçları |
| PyRAPL | No | Sì | No | Yüksek (Intel CPU) | 2021 |
| Karbon Bilinçli SDK | Yok | No | No | Yok (değişiyor) | Aktif (GSF) |
Seçim Yönergeleri
- KodKarbon: Yerel veya şirket içi donanımda Python'da makine öğrenimi eğitimi için önde gelen seçim. Mükemmel NVIDIA GPU desteği, MLflow entegrasyonu, geniş topluluk.
- Bulut Karbon Ayak İzi: Bulut altyapısının karbon maliyeti analizi için. CodeCarbon'un tamamlayıcısıdır, yerine geçmez.
- ML CO2 Etki Hesaplayıcısı: Eğitime başlamadan önce hızlı tahminler için web aracı. Donanım ve bulut bölgesini seçmek planlama aşamasında faydalıdır.
- Karbon Uyumlu SDK (GSF): Emisyonları ölçmez ancak zaman/konum aracılığıyla bunları en aza indirir değişiyor. Eksiksiz bir strateji için CodeCarbon ile birlikte kullanın.
GitHub Eylemleriyle CI/CD entegrasyonu
Sistematik ölçüm, otomatikleştirildiğinde gerçekten faydalı hale gelir. CodeCarbon'u karbon bütçesi uygulamasıyla GitHub Eylemleri iş akışına nasıl entegre edeceğiniz aşağıda açıklanmıştır.
# .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) |`
});
Karbon Bütçesi ve SCI (Yazılım Karbon Yoğunluğu)
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
Gerçek Vaka Çalışması: CodeCarbon ile NLP Eğitim Optimizasyonu
Bir NLP ekibi ürün incelemeleri üzerine bir duyarlılık sınıflandırma modeli eğitiyordu İtalyanca. Hedef %90'ın üzerinde doğruluk elde etmekti. CodeCarbon'u tanıtmadan önce, Eğitim süreci, karbon ayak izi açısından tamamen şeffaf değildi.
Başlangıç Durumu (Temel Durum)
Temel yapılandırma
| Parametre | Temel değer | Optimize Edilmiş Değer |
|---|---|---|
| Modeli | BERT-büyük-kasasız (340M parametreler) | DistilBERT çok dilli (66M parametre) |
| Donanım | 1xNVIDIA A100 80GB | 1xNVIDIA A100 80GB |
| Veri merkezi bölgesi | Almanya (381 gCO₂/kWh) | Fransa (56 gCO₂/kWh) |
| Çağlar | 20 (erken durmadan) | Erken durma, 9. dönemde yakınsama |
| Parti boyutu | 16 (A100 %30 kullanıldı) | 128 (A100 %92 kullanıldı) |
| Karışık hassasiyet | Hayır (FP32) | Evet (FP16) |
| Değer doğruluğu | %91,2 | %90,7 |
| Eğitim süresi | ~4,5 saat | ~36 dakika |
CodeCarbon ile Ölçülen Sonuçlar
Karbon Ayak İzi Karşılaştırması: Temel ve Optimize Edilmiş
| Metrik | Temel çizgiler | Optimize edilmiş | Kesinti |
|---|---|---|---|
| CO2 emisyonu | 1.723 kgCO₂eşd | 0,061 kgCO₂eşd | -%96,5 |
| Tüketilen enerji | 4,52 kWh | 1,09 kWh | -75,9% |
| Eğitim süresi | 4,5 saat | 36 dakika | -%86,7 |
| Değer Doğruluğu | %91,2 | %90,7 | -%0,5 (kabul edilebilir) |
| GPU Kullanımı | ~%30 | ~%92 | +62 puan |
| Tahmini bulut maliyeti | ~13,50$ | ~1,80$ | -%86,7 |
Azaltılması Emisyonların %96,5'i yalnızca %-0,5 doğrulukla şunu kanıtlıyor: çoğu durumda makine öğrenimi yazılımının karbon ayak izi büyük ölçüde model kalitesinden ödün vermeden azaltılmıştır. En önemli ders: optimizasyondan önce ölçün.
ML Emisyonlarını Azaltmaya Yönelik 5 Müdahale (etki sırasına göre)
- Yer değiştirme (Almanya → Fransa): ana katkı -%85 emisyon. Elektrik şebekesinin karbon yoğunluğu en etkili faktördür. Fransa (nükleer, ~56 gCO₂/kWh) ile Almanya (~381 gCO₂/kWh) arasında fark yaratıyor 7x'in diğer her şey eşit olması.
- Erken durdurma: -%55 ortalama süre. ML eğitiminin çoğunluğu birleşiyor yapılandırılmış dönem sayısından çok daha erken. 3-5 sabırla erken durmak gereksiz dönemleri ortadan kaldırır.
- Küçültülmüş model boyutu (BERT-büyük → DistilBERT): -%80 parametreler, -%60 zaman. Damıtılmış veya daha küçük modeller genellikle hesaplamanın çok küçük bir bölümünde karşılaştırılabilir doğruluk elde eder.
- Karışık hassas FP16: -%30-50 GPU enerjisi. NVIDIA A100 GPU, RTX 3090+ ve FP16'da Donanımla hızlandırılır ve matris çarpma işlemlerindeki tüketimi neredeyse yarıya indirir.
- Optimum parti boyutu: Aynı dönemler için -%75 süre. Optimum parti boyutu kullanılabilir VRAM için GPU kullanımını en üst düzeye çıkarır ve toplam eğitim süresini azaltır.
Sistematik Karbon Takibi İçin En İyi Uygulamalar
Önerilen Proje Yapısı
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
Ortam Değişkenlerinden Adlandırma Kuralı ve Yapılandırma
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()
Kaçınılması Gereken Anti-Desenler
- Ön işlemeyi izleme: Tokenleştirme ve veri artırma tüketebilir Önemli CPU. Tam ayak izini elde etmek için izlemenize her zaman ön işlemeyi dahil edin.
- Farklı ülkeler arasındaki koşuları karşılaştırın: CO₂ emisyonları karşılaştırılamaz Farklı karbon yoğunluklarına sahip ülkelerdeki çalışmalar arasında doğrudan. kWh ile normalleştirin veya kullanın tüm kıyaslamalar için sabit bir ülke.
- .codekarbon.config dosyasının sürümünü değiştirmeyin: İzleyici yapılandırması şu şekilde olmalıdır: geliştiriciler arasında ölçümlerin tekrarlanabilirliğini sağlamak için depoda sürümlendirilmiştir.
-
İstisnai durumlarda izleyiciyi durdurun: Her zaman bir try/finally bloğu kullanın
veya içerik yöneticisinin bunu sağlamak için
tracker.stop()ayrıca çağrılır Kilitlenme durumunda kısmi veriler korunuyor. - CSV'yi son uç nokta olarak ele alın: CSV başlangıç noktasıdır. Eyleme dönüştürülebilir içgörüler elde etmek ve deneyleri karşılaştırmak için analiz hatları oluşturun.
CodeCarbon Verileri ile Karbon Muhasebesi ve ÇSY Raporlaması
CodeCarbon tarafından ölçülen emisyonlar yalnızca kodun optimize edilmesi için yararlı değildir: ÇSY raporlaması ve uyumluluğu için değerli verileri temsil eder CSRD Direktifi (Kurumsal Sürdürülebilirlik Raporlama Direktifi), bu da dayatıyor Büyük Avrupalı şirketler 2025-2026'dan itibaren dijital emisyonları raporlayacak. Bu bağlamda CodeCarbon bir geliştirme aracı olmanın yanı sıra bir yönetişim aracına da dönüşüyor.
Sera Gazı Protokolü (Sera Gazı Protokolü) çerçevesi emisyonları üç kapsamda sınıflandırır: Kapsam 1 (doğrudan emisyonlar, örneğin dizel jeneratörler), Kapsam 2 (CodeCarbon emisyonlarını içeren satın alınan elektrik) e Kapsam 3 (değer zinciri, örneğin bulut satıcısı ve donanım ürünü). CodeCarbon öncelikle hesaplamalı iş yükleriyle ilgili Kapsam 2 emisyonlarını kapsar.
Üç Aylık ÇSY Raporları için Veri Toplama
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"
)
Azaltma Hedefleri ve Bilime Dayalı Hedefler (SBTi)
Bilime Dayalı Hedefler girişimine (SBTi) katılan şirketler, Paris Anlaşması'nın iklim hedeflerine uygun emisyonlar. BİT emisyonları için, bu genellikle yıllık bir azalma anlamına gelir %4-7. CodeCarbon bu hedeflere doğru ilerlemeyi otomatik olarak izlemek için kullanılabilir.
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 ve CSRD: Bilmeniz Gerekenler
CSRD Direktifi (Kurumsal Sürdürülebilirlik Raporlama Direktifi), Avrupalı şirketlerin 500'den fazla çalışanı olanlara (2025'ten itibaren) ve ardından 250'den fazla çalışanı olanlara (2026'dan itibaren) Sera gazı emisyonlarını ESRS standartlarına (Avrupa Sürdürülebilirlik Raporlama Standartları) göre raporlamak. Dijital yayınlar için:
- ESRS E1 (İklim değişikliği): Kapsam 1, 2 ve 3 emisyonlarının açıklanmasını gerektirir Sera Gazı Protokolü metodolojisi ile. CodeCarbon hesaplama işlemlerinin Kapsam 2'sini kapsar.
- Önemlilik: BİT emisyonları önemliyse (karşılaştırıldığında anlamlı şirket toplamına) bildirilmesi gerekmektedir. Teknoloji şirketleri için bu neredeyse her zaman böyledir.
- Denetim izleri: CodeCarbon CSV'leri doğrulama için ayrıntılı bir denetim yolu sağlar üçüncü taraf raporlaması, ÇSY raporunun güvenilirliği için temel bir gerekliliktir.
- Güvence: CSRD, sınırlı (2025'ten itibaren) ve makul (2028'den itibaren) güvence gerektirir. CodeCarbon verilerinin kalitesi (doğrudan ölçüm ve tahmin) çok önemlidir.
Sonuçlar: Ölçüm ilk adımdır
CodeCarbon, kod karbon takibini akademik bir alıştırmadan pratiğe dönüştürdü Beton ve erişilebilir mühendislik. 10 satırdan az Python satırına sahip herhangi bir veri bilimci o ML mühendisi, çalışmalarının çevresel etkisini ölçmeye ve sayısallaştırmaya başlayabilir.
Vaka çalışması bir azalma gösterdi CO₂ emisyonlarının %96,5'i yalnızca %-0,5 doğrulukla. Bu istisnai bir durum değil; normal bir durumdur. optimize edilmemiş bir konfigürasyondan başlıyoruz. Çoğu makine öğrenimi eğitiminin büyük marjları var siz ölçüme başlayana kadar görünmez kalan karbon optimizasyonu.
Daha sürdürülebilir yazılıma giden yol üç aşamadan oluşur:
- Ölçüm: CodeCarbon'u tüm iş akışlarına entegre edin. Karbon bütçesini tanımlayın. Ölçülebilir temeller oluşturun. Emisyonları doğruluk kadar görünür hale getirin.
- Optimize edin: Karbon darboğazlarını belirlemek için verileri kullanın. Yer değiştirme, model boyutu, parti boyutu ve karma hassasiyet en etkili kaldıraçlardır.
- Önlemek: Karbon takibini CI/CD'ye entegre edin. Türe göre karbon bütçesini tanımlayın deney. Konum/zaman değiştirmeyi otomatikleştirmek için Carbon Aware SDK'yı kullanın.
Serinin bir sonraki makalesinde inceleyeceğiz İklimlendirme API'si, bir araç Sera Gazı Protokolü emisyonlarını (Kapsam 1, 2 ve 3) hesaplamanıza olanak tanıyan tamamlayıcı Otomatik ESG raporlaması için hesaplamaları uygulamaların arka ucuna entegre eden REST API.
Kaynaklar ve Faydalı Bağlantılar
Yeşil Yazılım Serisi devam ediyor
- Madde 1: Yeşil Yazılımın Temel İlkeleri — GSF, SCI, 8 ilkeleri
- Madde 2 (güncel): Karbon Ayak İzinizi CodeCarbon ile Ölçmek
- Madde 3: Climatiq API — Sera Gazı Protokolü hesaplamalarını arka uca entegre edin
- Madde 4: Carbon Aware SDK - Zaman kaydırma ve konum değiştirme
- Madde 6: Kubernetes ile GreenOps — Karbon farkındalığına sahip altyapı
- Madde 10: Yapay Zeka ve Karbon - ML Eğitiminin ayak izini ölçmek ve azaltmak







