e-footprint quickstart
This notebook provides an example scenario that you can use to get familiar with the Python API of efootprint: the daily video consumption of all French households on a big streaming platform.
You will get to describe:
- the infrastructure involved (servers with auto-scaling settings, storage and network)
- the user journey involving 2 steps (Streaming, Upload)
- the usage pattern and the device population that executes it (the laptops of all French households)
Import the packages
⚠ If this steps fails, remember to run ipython kernel install --user --name=efootprint-kernel inside your python virtual environement (initializable with poetry install
) to be able to select efootprint-kernel as the jupyter kernel.
Requirement already satisfied: efootprint in /Users/vincentvillet/Library/Caches/pypoetry/virtualenvs/efootprint-DvRIyG39-py3.12/lib/python3.12/site-packages (7.0.0)
Requirement already satisfied: Pint-Pandas<0.7,>=0.6 in /Users/vincentvillet/Library/Caches/pypoetry/virtualenvs/efootprint-DvRIyG39-py3.12/lib/python3.12/site-packages (from efootprint) (0.6)
Requirement already satisfied: matplotlib==3.8 in /Users/vincentvillet/Library/Caches/pypoetry/virtualenvs/efootprint-DvRIyG39-py3.12/lib/python3.12/site-packages (from efootprint) (3.8.0)
Requirement already satisfied: pandas==2.2 in /Users/vincentvillet/Library/Caches/pypoetry/virtualenvs/efootprint-DvRIyG39-py3.12/lib/python3.12/site-packages (from efootprint) (2.2.0)
Requirement already satisfied: pint==0.23 in /Users/vincentvillet/Library/Caches/pypoetry/virtualenvs/efootprint-DvRIyG39-py3.12/lib/python3.12/site-packages (from efootprint) (0.23)
Requirement already satisfied: plotly==5.19 in /Users/vincentvillet/Library/Caches/pypoetry/virtualenvs/efootprint-DvRIyG39-py3.12/lib/python3.12/site-packages (from efootprint) (5.19.0)
Requirement already satisfied: pytz==2024.1 in /Users/vincentvillet/Library/Caches/pypoetry/virtualenvs/efootprint-DvRIyG39-py3.12/lib/python3.12/site-packages (from efootprint) (2024.1)
Requirement already satisfied: pyvis==0.3.2 in /Users/vincentvillet/Library/Caches/pypoetry/virtualenvs/efootprint-DvRIyG39-py3.12/lib/python3.12/site-packages (from efootprint) (0.3.2)
Requirement already satisfied: requests==2.31 in /Users/vincentvillet/Library/Caches/pypoetry/virtualenvs/efootprint-DvRIyG39-py3.12/lib/python3.12/site-packages (from efootprint) (2.31.0)
Requirement already satisfied: contourpy>=1.0.1 in /Users/vincentvillet/Library/Caches/pypoetry/virtualenvs/efootprint-DvRIyG39-py3.12/lib/python3.12/site-packages (from matplotlib==3.8->efootprint) (1.3.0)
Requirement already satisfied: cycler>=0.10 in /Users/vincentvillet/Library/Caches/pypoetry/virtualenvs/efootprint-DvRIyG39-py3.12/lib/python3.12/site-packages (from matplotlib==3.8->efootprint) (0.12.1)
Requirement already satisfied: fonttools>=4.22.0 in /Users/vincentvillet/Library/Caches/pypoetry/virtualenvs/efootprint-DvRIyG39-py3.12/lib/python3.12/site-packages (from matplotlib==3.8->efootprint) (4.54.1)
Requirement already satisfied: kiwisolver>=1.0.1 in /Users/vincentvillet/Library/Caches/pypoetry/virtualenvs/efootprint-DvRIyG39-py3.12/lib/python3.12/site-packages (from matplotlib==3.8->efootprint) (1.4.7)
Requirement already satisfied: numpy<2,>=1.21 in /Users/vincentvillet/Library/Caches/pypoetry/virtualenvs/efootprint-DvRIyG39-py3.12/lib/python3.12/site-packages (from matplotlib==3.8->efootprint) (1.26.4)
Requirement already satisfied: packaging>=20.0 in /Users/vincentvillet/Library/Caches/pypoetry/virtualenvs/efootprint-DvRIyG39-py3.12/lib/python3.12/site-packages (from matplotlib==3.8->efootprint) (24.1)
Requirement already satisfied: pillow>=6.2.0 in /Users/vincentvillet/Library/Caches/pypoetry/virtualenvs/efootprint-DvRIyG39-py3.12/lib/python3.12/site-packages (from matplotlib==3.8->efootprint) (11.0.0)
Requirement already satisfied: pyparsing>=2.3.1 in /Users/vincentvillet/Library/Caches/pypoetry/virtualenvs/efootprint-DvRIyG39-py3.12/lib/python3.12/site-packages (from matplotlib==3.8->efootprint) (3.2.0)
Requirement already satisfied: python-dateutil>=2.7 in /Users/vincentvillet/Library/Caches/pypoetry/virtualenvs/efootprint-DvRIyG39-py3.12/lib/python3.12/site-packages (from matplotlib==3.8->efootprint) (2.9.0.post0)
Requirement already satisfied: tzdata>=2022.7 in /Users/vincentvillet/Library/Caches/pypoetry/virtualenvs/efootprint-DvRIyG39-py3.12/lib/python3.12/site-packages (from pandas==2.2->efootprint) (2024.2)
Requirement already satisfied: typing-extensions in /Users/vincentvillet/Library/Caches/pypoetry/virtualenvs/efootprint-DvRIyG39-py3.12/lib/python3.12/site-packages (from pint==0.23->efootprint) (4.12.2)
Requirement already satisfied: tenacity>=6.2.0 in /Users/vincentvillet/Library/Caches/pypoetry/virtualenvs/efootprint-DvRIyG39-py3.12/lib/python3.12/site-packages (from plotly==5.19->efootprint) (9.0.0)
Requirement already satisfied: ipython>=5.3.0 in /Users/vincentvillet/Library/Caches/pypoetry/virtualenvs/efootprint-DvRIyG39-py3.12/lib/python3.12/site-packages (from pyvis==0.3.2->efootprint) (8.18.1)
Requirement already satisfied: jinja2>=2.9.6 in /Users/vincentvillet/Library/Caches/pypoetry/virtualenvs/efootprint-DvRIyG39-py3.12/lib/python3.12/site-packages (from pyvis==0.3.2->efootprint) (3.1.4)
Requirement already satisfied: jsonpickle>=1.4.1 in /Users/vincentvillet/Library/Caches/pypoetry/virtualenvs/efootprint-DvRIyG39-py3.12/lib/python3.12/site-packages (from pyvis==0.3.2->efootprint) (3.3.0)
Requirement already satisfied: networkx>=1.11 in /Users/vincentvillet/Library/Caches/pypoetry/virtualenvs/efootprint-DvRIyG39-py3.12/lib/python3.12/site-packages (from pyvis==0.3.2->efootprint) (3.2.1)
Requirement already satisfied: charset-normalizer<4,>=2 in /Users/vincentvillet/Library/Caches/pypoetry/virtualenvs/efootprint-DvRIyG39-py3.12/lib/python3.12/site-packages (from requests==2.31->efootprint) (3.4.0)
Requirement already satisfied: idna<4,>=2.5 in /Users/vincentvillet/Library/Caches/pypoetry/virtualenvs/efootprint-DvRIyG39-py3.12/lib/python3.12/site-packages (from requests==2.31->efootprint) (3.10)
Requirement already satisfied: urllib3<3,>=1.21.1 in /Users/vincentvillet/Library/Caches/pypoetry/virtualenvs/efootprint-DvRIyG39-py3.12/lib/python3.12/site-packages (from requests==2.31->efootprint) (2.2.3)
Requirement already satisfied: certifi>=2017.4.17 in /Users/vincentvillet/Library/Caches/pypoetry/virtualenvs/efootprint-DvRIyG39-py3.12/lib/python3.12/site-packages (from requests==2.31->efootprint) (2024.8.30)
Requirement already satisfied: decorator in /Users/vincentvillet/Library/Caches/pypoetry/virtualenvs/efootprint-DvRIyG39-py3.12/lib/python3.12/site-packages (from ipython>=5.3.0->pyvis==0.3.2->efootprint) (5.1.1)
Requirement already satisfied: jedi>=0.16 in /Users/vincentvillet/Library/Caches/pypoetry/virtualenvs/efootprint-DvRIyG39-py3.12/lib/python3.12/site-packages (from ipython>=5.3.0->pyvis==0.3.2->efootprint) (0.19.1)
Requirement already satisfied: matplotlib-inline in /Users/vincentvillet/Library/Caches/pypoetry/virtualenvs/efootprint-DvRIyG39-py3.12/lib/python3.12/site-packages (from ipython>=5.3.0->pyvis==0.3.2->efootprint) (0.1.7)
Requirement already satisfied: prompt-toolkit<3.1.0,>=3.0.41 in /Users/vincentvillet/Library/Caches/pypoetry/virtualenvs/efootprint-DvRIyG39-py3.12/lib/python3.12/site-packages (from ipython>=5.3.0->pyvis==0.3.2->efootprint) (3.0.48)
Requirement already satisfied: pygments>=2.4.0 in /Users/vincentvillet/Library/Caches/pypoetry/virtualenvs/efootprint-DvRIyG39-py3.12/lib/python3.12/site-packages (from ipython>=5.3.0->pyvis==0.3.2->efootprint) (2.18.0)
Requirement already satisfied: stack-data in /Users/vincentvillet/Library/Caches/pypoetry/virtualenvs/efootprint-DvRIyG39-py3.12/lib/python3.12/site-packages (from ipython>=5.3.0->pyvis==0.3.2->efootprint) (0.6.3)
Requirement already satisfied: traitlets>=5 in /Users/vincentvillet/Library/Caches/pypoetry/virtualenvs/efootprint-DvRIyG39-py3.12/lib/python3.12/site-packages (from ipython>=5.3.0->pyvis==0.3.2->efootprint) (5.14.3)
Requirement already satisfied: pexpect>4.3 in /Users/vincentvillet/Library/Caches/pypoetry/virtualenvs/efootprint-DvRIyG39-py3.12/lib/python3.12/site-packages (from ipython>=5.3.0->pyvis==0.3.2->efootprint) (4.9.0)
Requirement already satisfied: MarkupSafe>=2.0 in /Users/vincentvillet/Library/Caches/pypoetry/virtualenvs/efootprint-DvRIyG39-py3.12/lib/python3.12/site-packages (from jinja2>=2.9.6->pyvis==0.3.2->efootprint) (3.0.2)
Requirement already satisfied: six>=1.5 in /Users/vincentvillet/Library/Caches/pypoetry/virtualenvs/efootprint-DvRIyG39-py3.12/lib/python3.12/site-packages (from python-dateutil>=2.7->matplotlib==3.8->efootprint) (1.16.0)
Requirement already satisfied: parso<0.9.0,>=0.8.3 in /Users/vincentvillet/Library/Caches/pypoetry/virtualenvs/efootprint-DvRIyG39-py3.12/lib/python3.12/site-packages (from jedi>=0.16->ipython>=5.3.0->pyvis==0.3.2->efootprint) (0.8.4)
Requirement already satisfied: ptyprocess>=0.5 in /Users/vincentvillet/Library/Caches/pypoetry/virtualenvs/efootprint-DvRIyG39-py3.12/lib/python3.12/site-packages (from pexpect>4.3->ipython>=5.3.0->pyvis==0.3.2->efootprint) (0.7.0)
Requirement already satisfied: wcwidth in /Users/vincentvillet/Library/Caches/pypoetry/virtualenvs/efootprint-DvRIyG39-py3.12/lib/python3.12/site-packages (from prompt-toolkit<3.1.0,>=3.0.41->ipython>=5.3.0->pyvis==0.3.2->efootprint) (0.2.13)
Requirement already satisfied: executing>=1.2.0 in /Users/vincentvillet/Library/Caches/pypoetry/virtualenvs/efootprint-DvRIyG39-py3.12/lib/python3.12/site-packages (from stack-data->ipython>=5.3.0->pyvis==0.3.2->efootprint) (2.1.0)
Requirement already satisfied: asttokens>=2.1.0 in /Users/vincentvillet/Library/Caches/pypoetry/virtualenvs/efootprint-DvRIyG39-py3.12/lib/python3.12/site-packages (from stack-data->ipython>=5.3.0->pyvis==0.3.2->efootprint) (2.4.1)
Requirement already satisfied: pure-eval in /Users/vincentvillet/Library/Caches/pypoetry/virtualenvs/efootprint-DvRIyG39-py3.12/lib/python3.12/site-packages (from stack-data->ipython>=5.3.0->pyvis==0.3.2->efootprint) (0.2.3)
[1m[[0m[34;49mnotice[0m[1;39;49m][0m[39;49m A new release of pip is available: [0m[31;49m24.0[0m[39;49m -> [0m[32;49m24.3.1[0m
[1m[[0m[34;49mnotice[0m[1;39;49m][0m[39;49m To update, run: [0m[32;49mpip install --upgrade pip[0m
import os
from efootprint.abstract_modeling_classes.source_objects import SourceValue, Sources, SourceObject
from efootprint.abstract_modeling_classes.explainable_objects import EmptyExplainableObject
from efootprint.builders.hardware.storage_defaults import default_ssd
from efootprint.core.usage.user_journey import UserJourney
from efootprint.core.usage.user_journey_step import UserJourneyStep
from efootprint.core.usage.job import Job
from efootprint.core.hardware.servers.autoscaling import Autoscaling
from efootprint.core.hardware.storage import Storage
from efootprint.core.usage.usage_pattern import UsagePattern
from efootprint.core.hardware.network import Network
from efootprint.core.system import System
from efootprint.constants.countries import Countries
from efootprint.constants.units import u
from efootprint.utils.object_relationships_graphs import USAGE_PATTERN_VIEW_CLASSES_TO_IGNORE
from efootprint.builders.hardware.devices_defaults import default_laptop
Define the infrastructure
An e-footprint object has a name and attributes describing its technical and environmental characteristics:
storage = Storage(
"SSD storage",
carbon_footprint_fabrication=SourceValue(160 * u.kg, Sources.STORAGE_EMBODIED_CARBON_STUDY),
power=SourceValue(1.3 * u.W, Sources.STORAGE_EMBODIED_CARBON_STUDY),
lifespan=SourceValue(6 * u.years, Sources.HYPOTHESIS),
idle_power=SourceValue(0 * u.W, Sources.HYPOTHESIS),
storage_capacity=SourceValue(1 * u.TB, Sources.STORAGE_EMBODIED_CARBON_STUDY),
data_replication_factor=SourceValue(3 * u.dimensionless, Sources.HYPOTHESIS),
data_storage_duration = SourceValue(2 * u.year, Sources.HYPOTHESIS),
base_storage_need = SourceValue(100 * u.TB, Sources.HYPOTHESIS),
fixed_nb_of_instances = EmptyExplainableObject()
)
Moreover, all e-footprint objects have a calculated_attributes attributes that shows the list of attributes that are setup as None and then computed by e-footprint when the modeling is over. For example, for our storage:
Storage id-7d68e3-SSD-storage
carbon_footprint_fabrication: 160 kilogram
power: 1.3 watt
lifespan: 6 year
fraction_of_usage_time: 1 dimensionless
idle_power: 0 watt
storage_capacity: 1 terabyte
data_replication_factor: 3 dimensionless
data_storage_duration: 2 year
base_storage_need: 100 terabyte
fixed_nb_of_instances: no value
calculated_attributes:
storage_delta: None
full_cumulative_storage_need: None
raw_nb_of_instances: None
nb_of_instances: None
nb_of_active_instances: None
instances_fabrication_footprint: None
instances_energy: None
energy_footprint: None
Apart from environmental and technical attributes, e-footprint objects can link to other e-footprint objects. For example, Storage and Server objects can be linked to each other. A server can stored data on a storage device, and a storage device can be used by a server.
server = Autoscaling(
"server",
carbon_footprint_fabrication=SourceValue(600 * u.kg, Sources.BASE_ADEME_V19),
power=SourceValue(300 * u.W, Sources.HYPOTHESIS),
lifespan=SourceValue(6 * u.year, Sources.HYPOTHESIS),
idle_power=SourceValue(50 * u.W, Sources.HYPOTHESIS),
ram=SourceValue(128 * u.GB, Sources.HYPOTHESIS),
cpu_cores=SourceValue(24 * u.core, Sources.HYPOTHESIS),
power_usage_effectiveness=SourceValue(1.2 * u.dimensionless, Sources.HYPOTHESIS),
average_carbon_intensity=SourceValue(100 * u.g / u.kWh, Sources.HYPOTHESIS),
server_utilization_rate=SourceValue(0.9 * u.dimensionless, Sources.HYPOTHESIS),
base_ram_consumption=SourceValue(300 * u.MB, Sources.HYPOTHESIS),
base_cpu_consumption=SourceValue(2 * u.core, Sources.HYPOTHESIS),
storage=storage
)
More information on e-footprint objects’ calculated_attributes can be found in the e-footprint documentation.
Define the user journey
This is the modeling of the average daily usage of the streaming platform in France:
streaming_step = UserJourneyStep(
"20 min streaming",
user_time_spent=SourceValue(20 * u.min, Sources.USER_DATA),
jobs=[
Job(
"streaming",
server=server,
data_upload=SourceValue(0.05 * u.MB, Sources.USER_DATA),
data_download=SourceValue(800 * u.MB, Sources.USER_DATA),
data_stored=SourceValue(0.05 * u.MB, Sources.USER_DATA),
request_duration=SourceValue(4 * u.min, Sources.HYPOTHESIS),
cpu_needed=SourceValue(1 * u.core, Sources.HYPOTHESIS),
ram_needed=SourceValue(50 * u.MB, Sources.HYPOTHESIS)
)
]
)
upload_step = UserJourneyStep(
"1 min video capture then upload",
user_time_spent=SourceValue(70 * u.s, Sources.USER_DATA),
jobs=[
Job(
"video upload",
server=server,
data_upload=SourceValue(20 * u.MB, Sources.USER_DATA),
data_download=SourceValue(0 * u.GB, Sources.USER_DATA),
data_stored=SourceValue(20 * u.MB, Sources.USER_DATA),
request_duration=SourceValue(2 * u.s, Sources.HYPOTHESIS),
cpu_needed=SourceValue(1 * u.core, Sources.HYPOTHESIS),
ram_needed=SourceValue(50 * u.MB, Sources.HYPOTHESIS)
)
]
)
The user journey is then simply a list of user journey steps:
user_journey = UserJourney("Mean video consumption user journey", uj_steps=[streaming_step, upload_step])
Describe usage
An e-footprint usage pattern links a user journey to devices that run it, a network, a country, and the number of times the user journey gets executed hour by hour.
# Let’s build synthetic usage data by summing a linear growth with a sinusoidal fluctuation components, then adding daily variation
from datetime import datetime, timedelta
from efootprint.builders.time_builders import linear_growth_hourly_values
start_date = datetime.strptime("2025-01-01", "%Y-%m-%d")
timespan = 3 * u.year
linear_growth = linear_growth_hourly_values(timespan, start_value=5000, end_value=100000, start_date=start_date)
linear_growth.set_label("Hourly user journeys linear growth component")
linear_growth.plot()
from efootprint.builders.time_builders import sinusoidal_fluct_hourly_values
sinusoidal_fluct = sinusoidal_fluct_hourly_values(
timespan, sin_fluct_amplitude=3000, sin_fluct_period_in_hours=3 * 30 * 24, start_date=start_date)
lin_growth_plus_sin_fluct = (linear_growth + sinusoidal_fluct).set_label("Hourly user journeys linear growth with sinusoidal fluctuations")
lin_growth_plus_sin_fluct.plot()
# Let’s add daily variations because people use the system less at night
from efootprint.builders.time_builders import daily_fluct_hourly_values
daily_fluct = daily_fluct_hourly_values(timespan, fluct_scale=0.8, hour_of_day_for_min_value=4, start_date=start_date)
daily_fluct.set_label("Daily volume fluctuation")
daily_fluct.plot(xlims=[start_date, start_date+timedelta(days=1)])
hourly_user_journey_starts = lin_growth_plus_sin_fluct * daily_fluct
hourly_user_journey_starts.set_label("Hourly number of user journey started")
hourly_user_journey_starts.plot(xlims=[start_date, start_date + timedelta(days=7)])
# Over 3 years the daily fluctuation color the area between daily min and max number of hourly user journeys
hourly_user_journey_starts.plot()
network = Network(
"WIFI network",
bandwidth_energy_intensity=SourceValue(0.05 * u("kWh/GB"), Sources.TRAFICOM_STUDY))
usage_pattern = UsagePattern(
"Daily video streaming consumption",
user_journey=user_journey,
devices=[default_laptop()],
network=network,
country=Countries.FRANCE(),
hourly_user_journey_starts=hourly_user_journey_starts
)
system = System("System", usage_patterns=[usage_pattern])
2024-11-12 10:23:59,966 - INFO - Computing calculated attributes for System System
2024-11-12 10:23:59,967 - INFO - Computing calculated attributes for UserJourney Mean video consumption user journey
2024-11-12 10:23:59,968 - INFO - Computing calculated attributes for UsagePattern Daily video streaming consumption
2024-11-12 10:23:59,982 - INFO - Computing calculated attributes for Job streaming
2024-11-12 10:23:59,991 - INFO - Computing calculated attributes for Job video upload
2024-11-12 10:24:00,001 - INFO - Computing calculated attributes for Autoscaling server
2024-11-12 10:24:00,027 - INFO - Computing calculated attributes for Network WIFI network
2024-11-12 10:24:00,040 - INFO - Computing calculated attributes for Storage SSD storage
2024-11-12 10:24:00,106 - INFO - Finished computing System modeling
Results
Computed attributes
Now all calculated_attributes have been computed:
Autoscaling id-1b326a-server
carbon_footprint_fabrication: 600 kilogram
power: 300 watt
lifespan: 6 year
fraction_of_usage_time: 1 dimensionless
server_utilization_rate: 0.9 dimensionless
idle_power: 50 watt
ram: 128 gigabyte
cpu_cores: 24 core
power_usage_effectiveness: 1.2 dimensionless
average_carbon_intensity: 100.0 gram / kilowatt_hour
base_ram_consumption: 300 megabyte
base_cpu_consumption: 2 core
storage: id-7d68e3-SSD-storage
calculated_attributes:
hour_by_hour_cpu_need: 26298 values from 2024-12-31 23:00:00 to 2028-01-01 16:00:00 in core:
first 10 vals [201.67, 146.34, 103.76, 76.95, 67.89, 77.33, 104.78, 148.5, 205.65, 272.44],
last 10 vals [4138.19, 5469.34, 6898.03, 8326.93, 9658.7, 10802.58, 11680.63, 12233.0, 12422.03, 12234.82]
hour_by_hour_ram_need: 26298 values from 2024-12-31 23:00:00 to 2028-01-01 16:00:00 in GB:
first 10 vals [10.08, 7.32, 5.19, 3.85, 3.39, 3.87, 5.24, 7.42, 10.28, 13.62],
last 10 vals [206.91, 273.47, 344.9, 416.35, 482.93, 540.13, 584.03, 611.65, 621.1, 611.74]
available_ram_per_instance: 114.9 gigabyte
available_cpu_per_instance: 19.6 core
raw_nb_of_instances: 26298 values from 2024-12-31 23:00:00 to 2028-01-01 16:00:00 in dimensionless:
first 10 vals [10.29, 7.47, 5.29, 3.93, 3.46, 3.95, 5.35, 7.58, 10.49, 13.9],
last 10 vals [211.13, 279.05, 351.94, 424.84, 492.79, 551.15, 595.95, 624.13, 633.78, 624.23]
nb_of_instances: 26298 values from 2024-12-31 23:00:00 to 2028-01-01 16:00:00 in dimensionless:
first 10 vals [11.0, 8.0, 6.0, 4.0, 4.0, 4.0, 6.0, 8.0, 11.0, 14.0],
last 10 vals [212.0, 280.0, 352.0, 425.0, 493.0, 552.0, 596.0, 625.0, 634.0, 625.0]
instances_fabrication_footprint: 26298 values from 2024-12-31 23:00:00 to 2028-01-01 16:00:00 in kg:
first 10 vals [0.13, 0.09, 0.07, 0.05, 0.05, 0.05, 0.07, 0.09, 0.13, 0.16],
last 10 vals [2.42, 3.19, 4.02, 4.85, 5.62, 6.3, 6.8, 7.13, 7.23, 7.13]
instances_energy: 26298 values from 2024-12-31 23:00:00 to 2028-01-01 16:00:00 in kWh:
first 10 vals [3.75, 2.72, 1.95, 1.42, 1.28, 1.42, 1.96, 2.75, 3.81, 5.01],
last 10 vals [76.06, 100.51, 126.7, 152.95, 177.42, 198.47, 214.55, 224.74, 228.17, 224.77]
energy_footprint: 26298 values from 2024-12-31 23:00:00 to 2028-01-01 16:00:00 in kg:
first 10 vals [0.37, 0.27, 0.19, 0.14, 0.13, 0.14, 0.2, 0.28, 0.38, 0.5],
last 10 vals [7.61, 10.05, 12.67, 15.3, 17.74, 19.85, 21.45, 22.47, 22.82, 22.48]
System footprint overview
Object relationships graph
Hover over a node to get the numerical values of its environmental and technical attributes. For simplifying the graph the Network and Hardware nodes are not shown.
usage_pattern.object_relationship_graph_to_file("object_relationships_graph.html", width="800px", height="500px",
classes_to_ignore=USAGE_PATTERN_VIEW_CLASSES_TO_IGNORE, notebook=True)
Calculus graph
Any e-footprint calculation can generate its calculation graph for full auditability. Hover on a calculus node to display its formula and numeric value.
usage_pattern.devices_fabrication_footprint.calculus_graph_to_file(
"device_population_fab_footprint_calculus_graph.html", width="800px", height="500px", notebook=True)
Analysing the impact of a change
Numeric input change
Any input change automatically triggers the computation of calculations that depend on the input. For example, let’s say that the average data download consumption of the streaming step decreased because of a change in default video quality:
Plotting the impact of streaming’s data_download changing from 800 megabyte to 500 megabyte
System structure change
Now let’s make a more complex change, like adding a conversation with a generative AI chatbot before streaming the video. Numerical values don’t matter so much for the sake of this tutorial, please check out the e-footprint-modelings github repository for a more detailed modeling of the impact of LLM training and inference.
llm_server = Autoscaling(
"Inference GPU server",
carbon_footprint_fabrication=SourceValue(4900 * u.kg, Sources.HYPOTHESIS),
power=SourceValue(6400 * u.W, Sources.HYPOTHESIS),
lifespan=SourceValue(5 * u.year, Sources.HYPOTHESIS),
idle_power=SourceValue(500 * u.W, Sources.HYPOTHESIS),
ram=SourceValue(128 * u.GB, Sources.HYPOTHESIS),
cpu_cores=SourceValue(16 * u.core, Sources.HYPOTHESIS), # Used to represent GPUs because e-footprint doesn’t natively model GPU resources yet.
power_usage_effectiveness=SourceValue(1.2 * u.dimensionless, Sources.HYPOTHESIS),
average_carbon_intensity=SourceValue(300 * u.g / u.kWh, Sources.HYPOTHESIS),
server_utilization_rate=SourceValue(1 * u.dimensionless, Sources.HYPOTHESIS),
base_ram_consumption=SourceValue(0 * u.MB, Sources.HYPOTHESIS),
base_cpu_consumption=SourceValue(0 * u.core, Sources.HYPOTHESIS),
storage=default_ssd()
)
llm_chat_step = UserJourneyStep(
"Chat with LLM to select video", user_time_spent=SourceValue(1 * u.min, Sources.HYPOTHESIS),
jobs=[Job("LLM API call", llm_server, SourceValue(300 * u.kB, Sources.USER_DATA),
SourceValue(300 * u.kB, Sources.USER_DATA), SourceValue(300 * u.kB, Sources.USER_DATA),
request_duration=SourceValue(5 * u.s, Sources.HYPOTHESIS),
cpu_needed=SourceValue(16 * u.core, Sources.HYPOTHESIS),
ram_needed=SourceValue(128 * u.GB, Sources.HYPOTHESIS))])
# Adding the new step is simply an attribute update.
# Don’t use user_journey.uj_steps.append(llm_chat_step) as e-footprint recomputation logic wouldn’t be triggered
user_journey.uj_steps += [llm_chat_step]
2024-11-12 10:24:02,746 - INFO - Computing calculated attributes for UserJourney Mean video consumption user journey
2024-11-12 10:24:02,747 - INFO - Computing calculated attributes for UsagePattern Daily video streaming consumption
2024-11-12 10:24:02,760 - INFO - Computing calculated attributes for Job streaming
2024-11-12 10:24:02,769 - INFO - Computing calculated attributes for Job video upload
2024-11-12 10:24:02,780 - INFO - Computing calculated attributes for Job LLM API call
2024-11-12 10:24:02,790 - INFO - Computing calculated attributes for Autoscaling server
2024-11-12 10:24:02,815 - INFO - Computing calculated attributes for Network WIFI network
2024-11-12 10:24:02,826 - INFO - Computing calculated attributes for Autoscaling Inference GPU server
2024-11-12 10:24:02,846 - INFO - Computing calculated attributes for Storage SSD storage
2024-11-12 10:24:02,913 - INFO - Computing calculated attributes for Storage Default SSD storage
Plotting the impact of Mean video consumption user journey’s uj_steps changing from ['20 min streaming', '1 min video capture then upload'] to ['20 min streaming', '1 min video capture then upload', 'Chat with LLM to select video']
We can see that server energy footprint has been multiplied by more than 10 and the rest of the impact is quite negligible. Good to know to make informed decisions ! Of course the impact is very much dependent on assumptions. If the LLM server ran on low-carbon electricity for example:
llm_server.average_carbon_intensity=SourceValue(50 * u.g / u.kWh, Sources.HYPOTHESIS)
system.plot_emission_diffs("lower LLM inference carbon intensity.png")
Plotting the impact of Inference GPU server’s average_carbon_intensity changing from 300.0 gram / kilowatt_hour to 50.0 gram / kilowatt_hour
Recap of all System changes
Plotting the impact of:
- streaming’s data_download changing from 800 megabyte to 500 megabyte
- Mean video consumption user journey’s uj_steps changing from ['20 min streaming', '1 min video capture then upload'] to ['20 min streaming', '1 min video capture then upload', 'Chat with LLM to select video']
- Inference GPU server’s average_carbon_intensity changing from 300.0 gram / kilowatt_hour to 50.0 gram / kilowatt_hour