mlco2 / codecarbon

Track emissions from Compute and recommend ways to reduce their impact on the environment.
https://mlco2.github.io/codecarbon
MIT License
1.11k stars 173 forks source link

Is it right that the Carbon Intensity of Solar, Wind, ... is ignored in your calculations? #673

Closed headscott closed 3 hours ago

headscott commented 1 week ago

Description

I am about to write a paper about sustainability of AI for my university. Therefore I wanted to know what Electricity mix (Percentages of Coal, Petroleum, Natural Gas, Solar, ...) your code is guessing and how it gets the values/where are the guessed values from?

Where can I get more current information about the german energy mix/Where did you get it from?

What I Did

I saw in /codecarbon/core/emissions.py that there is a function called _region_energy_mix_to_emissions_rate which only uses coal, petroleum and natural gas. But on your website CodeCarbon there is also mentioned emissions for Solar, Wind, ...

benoit-cty commented 1 week ago

Hello,

The function you mention is only used in the case of an error DataSourceException, which is not supposed to happen anymore.

Our data came from our_world_in_data and you can see them in the file https://github.com/mlco2/codecarbon/blob/master/codecarbon/data/private_infra/global_energy_mix.json

We could also use ElectricityMaps to get the energy mix in realtime.

Let us know when your paper is out !

headscott commented 1 week ago

Is there a way for me to do something like get_regional_energy_mix(ISO_Code, Region) and get the same results that you used to calculate the CO2eq of the power consumption? If so, what should I do?

I tried this code, but it didn't work:

from codecarbon.external.geography import GeoMetadata
from codecarbon.input import DataSourceException
from codecarbon import EmissionsTracker

def get_my_energy_mix():
    # create EmissionTracker Instance
    tracker = EmissionsTracker()

    # define GeoMetadata for your region
    geo = GeoMetadata(
        country_iso_code,
        country_name,
        region,
        latitude,
        longitude
    )

    try:
        country_emissions_data = tracker._data_source.get_country_emissions_data(
            geo.country_iso_code.lower()
        )

        if geo.region not in country_emissions_data:
            # TODO: Deal with missing data, default to something
            raise ValueError(
                f"Region: {geo.region} not found for Country "
                + f" with ISO CODE: {geo.country_iso_code}"
            )

        print("Energy Mix for country:", country_emissions_data)

    except DataSourceException:
        # This country has regional data at the energy mix level,
        # not the emissions level

        try:
            country_energy_mix_data = tracker._data_source.get_global_energy_mix_data()
            if geo.region in country_energy_mix_data:
                region_energy_mix_data = country_energy_mix_data[geo.region]
                print("Energy Mix for region:", region_energy_mix_data)
            else:
                print(f"Energy mix-Data for {geo.region} is missing.")
        except KeyError as error:
            print("Error: Data not available.", error)

My paper will be in german btw

benoit-cty commented 1 week ago

Hello, You can do :

from codecarbon.input import DataSource
DataSource().get_global_energy_mix_data()["DEU"]
{
  "biofuel_TWh": 46.02,
  "carbon_intensity": 380.95,
  "coal_TWh": 135.35,
  "country_name": "Germany",
  "fossil_TWh": 231.48,
  "gas_TWh": 76,
  "hydroelectricity_TWh": 19.48,
  "iso_code": "DEU",
  "low_carbon_TWh": 273.31,
  "nuclear_TWh": 8.75,
  "oil_TWh": 20.13,
  "other_renewable_TWh": 46.23,
  "other_renewable_exc_biofuel_TWh": 0.21,
  "per_capita_Wh": 6060.295,
  "renewables_TWh": 264.56,
  "solar_TWh": 61.56,
  "total_TWh": 504.78999999999996,
  "wind_TWh": 137.29,
  "year": 2023
}

If you what to use realtime data, look at CO2 Signal in CodeCarbon as it was the previous name of ElectricityMaps API.

Even if it's in German it's always nice to see where and why CodeCarbon is used.

headscott commented 1 week ago

Okay thank you, this helped me. But I still have a problem:

this is the total energy consumption of one of my AI training runs: 5.4478812927977245kWh this is the calculated emissions in kgCO2: 2.0995535235500222

if I use the 380.95 carbon intensity, I get: 5.4478812927977245 * 380.95 = 2.07537037849129315kg so its a bit less. I've got version 2.5.0 btw.

And where do these 380.95 come from?

oil 20.13 -> 3.9878% of total Energy coal 135.35 -> 26.8131% gas 76 -> 15.0558% -> total fossil TWh: 231.48 --> 45.8567%

solar 61.56 -> 12.1952% wind 137.29 -> 27.1974% hydro 19.48 -> 3.859% biofuel 46.02 -> 9.1167% -> total renewable 264.56 -> 52.4099% nuclear 8.75 -> 1.7334% total 504.79

CO2eq = 0.268131 995 + 0.039878 816 + 0.150558 743 + 0.03859 26 + 0.017334 29 + 0.121952 48 + 0.271974 * 26 = 425.626433 (I am using the formula from CodeCarbon Methodology). And there is even the value for Geothermal missing.

But even with this value, I get 5.4478812927977245 * 425.626433 = 2.318766kg CO2

If I calculate it backwards, the CO2eq should be: 5,4478812927977245 * CO2eq = 2,0995535235500222 ==> CO2eq = 385.3889

So is it an older energy mix used for that caluclation? Which would it be then, and how can I get the mix (like 10% Coal, 12% Solar, ...)?

UPDATE:

If I run your code, I get:

{ 'biofuel_TWh': 41.51, 'carbon_intensity': 385.389, 'coal_TWh': 178.94, 'country_name': 'Germany', 'fossil_TWh': 280.96, 'gas_TWh': 79.8, 'hydroelectricity_TWh': 17.06, 'iso_code': 'DEU', 'low_carbon_TWh': 279.59, 'nuclear_TWh': 35.86, 'oil_TWh': 22.22, 'other_renewable_TWh': 41.75, 'other_renewable_exc_biofuel_TWh': 0.24, 'per_capita_Wh': 6723.654, 'renewables_TWh': 243.73, 'solar_TWh': 60.01, 'total_TWh': 560.55, 'wind_TWh': 124.91, 'year': 2022 }

and 385.389 should actually be correct for the calculation. But I still don't know how 385.389 is calculated with this energy mix

benoit-cty commented 4 hours ago

'carbon_intensity': 385.389, is not computed, it came directly from Our World in Data, here is what we do to build the dataset : https://github.com/mlco2/codecarbon/blob/master/codecarbon/data/private_infra/our_world_in_data.ipynb

headscott commented 3 hours ago

So, the computation formular on the mentioned website is nowhere used in your code?

benoit-cty commented 3 hours ago

Yes, it was computed before, but now we read directly the carbon_intensity as it is now provided by Our World in Data.

headscott commented 3 hours ago

okay thanks