File size: 9,587 Bytes
197f5ec |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 |
from dataclasses import dataclass
from enum import Enum
import pandas as pd
from ecologits.model_repository import models
from ecologits.impacts.modeling import Impacts, Energy, GWP, ADPe, PE
#from ecologits.tracers.utils import llm_impacts
from pint import UnitRegistry, Quantity
#####################################################################################
### UNITS DEFINITION
#####################################################################################
u = UnitRegistry()
u.define('Wh = watt_hour')
u.define('kWh = kilowatt_hour')
u.define('MWh = megawatt_hour')
u.define('GWh = gigawatt_hour')
u.define('TWh = terawatt_hour')
u.define('gCO2eq = gram')
u.define('kgCO2eq = kilogram')
u.define('tCO2eq = metricton')
u.define('kgSbeq = kilogram')
u.define('kJ = kilojoule')
u.define('MJ = megajoule')
u.define('m = meter')
u.define('km = kilometer')
u.define('s = second')
u.define('min = minute')
u.define('h = hour')
q = u.Quantity
@dataclass
class QImpacts:
energy: Quantity
gwp: Quantity
adpe: Quantity
pe: Quantity
class PhysicalActivity(str, Enum):
RUNNING = "running"
WALKING = "walking"
class EnergyProduction(str, Enum):
NUCLEAR = "nuclear"
WIND = "wind"
COUNTRIES = [
("cook_islands", 38.81, 9_556),
("tonga", 51.15, 104_490),
("comoros", 100, 821_632),
("samoa", 100, 821_632),
]
#####################################################################################
### EQUIVALENT RAW DATA
#####################################################################################
# From https://www.runningtools.com/energyusage.htm
RUNNING_ENERGY_EQ = q("294 kJ / km") # running 1 km at 10 km/h with a weight of 70 kg
WALKING_ENERGY_EQ = q("196 kJ / km") # walking 1 km at 3 km/h with a weight of 70 kg
# From https://selectra.info/energie/actualites/insolite/consommation-vehicules-electriques-france-2040
# and https://www.tesla.com/fr_fr/support/power-consumption
EV_ENERGY_EQ = q("0.17 kWh / km")
# From https://impactco2.fr/outils/comparateur?value=1&comparisons=streamingvideo
STREAMING_GWP_EQ = q("15.6 h / kgCO2eq")
# From https://ourworldindata.org/population-growth
ONE_PERCENT_WORLD_POPULATION = 80_000_000
DAYS_IN_YEAR = 365
# For a 900 MW nuclear plant -> 500 000 MWh / month
# From https://www.edf.fr/groupe-edf/espaces-dedies/jeunes-enseignants/pour-les-jeunes/lenergie-de-a-a-z/produire-de-lelectricite/le-nucleaire-en-chiffres
YEARLY_NUCLEAR_ENERGY_EQ = q("6 TWh")
# For a 2MW wind turbine
# https://www.ecologie.gouv.fr/eolien-terrestre
YEARLY_WIND_ENERGY_EQ = q("4.2 GWh")
# Ireland yearly electricity consumption
# From https://en.wikipedia.org/wiki/List_of_countries_by_electricity_consumption
YEARLY_IRELAND_ELECTRICITY_CONSUMPTION = q("33 TWh")
IRELAND_POPULATION_MILLION = 5
# From https://impactco2.fr/outils/comparateur?value=1&comparisons=&equivalent=avion-pny
AIRPLANE_PARIS_NYC_GWP_EQ = q("177000 kgCO2eq")
def filter_models(provider, list_models):
model = 1
return model
#####################################################################################
### IMPACTS FORMATING
#####################################################################################
def format_energy(energy: Energy) -> Quantity:
val = q(energy.value, energy.unit)
if val < q("1 kWh"):
val = val.to("Wh")
return val
def format_gwp(gwp: GWP) -> Quantity:
val = q(gwp.value, gwp.unit)
if val < q("1 kgCO2eq"):
val = val.to("gCO2eq")
return val
def format_adpe(adpe: ADPe) -> Quantity:
return q(adpe.value, adpe.unit)
def format_pe(pe: PE) -> Quantity:
val = q(pe.value, pe.unit)
if val < q("1 MJ"):
val = val.to("kJ")
return val
def format_impacts(impacts: Impacts) -> QImpacts:
try:
impacts.energy.value = (impacts.energy.value.max + impacts.energy.value.min)/2
impacts.gwp.value = (impacts.gwp.value.max + impacts.gwp.value.min)/2
impacts.adpe.value = (impacts.adpe.value.max + impacts.adpe.value.min)/2
impacts.pe.value = (impacts.pe.value.max + impacts.pe.value.min)/2
return QImpacts(
energy=format_energy(impacts.energy),
gwp=format_gwp(impacts.gwp),
adpe=format_adpe(impacts.adpe),
pe=format_pe(impacts.pe)
), impacts.usage, impacts.embodied
except: #when no range
return QImpacts(
energy=format_energy(impacts.energy),
gwp=format_gwp(impacts.gwp),
adpe=format_adpe(impacts.adpe),
pe=format_pe(impacts.pe)
), impacts.usage, impacts.embodied
def split_impacts_u_e(impacts: Impacts) -> QImpacts:
return impacts.usage, impacts.embodied
def average_range_impacts(RangeValue):
return (RangeValue.max + RangeValue.min)/2
def format_impacts_expert(impacts: Impacts, display_range: bool) -> QImpacts:
if display_range:
return QImpacts(
energy=format_energy(impacts.energy),
gwp=format_gwp(impacts.gwp),
adpe=format_adpe(impacts.adpe),
pe=format_pe(impacts.pe)
), impacts.usage, impacts.embodied
else:
energy = {"value":(impacts.energy.value.max + impacts.energy.value.min)/2, "unit":impacts.energy.unit}
gwp = (impacts.gwp.value.max + impacts.gwp.value.min)/2
adpe = (impacts.adpe.value.max + impacts.adpe.value.min)/2
pe = (impacts.pe.value.max + impacts.pe.value.min)/2
return QImpacts(
energy=format_energy(energy),
gwp=format_gwp(gwp),
adpe=format_adpe(adpe),
pe=format_pe(pe)
), impacts.usage, impacts.embodied
#####################################################################################
### EQUIVALENT FORMATING
#####################################################################################
def format_energy_eq_physical_activity(energy: Quantity) -> tuple[PhysicalActivity, Quantity]:
energy = energy.to("kJ")
running_eq = energy / RUNNING_ENERGY_EQ
if running_eq > q("1 km"):
return PhysicalActivity.RUNNING, running_eq
walking_eq = energy / WALKING_ENERGY_EQ
if walking_eq < q("1 km"):
walking_eq = walking_eq.to("meter")
return PhysicalActivity.WALKING, walking_eq
def format_energy_eq_electric_vehicle(energy: Quantity) -> Quantity:
energy = energy.to("kWh")
ev_eq = energy / EV_ENERGY_EQ
if ev_eq < q("1 km"):
ev_eq = ev_eq.to("meter")
return ev_eq
def format_gwp_eq_streaming(gwp: Quantity) -> Quantity:
gwp = gwp.to("kgCO2eq")
streaming_eq = gwp * STREAMING_GWP_EQ
if streaming_eq < q("1 h"):
streaming_eq = streaming_eq.to("min")
if streaming_eq < q("1 min"):
streaming_eq = streaming_eq.to("s")
return streaming_eq
def format_energy_eq_electricity_production(energy: Quantity) -> tuple[EnergyProduction, Quantity]:
electricity_eq = energy * ONE_PERCENT_WORLD_POPULATION * DAYS_IN_YEAR
electricity_eq = electricity_eq.to("TWh")
if electricity_eq > YEARLY_NUCLEAR_ENERGY_EQ:
return EnergyProduction.NUCLEAR, electricity_eq / YEARLY_NUCLEAR_ENERGY_EQ
electricity_eq = electricity_eq.to("GWh")
return EnergyProduction.WIND, electricity_eq / YEARLY_WIND_ENERGY_EQ
def format_energy_eq_electricity_consumption_ireland(energy: Quantity) -> Quantity:
electricity_eq = energy * ONE_PERCENT_WORLD_POPULATION * DAYS_IN_YEAR
electricity_eq = electricity_eq.to("TWh")
return electricity_eq / YEARLY_IRELAND_ELECTRICITY_CONSUMPTION
def format_gwp_eq_airplane_paris_nyc(gwp: Quantity) -> Quantity:
gwp_eq = gwp * ONE_PERCENT_WORLD_POPULATION * DAYS_IN_YEAR
gwp_eq = gwp_eq.to("kgCO2eq")
return gwp_eq / AIRPLANE_PARIS_NYC_GWP_EQ
#####################################################################################
### MODELS PARAMETERS
#####################################################################################
def model_active_params_fn(provider_name: str, model_name: str, n_param: float):
if model_name == 'CUSTOM':
return n_param
else:
model = models.find_model(provider=provider_name, model_name=model_name)
if model.architecture == 'moe':
try:
return model.architecture.parameters.active.max
except:
try:
return model.architecture.parameters.active
except:
return model.architecture.parameters
elif model.architecture == 'dense':
try: #dense with range
return model.architecture.parameters.max
except: #dense without range
return model.architecture.parameters
def model_total_params_fn(provider_name: str, model_name: str, n_param: float):
if model_name == 'CUSTOM':
return n_param
provider, model_name = model_name.split('/', 1)
model = models.find_model(provider=provider, model_name=model_name)
try: #moe
return model.architecture.parameters.total.max
except:
try: #dense with range
return model.architecture.parameters.max
except: #dense without range
try:
return model.architecture.parameters.total
except:
return model.architecture.parameters |