feat : massive update (streamlit migration, integration of ecologits 0.6.1, dataviz, ...)
Browse filesThis view is limited to 50 files because it contains too many changes.
See raw diff
- .gitattributes +35 -35
- .gitignore +1 -303
- .python-version +1 -0
- LICENSE +0 -427
- Makefile +0 -6
- README.md +3 -31
- __init__.py +8 -0
- __pycache__/__init__.cpython-312.pyc +0 -0
- __pycache__/calculator.cpython-312.pyc +0 -0
- __pycache__/constants.cpython-312.pyc +0 -0
- __pycache__/content.cpython-312.pyc +0 -0
- __pycache__/electricity_mix.cpython-312.pyc +0 -0
- __pycache__/expert.cpython-312.pyc +0 -0
- __pycache__/impacts.cpython-312.pyc +0 -0
- __pycache__/models.cpython-312.pyc +0 -0
- __pycache__/utils.cpython-312.pyc +0 -0
- app.py +46 -539
- calculator.py +67 -0
- constants.py +106 -0
- content.py +232 -0
- {src → data}/electricity_mix.csv +3 -3
- electricity_mix.py +175 -0
- expert.py +156 -0
- impacts.py +116 -0
- models.py +46 -0
- pyproject.toml +12 -0
- requirements-dev.txt +0 -6
- requirements.txt +3 -4
- src/__init__.py +8 -0
- src/__pycache__/__init__.cpython-312.pyc +0 -0
- src/__pycache__/calculator.cpython-312.pyc +0 -0
- src/__pycache__/constants.cpython-312.pyc +0 -0
- src/__pycache__/content.cpython-312.pyc +0 -0
- src/__pycache__/electricity_mix.cpython-312.pyc +0 -0
- src/__pycache__/expert.cpython-312.pyc +0 -0
- src/__pycache__/impacts.cpython-312.pyc +0 -0
- src/__pycache__/models.cpython-312.pyc +0 -0
- src/__pycache__/utils.cpython-312.pyc +0 -0
- src/assets.py +0 -17
- src/calculator.py +67 -0
- src/constants.py +106 -103
- src/content.py +232 -286
- src/data/electricity_mix.csv +4 -0
- src/electricity_mix.py +175 -155
- src/expert.py +156 -0
- src/impacts.py +116 -0
- src/models.py +46 -0
- src/scrapper.py +0 -33
- src/utils.py +262 -197
- utils.py +262 -0
.gitattributes
CHANGED
@@ -1,35 +1,35 @@
|
|
1 |
-
*.7z filter=lfs diff=lfs merge=lfs -text
|
2 |
-
*.arrow filter=lfs diff=lfs merge=lfs -text
|
3 |
-
*.bin filter=lfs diff=lfs merge=lfs -text
|
4 |
-
*.bz2 filter=lfs diff=lfs merge=lfs -text
|
5 |
-
*.ckpt filter=lfs diff=lfs merge=lfs -text
|
6 |
-
*.ftz filter=lfs diff=lfs merge=lfs -text
|
7 |
-
*.gz filter=lfs diff=lfs merge=lfs -text
|
8 |
-
*.h5 filter=lfs diff=lfs merge=lfs -text
|
9 |
-
*.joblib filter=lfs diff=lfs merge=lfs -text
|
10 |
-
*.lfs.* filter=lfs diff=lfs merge=lfs -text
|
11 |
-
*.mlmodel filter=lfs diff=lfs merge=lfs -text
|
12 |
-
*.model filter=lfs diff=lfs merge=lfs -text
|
13 |
-
*.msgpack filter=lfs diff=lfs merge=lfs -text
|
14 |
-
*.npy filter=lfs diff=lfs merge=lfs -text
|
15 |
-
*.npz filter=lfs diff=lfs merge=lfs -text
|
16 |
-
*.onnx filter=lfs diff=lfs merge=lfs -text
|
17 |
-
*.ot filter=lfs diff=lfs merge=lfs -text
|
18 |
-
*.parquet filter=lfs diff=lfs merge=lfs -text
|
19 |
-
*.pb filter=lfs diff=lfs merge=lfs -text
|
20 |
-
*.pickle filter=lfs diff=lfs merge=lfs -text
|
21 |
-
*.pkl filter=lfs diff=lfs merge=lfs -text
|
22 |
-
*.pt filter=lfs diff=lfs merge=lfs -text
|
23 |
-
*.pth filter=lfs diff=lfs merge=lfs -text
|
24 |
-
*.rar filter=lfs diff=lfs merge=lfs -text
|
25 |
-
*.safetensors filter=lfs diff=lfs merge=lfs -text
|
26 |
-
saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
27 |
-
*.tar.* filter=lfs diff=lfs merge=lfs -text
|
28 |
-
*.tar filter=lfs diff=lfs merge=lfs -text
|
29 |
-
*.tflite filter=lfs diff=lfs merge=lfs -text
|
30 |
-
*.tgz filter=lfs diff=lfs merge=lfs -text
|
31 |
-
*.wasm filter=lfs diff=lfs merge=lfs -text
|
32 |
-
*.xz filter=lfs diff=lfs merge=lfs -text
|
33 |
-
*.zip filter=lfs diff=lfs merge=lfs -text
|
34 |
-
*.zst filter=lfs diff=lfs merge=lfs -text
|
35 |
-
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
|
|
1 |
+
*.7z filter=lfs diff=lfs merge=lfs -text
|
2 |
+
*.arrow filter=lfs diff=lfs merge=lfs -text
|
3 |
+
*.bin filter=lfs diff=lfs merge=lfs -text
|
4 |
+
*.bz2 filter=lfs diff=lfs merge=lfs -text
|
5 |
+
*.ckpt filter=lfs diff=lfs merge=lfs -text
|
6 |
+
*.ftz filter=lfs diff=lfs merge=lfs -text
|
7 |
+
*.gz filter=lfs diff=lfs merge=lfs -text
|
8 |
+
*.h5 filter=lfs diff=lfs merge=lfs -text
|
9 |
+
*.joblib filter=lfs diff=lfs merge=lfs -text
|
10 |
+
*.lfs.* filter=lfs diff=lfs merge=lfs -text
|
11 |
+
*.mlmodel filter=lfs diff=lfs merge=lfs -text
|
12 |
+
*.model filter=lfs diff=lfs merge=lfs -text
|
13 |
+
*.msgpack filter=lfs diff=lfs merge=lfs -text
|
14 |
+
*.npy filter=lfs diff=lfs merge=lfs -text
|
15 |
+
*.npz filter=lfs diff=lfs merge=lfs -text
|
16 |
+
*.onnx filter=lfs diff=lfs merge=lfs -text
|
17 |
+
*.ot filter=lfs diff=lfs merge=lfs -text
|
18 |
+
*.parquet filter=lfs diff=lfs merge=lfs -text
|
19 |
+
*.pb filter=lfs diff=lfs merge=lfs -text
|
20 |
+
*.pickle filter=lfs diff=lfs merge=lfs -text
|
21 |
+
*.pkl filter=lfs diff=lfs merge=lfs -text
|
22 |
+
*.pt filter=lfs diff=lfs merge=lfs -text
|
23 |
+
*.pth filter=lfs diff=lfs merge=lfs -text
|
24 |
+
*.rar filter=lfs diff=lfs merge=lfs -text
|
25 |
+
*.safetensors filter=lfs diff=lfs merge=lfs -text
|
26 |
+
saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
27 |
+
*.tar.* filter=lfs diff=lfs merge=lfs -text
|
28 |
+
*.tar filter=lfs diff=lfs merge=lfs -text
|
29 |
+
*.tflite filter=lfs diff=lfs merge=lfs -text
|
30 |
+
*.tgz filter=lfs diff=lfs merge=lfs -text
|
31 |
+
*.wasm filter=lfs diff=lfs merge=lfs -text
|
32 |
+
*.xz filter=lfs diff=lfs merge=lfs -text
|
33 |
+
*.zip filter=lfs diff=lfs merge=lfs -text
|
34 |
+
*.zst filter=lfs diff=lfs merge=lfs -text
|
35 |
+
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
.gitignore
CHANGED
@@ -1,303 +1 @@
|
|
1 |
-
|
2 |
-
.vscode/
|
3 |
-
|
4 |
-
### JetBrains template
|
5 |
-
.idea/
|
6 |
-
|
7 |
-
### Linux template
|
8 |
-
*~
|
9 |
-
|
10 |
-
# temporary files which can be created if a process still has a handle open of a deleted file
|
11 |
-
.fuse_hidden*
|
12 |
-
|
13 |
-
# KDE directory preferences
|
14 |
-
.directory
|
15 |
-
|
16 |
-
# Linux trash folder which might appear on any partition or disk
|
17 |
-
.Trash-*
|
18 |
-
|
19 |
-
# .nfs files are created when an open file is removed but is still being accessed
|
20 |
-
.nfs*
|
21 |
-
|
22 |
-
### Windows template
|
23 |
-
# Windows thumbnail cache files
|
24 |
-
Thumbs.db
|
25 |
-
Thumbs.db:encryptable
|
26 |
-
ehthumbs.db
|
27 |
-
ehthumbs_vista.db
|
28 |
-
|
29 |
-
# Dump file
|
30 |
-
*.stackdump
|
31 |
-
|
32 |
-
# Folder config file
|
33 |
-
[Dd]esktop.ini
|
34 |
-
|
35 |
-
# Recycle Bin used on file shares
|
36 |
-
$RECYCLE.BIN/
|
37 |
-
|
38 |
-
# Windows Installer files
|
39 |
-
*.cab
|
40 |
-
*.msi
|
41 |
-
*.msix
|
42 |
-
*.msm
|
43 |
-
*.msp
|
44 |
-
|
45 |
-
# Windows shortcuts
|
46 |
-
*.lnk
|
47 |
-
|
48 |
-
### Archives template
|
49 |
-
# It's better to unpack these files and commit the raw source because
|
50 |
-
# git has its own built in compression methods.
|
51 |
-
*.7z
|
52 |
-
*.jar
|
53 |
-
*.rar
|
54 |
-
*.zip
|
55 |
-
*.gz
|
56 |
-
*.gzip
|
57 |
-
*.tgz
|
58 |
-
*.bzip
|
59 |
-
*.bzip2
|
60 |
-
*.bz2
|
61 |
-
*.xz
|
62 |
-
*.lzma
|
63 |
-
*.xar
|
64 |
-
|
65 |
-
# Packing-only formats
|
66 |
-
*.iso
|
67 |
-
*.tar
|
68 |
-
|
69 |
-
# Package management formats
|
70 |
-
*.dmg
|
71 |
-
*.xpi
|
72 |
-
*.gem
|
73 |
-
*.egg
|
74 |
-
*.deb
|
75 |
-
*.rpm
|
76 |
-
*.txz
|
77 |
-
|
78 |
-
### JupyterNotebooks template
|
79 |
-
# gitignore template for Jupyter Notebooks
|
80 |
-
# website: http://jupyter.org/
|
81 |
-
|
82 |
-
.ipynb_checkpoints
|
83 |
-
*/.ipynb_checkpoints/*
|
84 |
-
|
85 |
-
# IPython
|
86 |
-
profile_default/
|
87 |
-
ipython_config.py
|
88 |
-
|
89 |
-
# Remove previous ipynb_checkpoints
|
90 |
-
# git rm -r .ipynb_checkpoints/
|
91 |
-
|
92 |
-
### macOS template
|
93 |
-
# General
|
94 |
-
.DS_Store
|
95 |
-
.AppleDouble
|
96 |
-
.LSOverride
|
97 |
-
|
98 |
-
# Icon must end with two \r
|
99 |
-
Icon
|
100 |
-
|
101 |
-
# Thumbnails
|
102 |
-
._*
|
103 |
-
|
104 |
-
# Files that might appear in the root of a volume
|
105 |
-
.DocumentRevisions-V100
|
106 |
-
.fseventsd
|
107 |
-
.Spotlight-V100
|
108 |
-
.TemporaryItems
|
109 |
-
.Trashes
|
110 |
-
.VolumeIcon.icns
|
111 |
-
.com.apple.timemachine.donotpresent
|
112 |
-
|
113 |
-
# Directories potentially created on remote AFP share
|
114 |
-
.AppleDB
|
115 |
-
.AppleDesktop
|
116 |
-
Network Trash Folder
|
117 |
-
Temporary Items
|
118 |
-
.apdisk
|
119 |
-
|
120 |
-
### Python template
|
121 |
-
# Byte-compiled / optimized / DLL files
|
122 |
-
__pycache__/
|
123 |
-
*.py[cod]
|
124 |
-
*$py.class
|
125 |
-
|
126 |
-
# C extensions
|
127 |
-
*.so
|
128 |
-
|
129 |
-
# Distribution / packaging
|
130 |
-
.Python
|
131 |
-
build/
|
132 |
-
develop-eggs/
|
133 |
-
dist/
|
134 |
-
downloads/
|
135 |
-
eggs/
|
136 |
-
.eggs/
|
137 |
-
lib/
|
138 |
-
lib64/
|
139 |
-
parts/
|
140 |
-
sdist/
|
141 |
-
var/
|
142 |
-
wheels/
|
143 |
-
share/python-wheels/
|
144 |
-
*.egg-info/
|
145 |
-
.installed.cfg
|
146 |
-
MANIFEST
|
147 |
-
|
148 |
-
# PyInstaller
|
149 |
-
# Usually these files are written by a python script from a template
|
150 |
-
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
151 |
-
*.manifest
|
152 |
-
*.spec
|
153 |
-
|
154 |
-
# Installer logs
|
155 |
-
pip-log.txt
|
156 |
-
pip-delete-this-directory.txt
|
157 |
-
|
158 |
-
# Unit test / coverage reports
|
159 |
-
htmlcov/
|
160 |
-
.tox/
|
161 |
-
.nox/
|
162 |
-
.coverage
|
163 |
-
.coverage.*
|
164 |
-
.cache
|
165 |
-
nosetests.xml
|
166 |
-
coverage.xml
|
167 |
-
*.cover
|
168 |
-
*.py,cover
|
169 |
-
.hypothesis/
|
170 |
-
.pytest_cache/
|
171 |
-
cover/
|
172 |
-
|
173 |
-
# Translations
|
174 |
-
*.mo
|
175 |
-
*.pot
|
176 |
-
|
177 |
-
# Django stuff:
|
178 |
-
*.log
|
179 |
-
local_settings.py
|
180 |
-
db.sqlite3
|
181 |
-
db.sqlite3-journal
|
182 |
-
|
183 |
-
# Flask stuff:
|
184 |
-
instance/
|
185 |
-
.webassets-cache
|
186 |
-
|
187 |
-
# Scrapy stuff:
|
188 |
-
.scrapy
|
189 |
-
|
190 |
-
# Sphinx documentation
|
191 |
-
docs/_build/
|
192 |
-
|
193 |
-
# PyBuilder
|
194 |
-
.pybuilder/
|
195 |
-
target/
|
196 |
-
|
197 |
-
# Jupyter Notebook
|
198 |
-
|
199 |
-
# IPython
|
200 |
-
|
201 |
-
# pyenv
|
202 |
-
# For a library or package, you might want to ignore these files since the code is
|
203 |
-
# intended to run in multiple environments; otherwise, check them in:
|
204 |
-
.python-version
|
205 |
-
|
206 |
-
# pipenv
|
207 |
-
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
208 |
-
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
209 |
-
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
210 |
-
# install all needed dependencies.
|
211 |
-
#Pipfile.lock
|
212 |
-
|
213 |
-
# poetry
|
214 |
-
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
215 |
-
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
216 |
-
# commonly ignored for libraries.
|
217 |
-
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
218 |
-
#poetry.lock
|
219 |
-
|
220 |
-
# pdm
|
221 |
-
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
222 |
-
#pdm.lock
|
223 |
-
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
|
224 |
-
# in version control.
|
225 |
-
# https://pdm.fming.dev/#use-with-ide
|
226 |
-
.pdm.toml
|
227 |
-
|
228 |
-
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
229 |
-
__pypackages__/
|
230 |
-
|
231 |
-
# Celery stuff
|
232 |
-
celerybeat-schedule
|
233 |
-
celerybeat.pid
|
234 |
-
|
235 |
-
# SageMath parsed files
|
236 |
-
*.sage.py
|
237 |
-
|
238 |
-
# Environments
|
239 |
-
.env
|
240 |
-
.venv
|
241 |
-
env/
|
242 |
-
venv/
|
243 |
-
ENV/
|
244 |
-
env.bak/
|
245 |
-
venv.bak/
|
246 |
-
|
247 |
-
# Spyder project settings
|
248 |
-
.spyderproject
|
249 |
-
.spyproject
|
250 |
-
|
251 |
-
# Rope project settings
|
252 |
-
.ropeproject
|
253 |
-
|
254 |
-
# mkdocs documentation
|
255 |
-
/site
|
256 |
-
|
257 |
-
# mypy
|
258 |
-
.mypy_cache/
|
259 |
-
.dmypy.json
|
260 |
-
dmypy.json
|
261 |
-
|
262 |
-
# Pyre type checker
|
263 |
-
.pyre/
|
264 |
-
|
265 |
-
# pytype static type analyzer
|
266 |
-
.pytype/
|
267 |
-
|
268 |
-
# Cython debug symbols
|
269 |
-
cython_debug/
|
270 |
-
|
271 |
-
### SublimeText template
|
272 |
-
# Cache files for Sublime Text
|
273 |
-
*.tmlanguage.cache
|
274 |
-
*.tmPreferences.cache
|
275 |
-
*.stTheme.cache
|
276 |
-
|
277 |
-
# Workspace files are user-specific
|
278 |
-
*.sublime-workspace
|
279 |
-
|
280 |
-
# Project files should be checked into the repository, unless a significant
|
281 |
-
# proportion of contributors will probably not be using Sublime Text
|
282 |
-
# *.sublime-project
|
283 |
-
|
284 |
-
# SFTP configuration file
|
285 |
-
sftp-config.json
|
286 |
-
sftp-config-alt*.json
|
287 |
-
|
288 |
-
# Package control specific files
|
289 |
-
Package Control.last-run
|
290 |
-
Package Control.ca-list
|
291 |
-
Package Control.ca-bundle
|
292 |
-
Package Control.system-ca-bundle
|
293 |
-
Package Control.cache/
|
294 |
-
Package Control.ca-certs/
|
295 |
-
Package Control.merged-ca-bundle
|
296 |
-
Package Control.user-ca-bundle
|
297 |
-
oscrypto-ca-bundle.crt
|
298 |
-
bh_unicode_properties.cache
|
299 |
-
|
300 |
-
# Sublime-github package stores a github token in this file
|
301 |
-
# https://packagecontrol.io/packages/sublime-github
|
302 |
-
GitHub.sublime-settings
|
303 |
-
|
|
|
1 |
+
.venv
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.python-version
ADDED
@@ -0,0 +1 @@
|
|
|
|
|
1 |
+
3.12
|
LICENSE
DELETED
@@ -1,427 +0,0 @@
|
|
1 |
-
Attribution-ShareAlike 4.0 International
|
2 |
-
|
3 |
-
=======================================================================
|
4 |
-
|
5 |
-
Creative Commons Corporation ("Creative Commons") is not a law firm and
|
6 |
-
does not provide legal services or legal advice. Distribution of
|
7 |
-
Creative Commons public licenses does not create a lawyer-client or
|
8 |
-
other relationship. Creative Commons makes its licenses and related
|
9 |
-
information available on an "as-is" basis. Creative Commons gives no
|
10 |
-
warranties regarding its licenses, any material licensed under their
|
11 |
-
terms and conditions, or any related information. Creative Commons
|
12 |
-
disclaims all liability for damages resulting from their use to the
|
13 |
-
fullest extent possible.
|
14 |
-
|
15 |
-
Using Creative Commons Public Licenses
|
16 |
-
|
17 |
-
Creative Commons public licenses provide a standard set of terms and
|
18 |
-
conditions that creators and other rights holders may use to share
|
19 |
-
original works of authorship and other material subject to copyright
|
20 |
-
and certain other rights specified in the public license below. The
|
21 |
-
following considerations are for informational purposes only, are not
|
22 |
-
exhaustive, and do not form part of our licenses.
|
23 |
-
|
24 |
-
Considerations for licensors: Our public licenses are
|
25 |
-
intended for use by those authorized to give the public
|
26 |
-
permission to use material in ways otherwise restricted by
|
27 |
-
copyright and certain other rights. Our licenses are
|
28 |
-
irrevocable. Licensors should read and understand the terms
|
29 |
-
and conditions of the license they choose before applying it.
|
30 |
-
Licensors should also secure all rights necessary before
|
31 |
-
applying our licenses so that the public can reuse the
|
32 |
-
material as expected. Licensors should clearly mark any
|
33 |
-
material not subject to the license. This includes other CC-
|
34 |
-
licensed material, or material used under an exception or
|
35 |
-
limitation to copyright. More considerations for licensors:
|
36 |
-
wiki.creativecommons.org/Considerations_for_licensors
|
37 |
-
|
38 |
-
Considerations for the public: By using one of our public
|
39 |
-
licenses, a licensor grants the public permission to use the
|
40 |
-
licensed material under specified terms and conditions. If
|
41 |
-
the licensor's permission is not necessary for any reason--for
|
42 |
-
example, because of any applicable exception or limitation to
|
43 |
-
copyright--then that use is not regulated by the license. Our
|
44 |
-
licenses grant only permissions under copyright and certain
|
45 |
-
other rights that a licensor has authority to grant. Use of
|
46 |
-
the licensed material may still be restricted for other
|
47 |
-
reasons, including because others have copyright or other
|
48 |
-
rights in the material. A licensor may make special requests,
|
49 |
-
such as asking that all changes be marked or described.
|
50 |
-
Although not required by our licenses, you are encouraged to
|
51 |
-
respect those requests where reasonable. More considerations
|
52 |
-
for the public:
|
53 |
-
wiki.creativecommons.org/Considerations_for_licensees
|
54 |
-
|
55 |
-
=======================================================================
|
56 |
-
|
57 |
-
Creative Commons Attribution-ShareAlike 4.0 International Public
|
58 |
-
License
|
59 |
-
|
60 |
-
By exercising the Licensed Rights (defined below), You accept and agree
|
61 |
-
to be bound by the terms and conditions of this Creative Commons
|
62 |
-
Attribution-ShareAlike 4.0 International Public License ("Public
|
63 |
-
License"). To the extent this Public License may be interpreted as a
|
64 |
-
contract, You are granted the Licensed Rights in consideration of Your
|
65 |
-
acceptance of these terms and conditions, and the Licensor grants You
|
66 |
-
such rights in consideration of benefits the Licensor receives from
|
67 |
-
making the Licensed Material available under these terms and
|
68 |
-
conditions.
|
69 |
-
|
70 |
-
|
71 |
-
Section 1 -- Definitions.
|
72 |
-
|
73 |
-
a. Adapted Material means material subject to Copyright and Similar
|
74 |
-
Rights that is derived from or based upon the Licensed Material
|
75 |
-
and in which the Licensed Material is translated, altered,
|
76 |
-
arranged, transformed, or otherwise modified in a manner requiring
|
77 |
-
permission under the Copyright and Similar Rights held by the
|
78 |
-
Licensor. For purposes of this Public License, where the Licensed
|
79 |
-
Material is a musical work, performance, or sound recording,
|
80 |
-
Adapted Material is always produced where the Licensed Material is
|
81 |
-
synched in timed relation with a moving image.
|
82 |
-
|
83 |
-
b. Adapter's License means the license You apply to Your Copyright
|
84 |
-
and Similar Rights in Your contributions to Adapted Material in
|
85 |
-
accordance with the terms and conditions of this Public License.
|
86 |
-
|
87 |
-
c. BY-SA Compatible License means a license listed at
|
88 |
-
creativecommons.org/compatiblelicenses, approved by Creative
|
89 |
-
Commons as essentially the equivalent of this Public License.
|
90 |
-
|
91 |
-
d. Copyright and Similar Rights means copyright and/or similar rights
|
92 |
-
closely related to copyright including, without limitation,
|
93 |
-
performance, broadcast, sound recording, and Sui Generis Database
|
94 |
-
Rights, without regard to how the rights are labeled or
|
95 |
-
categorized. For purposes of this Public License, the rights
|
96 |
-
specified in Section 2(b)(1)-(2) are not Copyright and Similar
|
97 |
-
Rights.
|
98 |
-
|
99 |
-
e. Effective Technological Measures means those measures that, in the
|
100 |
-
absence of proper authority, may not be circumvented under laws
|
101 |
-
fulfilling obligations under Article 11 of the WIPO Copyright
|
102 |
-
Treaty adopted on December 20, 1996, and/or similar international
|
103 |
-
agreements.
|
104 |
-
|
105 |
-
f. Exceptions and Limitations means fair use, fair dealing, and/or
|
106 |
-
any other exception or limitation to Copyright and Similar Rights
|
107 |
-
that applies to Your use of the Licensed Material.
|
108 |
-
|
109 |
-
g. License Elements means the license attributes listed in the name
|
110 |
-
of a Creative Commons Public License. The License Elements of this
|
111 |
-
Public License are Attribution and ShareAlike.
|
112 |
-
|
113 |
-
h. Licensed Material means the artistic or literary work, database,
|
114 |
-
or other material to which the Licensor applied this Public
|
115 |
-
License.
|
116 |
-
|
117 |
-
i. Licensed Rights means the rights granted to You subject to the
|
118 |
-
terms and conditions of this Public License, which are limited to
|
119 |
-
all Copyright and Similar Rights that apply to Your use of the
|
120 |
-
Licensed Material and that the Licensor has authority to license.
|
121 |
-
|
122 |
-
j. Licensor means the individual(s) or entity(ies) granting rights
|
123 |
-
under this Public License.
|
124 |
-
|
125 |
-
k. Share means to provide material to the public by any means or
|
126 |
-
process that requires permission under the Licensed Rights, such
|
127 |
-
as reproduction, public display, public performance, distribution,
|
128 |
-
dissemination, communication, or importation, and to make material
|
129 |
-
available to the public including in ways that members of the
|
130 |
-
public may access the material from a place and at a time
|
131 |
-
individually chosen by them.
|
132 |
-
|
133 |
-
l. Sui Generis Database Rights means rights other than copyright
|
134 |
-
resulting from Directive 96/9/EC of the European Parliament and of
|
135 |
-
the Council of 11 March 1996 on the legal protection of databases,
|
136 |
-
as amended and/or succeeded, as well as other essentially
|
137 |
-
equivalent rights anywhere in the world.
|
138 |
-
|
139 |
-
m. You means the individual or entity exercising the Licensed Rights
|
140 |
-
under this Public License. Your has a corresponding meaning.
|
141 |
-
|
142 |
-
|
143 |
-
Section 2 -- Scope.
|
144 |
-
|
145 |
-
a. License grant.
|
146 |
-
|
147 |
-
1. Subject to the terms and conditions of this Public License,
|
148 |
-
the Licensor hereby grants You a worldwide, royalty-free,
|
149 |
-
non-sublicensable, non-exclusive, irrevocable license to
|
150 |
-
exercise the Licensed Rights in the Licensed Material to:
|
151 |
-
|
152 |
-
a. reproduce and Share the Licensed Material, in whole or
|
153 |
-
in part; and
|
154 |
-
|
155 |
-
b. produce, reproduce, and Share Adapted Material.
|
156 |
-
|
157 |
-
2. Exceptions and Limitations. For the avoidance of doubt, where
|
158 |
-
Exceptions and Limitations apply to Your use, this Public
|
159 |
-
License does not apply, and You do not need to comply with
|
160 |
-
its terms and conditions.
|
161 |
-
|
162 |
-
3. Term. The term of this Public License is specified in Section
|
163 |
-
6(a).
|
164 |
-
|
165 |
-
4. Media and formats; technical modifications allowed. The
|
166 |
-
Licensor authorizes You to exercise the Licensed Rights in
|
167 |
-
all media and formats whether now known or hereafter created,
|
168 |
-
and to make technical modifications necessary to do so. The
|
169 |
-
Licensor waives and/or agrees not to assert any right or
|
170 |
-
authority to forbid You from making technical modifications
|
171 |
-
necessary to exercise the Licensed Rights, including
|
172 |
-
technical modifications necessary to circumvent Effective
|
173 |
-
Technological Measures. For purposes of this Public License,
|
174 |
-
simply making modifications authorized by this Section 2(a)
|
175 |
-
(4) never produces Adapted Material.
|
176 |
-
|
177 |
-
5. Downstream recipients.
|
178 |
-
|
179 |
-
a. Offer from the Licensor -- Licensed Material. Every
|
180 |
-
recipient of the Licensed Material automatically
|
181 |
-
receives an offer from the Licensor to exercise the
|
182 |
-
Licensed Rights under the terms and conditions of this
|
183 |
-
Public License.
|
184 |
-
|
185 |
-
b. Additional offer from the Licensor -- Adapted Material.
|
186 |
-
Every recipient of Adapted Material from You
|
187 |
-
automatically receives an offer from the Licensor to
|
188 |
-
exercise the Licensed Rights in the Adapted Material
|
189 |
-
under the conditions of the Adapter's License You apply.
|
190 |
-
|
191 |
-
c. No downstream restrictions. You may not offer or impose
|
192 |
-
any additional or different terms or conditions on, or
|
193 |
-
apply any Effective Technological Measures to, the
|
194 |
-
Licensed Material if doing so restricts exercise of the
|
195 |
-
Licensed Rights by any recipient of the Licensed
|
196 |
-
Material.
|
197 |
-
|
198 |
-
6. No endorsement. Nothing in this Public License constitutes or
|
199 |
-
may be construed as permission to assert or imply that You
|
200 |
-
are, or that Your use of the Licensed Material is, connected
|
201 |
-
with, or sponsored, endorsed, or granted official status by,
|
202 |
-
the Licensor or others designated to receive attribution as
|
203 |
-
provided in Section 3(a)(1)(A)(i).
|
204 |
-
|
205 |
-
b. Other rights.
|
206 |
-
|
207 |
-
1. Moral rights, such as the right of integrity, are not
|
208 |
-
licensed under this Public License, nor are publicity,
|
209 |
-
privacy, and/or other similar personality rights; however, to
|
210 |
-
the extent possible, the Licensor waives and/or agrees not to
|
211 |
-
assert any such rights held by the Licensor to the limited
|
212 |
-
extent necessary to allow You to exercise the Licensed
|
213 |
-
Rights, but not otherwise.
|
214 |
-
|
215 |
-
2. Patent and trademark rights are not licensed under this
|
216 |
-
Public License.
|
217 |
-
|
218 |
-
3. To the extent possible, the Licensor waives any right to
|
219 |
-
collect royalties from You for the exercise of the Licensed
|
220 |
-
Rights, whether directly or through a collecting society
|
221 |
-
under any voluntary or waivable statutory or compulsory
|
222 |
-
licensing scheme. In all other cases the Licensor expressly
|
223 |
-
reserves any right to collect such royalties.
|
224 |
-
|
225 |
-
|
226 |
-
Section 3 -- License Conditions.
|
227 |
-
|
228 |
-
Your exercise of the Licensed Rights is expressly made subject to the
|
229 |
-
following conditions.
|
230 |
-
|
231 |
-
a. Attribution.
|
232 |
-
|
233 |
-
1. If You Share the Licensed Material (including in modified
|
234 |
-
form), You must:
|
235 |
-
|
236 |
-
a. retain the following if it is supplied by the Licensor
|
237 |
-
with the Licensed Material:
|
238 |
-
|
239 |
-
i. identification of the creator(s) of the Licensed
|
240 |
-
Material and any others designated to receive
|
241 |
-
attribution, in any reasonable manner requested by
|
242 |
-
the Licensor (including by pseudonym if
|
243 |
-
designated);
|
244 |
-
|
245 |
-
ii. a copyright notice;
|
246 |
-
|
247 |
-
iii. a notice that refers to this Public License;
|
248 |
-
|
249 |
-
iv. a notice that refers to the disclaimer of
|
250 |
-
warranties;
|
251 |
-
|
252 |
-
v. a URI or hyperlink to the Licensed Material to the
|
253 |
-
extent reasonably practicable;
|
254 |
-
|
255 |
-
b. indicate if You modified the Licensed Material and
|
256 |
-
retain an indication of any previous modifications; and
|
257 |
-
|
258 |
-
c. indicate the Licensed Material is licensed under this
|
259 |
-
Public License, and include the text of, or the URI or
|
260 |
-
hyperlink to, this Public License.
|
261 |
-
|
262 |
-
2. You may satisfy the conditions in Section 3(a)(1) in any
|
263 |
-
reasonable manner based on the medium, means, and context in
|
264 |
-
which You Share the Licensed Material. For example, it may be
|
265 |
-
reasonable to satisfy the conditions by providing a URI or
|
266 |
-
hyperlink to a resource that includes the required
|
267 |
-
information.
|
268 |
-
|
269 |
-
3. If requested by the Licensor, You must remove any of the
|
270 |
-
information required by Section 3(a)(1)(A) to the extent
|
271 |
-
reasonably practicable.
|
272 |
-
|
273 |
-
b. ShareAlike.
|
274 |
-
|
275 |
-
In addition to the conditions in Section 3(a), if You Share
|
276 |
-
Adapted Material You produce, the following conditions also apply.
|
277 |
-
|
278 |
-
1. The Adapter's License You apply must be a Creative Commons
|
279 |
-
license with the same License Elements, this version or
|
280 |
-
later, or a BY-SA Compatible License.
|
281 |
-
|
282 |
-
2. You must include the text of, or the URI or hyperlink to, the
|
283 |
-
Adapter's License You apply. You may satisfy this condition
|
284 |
-
in any reasonable manner based on the medium, means, and
|
285 |
-
context in which You Share Adapted Material.
|
286 |
-
|
287 |
-
3. You may not offer or impose any additional or different terms
|
288 |
-
or conditions on, or apply any Effective Technological
|
289 |
-
Measures to, Adapted Material that restrict exercise of the
|
290 |
-
rights granted under the Adapter's License You apply.
|
291 |
-
|
292 |
-
|
293 |
-
Section 4 -- Sui Generis Database Rights.
|
294 |
-
|
295 |
-
Where the Licensed Rights include Sui Generis Database Rights that
|
296 |
-
apply to Your use of the Licensed Material:
|
297 |
-
|
298 |
-
a. for the avoidance of doubt, Section 2(a)(1) grants You the right
|
299 |
-
to extract, reuse, reproduce, and Share all or a substantial
|
300 |
-
portion of the contents of the database;
|
301 |
-
|
302 |
-
b. if You include all or a substantial portion of the database
|
303 |
-
contents in a database in which You have Sui Generis Database
|
304 |
-
Rights, then the database in which You have Sui Generis Database
|
305 |
-
Rights (but not its individual contents) is Adapted Material,
|
306 |
-
including for purposes of Section 3(b); and
|
307 |
-
|
308 |
-
c. You must comply with the conditions in Section 3(a) if You Share
|
309 |
-
all or a substantial portion of the contents of the database.
|
310 |
-
|
311 |
-
For the avoidance of doubt, this Section 4 supplements and does not
|
312 |
-
replace Your obligations under this Public License where the Licensed
|
313 |
-
Rights include other Copyright and Similar Rights.
|
314 |
-
|
315 |
-
|
316 |
-
Section 5 -- Disclaimer of Warranties and Limitation of Liability.
|
317 |
-
|
318 |
-
a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE
|
319 |
-
EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS
|
320 |
-
AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF
|
321 |
-
ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS,
|
322 |
-
IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION,
|
323 |
-
WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
324 |
-
PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS,
|
325 |
-
ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT
|
326 |
-
KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT
|
327 |
-
ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU.
|
328 |
-
|
329 |
-
b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE
|
330 |
-
TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION,
|
331 |
-
NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT,
|
332 |
-
INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES,
|
333 |
-
COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR
|
334 |
-
USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN
|
335 |
-
ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR
|
336 |
-
DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR
|
337 |
-
IN PART, THIS LIMITATION MAY NOT APPLY TO YOU.
|
338 |
-
|
339 |
-
c. The disclaimer of warranties and limitation of liability provided
|
340 |
-
above shall be interpreted in a manner that, to the extent
|
341 |
-
possible, most closely approximates an absolute disclaimer and
|
342 |
-
waiver of all liability.
|
343 |
-
|
344 |
-
|
345 |
-
Section 6 -- Term and Termination.
|
346 |
-
|
347 |
-
a. This Public License applies for the term of the Copyright and
|
348 |
-
Similar Rights licensed here. However, if You fail to comply with
|
349 |
-
this Public License, then Your rights under this Public License
|
350 |
-
terminate automatically.
|
351 |
-
|
352 |
-
b. Where Your right to use the Licensed Material has terminated under
|
353 |
-
Section 6(a), it reinstates:
|
354 |
-
|
355 |
-
1. automatically as of the date the violation is cured, provided
|
356 |
-
it is cured within 30 days of Your discovery of the
|
357 |
-
violation; or
|
358 |
-
|
359 |
-
2. upon express reinstatement by the Licensor.
|
360 |
-
|
361 |
-
For the avoidance of doubt, this Section 6(b) does not affect any
|
362 |
-
right the Licensor may have to seek remedies for Your violations
|
363 |
-
of this Public License.
|
364 |
-
|
365 |
-
c. For the avoidance of doubt, the Licensor may also offer the
|
366 |
-
Licensed Material under separate terms or conditions or stop
|
367 |
-
distributing the Licensed Material at any time; however, doing so
|
368 |
-
will not terminate this Public License.
|
369 |
-
|
370 |
-
d. Sections 1, 5, 6, 7, and 8 survive termination of this Public
|
371 |
-
License.
|
372 |
-
|
373 |
-
|
374 |
-
Section 7 -- Other Terms and Conditions.
|
375 |
-
|
376 |
-
a. The Licensor shall not be bound by any additional or different
|
377 |
-
terms or conditions communicated by You unless expressly agreed.
|
378 |
-
|
379 |
-
b. Any arrangements, understandings, or agreements regarding the
|
380 |
-
Licensed Material not stated herein are separate from and
|
381 |
-
independent of the terms and conditions of this Public License.
|
382 |
-
|
383 |
-
|
384 |
-
Section 8 -- Interpretation.
|
385 |
-
|
386 |
-
a. For the avoidance of doubt, this Public License does not, and
|
387 |
-
shall not be interpreted to, reduce, limit, restrict, or impose
|
388 |
-
conditions on any use of the Licensed Material that could lawfully
|
389 |
-
be made without permission under this Public License.
|
390 |
-
|
391 |
-
b. To the extent possible, if any provision of this Public License is
|
392 |
-
deemed unenforceable, it shall be automatically reformed to the
|
393 |
-
minimum extent necessary to make it enforceable. If the provision
|
394 |
-
cannot be reformed, it shall be severed from this Public License
|
395 |
-
without affecting the enforceability of the remaining terms and
|
396 |
-
conditions.
|
397 |
-
|
398 |
-
c. No term or condition of this Public License will be waived and no
|
399 |
-
failure to comply consented to unless expressly agreed to by the
|
400 |
-
Licensor.
|
401 |
-
|
402 |
-
d. Nothing in this Public License constitutes or may be interpreted
|
403 |
-
as a limitation upon, or waiver of, any privileges and immunities
|
404 |
-
that apply to the Licensor or You, including from the legal
|
405 |
-
processes of any jurisdiction or authority.
|
406 |
-
|
407 |
-
|
408 |
-
=======================================================================
|
409 |
-
|
410 |
-
Creative Commons is not a party to its public
|
411 |
-
licenses. Notwithstanding, Creative Commons may elect to apply one of
|
412 |
-
its public licenses to material it publishes and in those instances
|
413 |
-
will be considered the “Licensor.” The text of the Creative Commons
|
414 |
-
public licenses is dedicated to the public domain under the CC0 Public
|
415 |
-
Domain Dedication. Except for the limited purpose of indicating that
|
416 |
-
material is shared under a Creative Commons public license or as
|
417 |
-
otherwise permitted by the Creative Commons policies published at
|
418 |
-
creativecommons.org/policies, Creative Commons does not authorize the
|
419 |
-
use of the trademark "Creative Commons" or any other trademark or logo
|
420 |
-
of Creative Commons without its prior written consent including,
|
421 |
-
without limitation, in connection with any unauthorized modifications
|
422 |
-
to any of its public licenses or any other arrangements,
|
423 |
-
understandings, or agreements concerning use of licensed material. For
|
424 |
-
the avoidance of doubt, this paragraph does not form part of the
|
425 |
-
public licenses.
|
426 |
-
|
427 |
-
Creative Commons may be contacted at creativecommons.org.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Makefile
DELETED
@@ -1,6 +0,0 @@
|
|
1 |
-
|
2 |
-
install:
|
3 |
-
pip install -U -r requirements-dev.txt
|
4 |
-
|
5 |
-
start:
|
6 |
-
gradio app.py
|
|
|
|
|
|
|
|
|
|
|
|
|
|
README.md
CHANGED
@@ -3,37 +3,9 @@ title: EcoLogits Calculator
|
|
3 |
emoji: 🧮
|
4 |
colorFrom: green
|
5 |
colorTo: indigo
|
6 |
-
sdk:
|
7 |
-
sdk_version:
|
8 |
app_file: app.py
|
9 |
pinned: true
|
10 |
license: cc-by-sa-4.0
|
11 |
-
---
|
12 |
-
|
13 |
-
Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
|
14 |
-
|
15 |
-
|
16 |
-
To do:
|
17 |
-
|
18 |
-
- [ ] Add a tab with basic documentation
|
19 |
-
- [X] Definition of each indicator (check the use of tool tip in gradio ?)
|
20 |
-
- [ ] Basic explanation of the methodology
|
21 |
-
- Why it depends on the number of tokens? (What is a token?)
|
22 |
-
- What is taken into account? (usage, manufacturing for inference != training)
|
23 |
-
- What hypotheses have we made?
|
24 |
-
- [X] Explain how to reduce the impacts? What are good strategies? (Valentin)
|
25 |
-
- [ ] Add more indicators like (km by car, kg of concrete, ...) we can use [impactco2.fr](https://impactco2.fr/). (Valentin)
|
26 |
-
- [X] First version
|
27 |
-
- [ ] To enrich
|
28 |
-
- [ ] Call to actions: (Valentin)
|
29 |
-
- [X] Follow us on LinkedIn
|
30 |
-
- [ ] Share the results of a simulation (e.g. export an image generated with plotly for instance?)
|
31 |
-
- [X] Add an advanced/expert tab
|
32 |
-
- [X] True number of tokens
|
33 |
-
- [X] Expose more inputs like the electricity mix
|
34 |
-
- [X] Examples of electricity mixes
|
35 |
-
- [X] Custom number of parameters
|
36 |
-
- [x] Live reload mode
|
37 |
-
- [ ] Idea : "estimate a given prompt impact" function which allows to enter a prompt in a text field and estimate its impacts
|
38 |
-
- [ ] Idea: copy-paste a ChatGPT conversation link and estimate the impacts.
|
39 |
-
- [ ] Idea: compare with country electricity consumption
|
|
|
3 |
emoji: 🧮
|
4 |
colorFrom: green
|
5 |
colorTo: indigo
|
6 |
+
sdk: streamlit
|
7 |
+
sdk_version: 1.40.2
|
8 |
app_file: app.py
|
9 |
pinned: true
|
10 |
license: cc-by-sa-4.0
|
11 |
+
---
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
__init__.py
ADDED
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from .content import *
|
2 |
+
from .constants import *
|
3 |
+
from .expert import expert_mode
|
4 |
+
from .utils import *
|
5 |
+
from .calculator import calculator_mode
|
6 |
+
from .impacts import get_impacts, display_impacts
|
7 |
+
from .models import load_models
|
8 |
+
from .electricity_mix import *
|
__pycache__/__init__.cpython-312.pyc
ADDED
Binary file (502 Bytes). View file
|
|
__pycache__/calculator.cpython-312.pyc
ADDED
Binary file (4.68 kB). View file
|
|
__pycache__/constants.cpython-312.pyc
ADDED
Binary file (3.39 kB). View file
|
|
__pycache__/content.cpython-312.pyc
ADDED
Binary file (17 kB). View file
|
|
__pycache__/electricity_mix.cpython-312.pyc
ADDED
Binary file (5.74 kB). View file
|
|
__pycache__/expert.cpython-312.pyc
ADDED
Binary file (8.14 kB). View file
|
|
__pycache__/impacts.cpython-312.pyc
ADDED
Binary file (7.91 kB). View file
|
|
__pycache__/models.cpython-312.pyc
ADDED
Binary file (3.67 kB). View file
|
|
__pycache__/utils.cpython-312.pyc
ADDED
Binary file (12.9 kB). View file
|
|
app.py
CHANGED
@@ -1,539 +1,46 @@
|
|
1 |
-
import
|
2 |
-
|
3 |
-
from
|
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 |
-
OPENAI_MODELS,
|
48 |
-
label="Model",
|
49 |
-
value=OPENAI_MODELS[0][1],
|
50 |
-
filterable=True,
|
51 |
-
)
|
52 |
-
elif provider == "anthropic":
|
53 |
-
return gr.Dropdown(
|
54 |
-
ANTHROPIC_MODELS,
|
55 |
-
label="Model",
|
56 |
-
value=ANTHROPIC_MODELS[0][1],
|
57 |
-
filterable=True,
|
58 |
-
)
|
59 |
-
elif provider == "cohere":
|
60 |
-
return gr.Dropdown(
|
61 |
-
COHERE_MODELS,
|
62 |
-
label="Model",
|
63 |
-
value=COHERE_MODELS[0][1],
|
64 |
-
filterable=True,
|
65 |
-
)
|
66 |
-
elif provider == "huggingface_hub/meta":
|
67 |
-
return gr.Dropdown(
|
68 |
-
META_MODELS,
|
69 |
-
label="Model",
|
70 |
-
value=META_MODELS[0][1],
|
71 |
-
filterable=True,
|
72 |
-
)
|
73 |
-
elif provider == "mistralai":
|
74 |
-
return gr.Dropdown(
|
75 |
-
MISTRALAI_MODELS,
|
76 |
-
label="Model",
|
77 |
-
value=MISTRALAI_MODELS[0][1],
|
78 |
-
filterable=True,
|
79 |
-
)
|
80 |
-
|
81 |
-
|
82 |
-
def custom():
|
83 |
-
return CUSTOM
|
84 |
-
|
85 |
-
def model_active_params_fn(model_name: str, n_param: float):
|
86 |
-
if model_name == CUSTOM:
|
87 |
-
return n_param
|
88 |
-
provider, model_name = model_name.split('/', 1)
|
89 |
-
model = models.find_model(provider=provider, model_name=model_name)
|
90 |
-
try: #moe with range
|
91 |
-
return model.architecture.parameters.active.max
|
92 |
-
except:
|
93 |
-
try: #moe without range
|
94 |
-
return model.architecture.parameters.active
|
95 |
-
except:
|
96 |
-
try: #dense with range
|
97 |
-
return model.architecture.parameters.max
|
98 |
-
except: #dense without range
|
99 |
-
return model.architecture.parameters
|
100 |
-
|
101 |
-
def model_total_params_fn(model_name: str, n_param: float):
|
102 |
-
if model_name == CUSTOM:
|
103 |
-
return n_param
|
104 |
-
provider, model_name = model_name.split('/', 1)
|
105 |
-
model = models.find_model(provider=provider, model_name=model_name)
|
106 |
-
try: #moe
|
107 |
-
return model.architecture.parameters.total.max
|
108 |
-
except:
|
109 |
-
try: #dense with range
|
110 |
-
return model.architecture.parameters.max
|
111 |
-
except: #dense without range
|
112 |
-
try:
|
113 |
-
return model.architecture.parameters.total
|
114 |
-
except:
|
115 |
-
return model.architecture.parameters
|
116 |
-
|
117 |
-
def mix_fn(country_code: str, mix_adpe: float, mix_pe: float, mix_gwp: float):
|
118 |
-
if country_code == CUSTOM:
|
119 |
-
return mix_adpe, mix_pe, mix_gwp
|
120 |
-
return find_electricity_mix(country_code)
|
121 |
-
|
122 |
-
with gr.Blocks(css=custom_css) as demo:
|
123 |
-
gr.Markdown(HERO_TEXT)
|
124 |
-
|
125 |
-
with gr.Tab("🧮 Calculator"):
|
126 |
-
with gr.Row():
|
127 |
-
gr.Markdown("# Estimate the environmental impacts of LLM inference")
|
128 |
-
with gr.Row():
|
129 |
-
input_provider = gr.Dropdown(
|
130 |
-
PROVIDERS,
|
131 |
-
label="Provider",
|
132 |
-
value=PROVIDERS[0][1],
|
133 |
-
filterable=True,
|
134 |
-
)
|
135 |
-
|
136 |
-
input_model = gr.Dropdown(
|
137 |
-
OPENAI_MODELS,
|
138 |
-
label="Model",
|
139 |
-
value=OPENAI_MODELS[0][1],
|
140 |
-
filterable=True,
|
141 |
-
)
|
142 |
-
input_provider.change(model_list, input_provider, input_model)
|
143 |
-
|
144 |
-
input_prompt = gr.Dropdown(
|
145 |
-
PROMPTS,
|
146 |
-
label="Example prompt",
|
147 |
-
value=400,
|
148 |
-
)
|
149 |
-
|
150 |
-
|
151 |
-
@gr.render(inputs=[input_provider, input_model, input_prompt])
|
152 |
-
def render_simple(provider, model, prompt):
|
153 |
-
if provider.startswith("huggingface_hub"):
|
154 |
-
provider = provider.split("/")[0]
|
155 |
-
if models.find_model(provider, model) is not None:
|
156 |
-
impacts = llm_impacts(
|
157 |
-
provider=provider,
|
158 |
-
model_name=model,
|
159 |
-
output_token_count=prompt,
|
160 |
-
request_latency=100000
|
161 |
-
)
|
162 |
-
impacts = format_impacts(impacts)
|
163 |
-
|
164 |
-
# Inference impacts
|
165 |
-
with gr.Blocks():
|
166 |
-
if f"{provider}/{model}" in CLOSED_SOURCE_MODELS:
|
167 |
-
with gr.Row():
|
168 |
-
gr.Markdown("""<p> ⚠️ You have selected a closed-source model. Please be aware that
|
169 |
-
some providers do not fully disclose information about such models. Consequently, our
|
170 |
-
estimates have a lower precision for closed-source models. For further details, refer to
|
171 |
-
our FAQ in the About section.
|
172 |
-
</p>""", elem_classes="warning-box")
|
173 |
-
|
174 |
-
with gr.Row():
|
175 |
-
gr.Markdown("""
|
176 |
-
## Environmental impacts
|
177 |
-
|
178 |
-
To understand how the environmental impacts are computed go to the 📖 Methodology tab.
|
179 |
-
""")
|
180 |
-
with gr.Row():
|
181 |
-
with gr.Column(scale=1, min_width=220):
|
182 |
-
gr.Markdown(f"""
|
183 |
-
<h2 align="center">⚡️ Energy</h2>
|
184 |
-
$$ \Large {impacts.energy.magnitude:.3g} \ \large {impacts.energy.units} $$
|
185 |
-
<p align="center"><i>Evaluates the electricity consumption<i></p><br>
|
186 |
-
""")
|
187 |
-
with gr.Column(scale=1, min_width=220):
|
188 |
-
gr.Markdown(f"""
|
189 |
-
<h2 align="center">🌍️ GHG Emissions</h2>
|
190 |
-
$$ \Large {impacts.gwp.magnitude:.3g} \ \large {impacts.gwp.units} $$
|
191 |
-
<p align="center"><i>Evaluates the effect on global warming<i></p><br>
|
192 |
-
""")
|
193 |
-
with gr.Column(scale=1, min_width=220):
|
194 |
-
gr.Markdown(f"""
|
195 |
-
<h2 align="center">🪨 Abiotic Resources</h2>
|
196 |
-
$$ \Large {impacts.adpe.magnitude:.3g} \ \large {impacts.adpe.units} $$
|
197 |
-
<p align="center"><i>Evaluates the use of metals and minerals<i></p><br>
|
198 |
-
""")
|
199 |
-
with gr.Column(scale=1, min_width=220):
|
200 |
-
gr.Markdown(f"""
|
201 |
-
<h2 align="center">⛽️ Primary Energy</h2>
|
202 |
-
$$ \Large {impacts.pe.magnitude:.3g} \ \large {impacts.pe.units} $$
|
203 |
-
<p align="center"><i>Evaluates the use of energy resources<i></p><br>
|
204 |
-
""")
|
205 |
-
|
206 |
-
# Impacts equivalents
|
207 |
-
with gr.Blocks():
|
208 |
-
with gr.Row():
|
209 |
-
gr.Markdown("""
|
210 |
-
---
|
211 |
-
## That's equivalent to...
|
212 |
-
|
213 |
-
Making this request to the LLM is equivalent to the following actions.
|
214 |
-
""")
|
215 |
-
with gr.Row():
|
216 |
-
physical_activity, distance = format_energy_eq_physical_activity(impacts.energy)
|
217 |
-
if physical_activity == PhysicalActivity.WALKING:
|
218 |
-
physical_activity = "🚶 " + physical_activity.capitalize()
|
219 |
-
if physical_activity == PhysicalActivity.RUNNING:
|
220 |
-
physical_activity = "🏃 " + physical_activity.capitalize()
|
221 |
-
with gr.Column(scale=1, min_width=300):
|
222 |
-
gr.Markdown(f"""
|
223 |
-
<h2 align="center">{physical_activity} $$ \Large {distance.magnitude:.3g}\ {distance.units} $$ </h2>
|
224 |
-
<p align="center"><i>Based on energy consumption<i></p><br>
|
225 |
-
""", latex_delimiters=[{"left": "$$", "right": "$$", "display": False}])
|
226 |
-
|
227 |
-
ev_eq = format_energy_eq_electric_vehicle(impacts.energy)
|
228 |
-
with gr.Column(scale=1, min_width=300):
|
229 |
-
gr.Markdown(f"""
|
230 |
-
<h2 align="center">🔋 Electric Vehicle $$ \Large {ev_eq.magnitude:.3g}\ {ev_eq.units} $$ </h2>
|
231 |
-
<p align="center"><i>Based on energy consumption<i></p><br>
|
232 |
-
""", latex_delimiters=[{"left": "$$", "right": "$$", "display": False}])
|
233 |
-
|
234 |
-
streaming_eq = format_gwp_eq_streaming(impacts.gwp)
|
235 |
-
with gr.Column(scale=1, min_width=300):
|
236 |
-
gr.Markdown(f"""
|
237 |
-
<h2 align="center">⏯️ Streaming $$ \Large {streaming_eq.magnitude:.3g}\ {streaming_eq.units} $$ </h2>
|
238 |
-
<p align="center"><i>Based on GHG emissions<i></p><br>
|
239 |
-
""", latex_delimiters=[{"left": "$$", "right": "$$", "display": False}])
|
240 |
-
|
241 |
-
# Bigger scale impacts equivalent
|
242 |
-
with gr.Blocks():
|
243 |
-
with gr.Row():
|
244 |
-
gr.Markdown("""
|
245 |
-
## What if 1% of the planet does this request everyday for 1 year?
|
246 |
-
|
247 |
-
If this use case is largely deployed around the world the equivalent impacts would be. (The
|
248 |
-
impacts of this request x 1% of 8 billion people x 365 days in a year.)
|
249 |
-
""")
|
250 |
-
with gr.Row():
|
251 |
-
electricity_production, count = format_energy_eq_electricity_production(impacts.energy)
|
252 |
-
if electricity_production == EnergyProduction.NUCLEAR:
|
253 |
-
emoji = "☢️"
|
254 |
-
name = "Nuclear power plants"
|
255 |
-
if electricity_production == EnergyProduction.WIND:
|
256 |
-
emoji = "💨️ "
|
257 |
-
name = "Wind turbines"
|
258 |
-
with gr.Column(scale=1, min_width=300):
|
259 |
-
gr.Markdown(f"""
|
260 |
-
<h2 align="center">{emoji} $$ \Large {count.magnitude:.0f} $$ {name} <span style="font-size: 12px">(yearly)</span></h2>
|
261 |
-
<p align="center"><i>Based on electricity consumption<i></p><br>
|
262 |
-
""", latex_delimiters=[{"left": "$$", "right": "$$", "display": False}])
|
263 |
-
|
264 |
-
ireland_count = format_energy_eq_electricity_consumption_ireland(impacts.energy)
|
265 |
-
with gr.Column(scale=1, min_width=300):
|
266 |
-
gr.Markdown(f"""
|
267 |
-
<h2 align="center">🇮🇪 $$ \Large {ireland_count.magnitude:.2g} $$ x Ireland <span style="font-size: 12px">(yearly ⚡️ cons.)</span></h2>
|
268 |
-
<p align="center"><i>Based on electricity consumption<i></p><br>
|
269 |
-
""", latex_delimiters=[{"left": "$$", "right": "$$", "display": False}])
|
270 |
-
|
271 |
-
paris_nyc_airplane = format_gwp_eq_airplane_paris_nyc(impacts.gwp)
|
272 |
-
with gr.Column(scale=1, min_width=300):
|
273 |
-
gr.Markdown(f"""
|
274 |
-
<h2 align="center">✈️ $$ \Large {paris_nyc_airplane.magnitude:,.0f} $$ Paris ↔ NYC </h2>
|
275 |
-
<p align="center"><i>Based on GHG emissions<i></p><br>
|
276 |
-
""", latex_delimiters=[{"left": "$$", "right": "$$", "display": False}])
|
277 |
-
|
278 |
-
with gr.Tab("🤓 Expert Mode"):
|
279 |
-
|
280 |
-
with gr.Row():
|
281 |
-
gr.Markdown("# 🤓 Expert mode")
|
282 |
-
|
283 |
-
model = gr.Dropdown(
|
284 |
-
MODELS + [CUSTOM],
|
285 |
-
label="Model name",
|
286 |
-
value="openai/gpt-3.5-turbo",
|
287 |
-
filterable=True,
|
288 |
-
interactive=True
|
289 |
-
)
|
290 |
-
input_model_active_params = gr.Number(
|
291 |
-
label="Number of billions of active parameters",
|
292 |
-
value=45.0,
|
293 |
-
interactive=True
|
294 |
-
)
|
295 |
-
input_model_total_params = gr.Number(
|
296 |
-
label="Number of billions of total parameters",
|
297 |
-
value=45.0,
|
298 |
-
interactive=True
|
299 |
-
)
|
300 |
-
|
301 |
-
model.change(fn=model_active_params_fn,
|
302 |
-
inputs=[model, input_model_active_params],
|
303 |
-
outputs=[input_model_active_params])
|
304 |
-
model.change(fn=model_total_params_fn,
|
305 |
-
inputs=[model, input_model_total_params],
|
306 |
-
outputs=[input_model_total_params])
|
307 |
-
input_model_active_params.input(fn=custom, outputs=[model])
|
308 |
-
input_model_total_params.input(fn=custom, outputs=[model])
|
309 |
-
|
310 |
-
input_tokens = gr.Number(
|
311 |
-
label="Output tokens",
|
312 |
-
value=100
|
313 |
-
)
|
314 |
-
|
315 |
-
mix = gr.Dropdown(
|
316 |
-
COUNTRY_CODES + [CUSTOM],
|
317 |
-
label="Location",
|
318 |
-
value="WOR",
|
319 |
-
filterable=True,
|
320 |
-
interactive=True
|
321 |
-
)
|
322 |
-
input_mix_gwp = gr.Number(
|
323 |
-
label="Electricity mix - GHG emissions [kgCO2eq / kWh]",
|
324 |
-
value=find_electricity_mix('WOR')[2],
|
325 |
-
interactive=True
|
326 |
-
)
|
327 |
-
input_mix_adpe = gr.Number(
|
328 |
-
label="Electricity mix - Abiotic resources [kgSbeq / kWh]",
|
329 |
-
value=find_electricity_mix('WOR')[0],
|
330 |
-
interactive=True
|
331 |
-
)
|
332 |
-
input_mix_pe = gr.Number(
|
333 |
-
label="Electricity mix - Primary energy [MJ / kWh]",
|
334 |
-
value=find_electricity_mix('WOR')[1],
|
335 |
-
interactive=True
|
336 |
-
)
|
337 |
-
|
338 |
-
mix.change(fn=mix_fn,
|
339 |
-
inputs=[mix, input_mix_adpe, input_mix_pe, input_mix_gwp],
|
340 |
-
outputs=[input_mix_adpe, input_mix_pe, input_mix_gwp])
|
341 |
-
input_mix_gwp.input(fn=custom, outputs=mix)
|
342 |
-
input_mix_adpe.input(fn=custom, outputs=mix)
|
343 |
-
input_mix_pe.input(fn=custom, outputs=mix)
|
344 |
-
|
345 |
-
|
346 |
-
@gr.render(inputs=[
|
347 |
-
input_model_active_params,
|
348 |
-
input_model_total_params,
|
349 |
-
input_tokens,
|
350 |
-
input_mix_gwp,
|
351 |
-
input_mix_adpe,
|
352 |
-
input_mix_pe
|
353 |
-
])
|
354 |
-
def render_expert(
|
355 |
-
model_active_params,
|
356 |
-
model_total_params,
|
357 |
-
tokens,
|
358 |
-
mix_gwp,
|
359 |
-
mix_adpe,
|
360 |
-
mix_pe
|
361 |
-
):
|
362 |
-
impacts = compute_llm_impacts_expert(
|
363 |
-
model_active_parameter_count=model_active_params,
|
364 |
-
model_total_parameter_count=model_total_params,
|
365 |
-
output_token_count=tokens,
|
366 |
-
request_latency=100000,
|
367 |
-
if_electricity_mix_gwp=mix_gwp,
|
368 |
-
if_electricity_mix_adpe=mix_adpe,
|
369 |
-
if_electricity_mix_pe=mix_pe
|
370 |
-
)
|
371 |
-
impacts, usage, embodied = format_impacts_expert(impacts)
|
372 |
-
|
373 |
-
with gr.Blocks():
|
374 |
-
|
375 |
-
with gr.Row():
|
376 |
-
gr.Markdown(f"""
|
377 |
-
<h2 align = "center">Environmental impacts</h2>
|
378 |
-
""")
|
379 |
-
|
380 |
-
with gr.Row():
|
381 |
-
with gr.Column(scale=1, min_width=220):
|
382 |
-
gr.Markdown(f"""
|
383 |
-
<h2 align="center">⚡️ Energy</h2>
|
384 |
-
$$ \Large {impacts.energy.magnitude:.3g} \ \large {impacts.energy.units} $$
|
385 |
-
<p align="center"><i>Evaluates the electricity consumption<i></p><br>
|
386 |
-
""")
|
387 |
-
|
388 |
-
with gr.Column(scale=1, min_width=220):
|
389 |
-
gr.Markdown(f"""
|
390 |
-
<h2 align="center">🌍️ GHG Emissions</h2>
|
391 |
-
$$ \Large {impacts.gwp.magnitude:.3g} \ \large {impacts.gwp.units} $$
|
392 |
-
<p align="center"><i>Evaluates the effect on global warming<i></p><br>
|
393 |
-
$$ \Large {100*usage.gwp.value / (usage.gwp.value + embodied.gwp.value):.3} $$
|
394 |
-
<p align="center"><i>% of GWP by usage (vs embodied)<i></p><br>
|
395 |
-
""")
|
396 |
-
|
397 |
-
with gr.Column(scale=1, min_width=220):
|
398 |
-
gr.Markdown(f"""
|
399 |
-
<h2 align="center">🪨 Abiotic Resources</h2>
|
400 |
-
$$ \Large {impacts.adpe.magnitude:.3g} \ \large {impacts.adpe.units} $$
|
401 |
-
<p align="center"><i>Evaluates the use of metals and minerals<i></p><br>
|
402 |
-
$$ \Large {100*usage.adpe.value / (usage.adpe.value + embodied.adpe.value):.3} $$
|
403 |
-
<p align="center"><i>% of ADPE by usage (vs embodied)<i></p><br>
|
404 |
-
""")
|
405 |
-
|
406 |
-
with gr.Column(scale=1, min_width=220):
|
407 |
-
gr.Markdown(f"""
|
408 |
-
<h2 align="center">⛽️ Primary Energy</h2>
|
409 |
-
$$ \Large {impacts.pe.magnitude:.3g} \ \large {impacts.pe.units} $$
|
410 |
-
<p align="center"><i>Evaluates the use of energy resources<i></p><br>
|
411 |
-
$$ \Large {100*usage.pe.value / (usage.pe.value + embodied.pe.value):.3} $$
|
412 |
-
<p align="center"><i>% of PE by usage (vs embodied)<i></p><br>
|
413 |
-
""")
|
414 |
-
|
415 |
-
with gr.Row():
|
416 |
-
gr.Markdown(f"""
|
417 |
-
<h2 align="center">How can location impact the footprint ?</h2>
|
418 |
-
""")
|
419 |
-
|
420 |
-
with gr.Row():
|
421 |
-
gr.BarPlot(df_elec_mix_for_plot,
|
422 |
-
x='country',
|
423 |
-
y='electricity_mix',
|
424 |
-
sort='y',
|
425 |
-
scale=1,
|
426 |
-
height=250,
|
427 |
-
min_width=800,
|
428 |
-
x_title=None,
|
429 |
-
y_title='electricity mix in gCO2eq / kWh')
|
430 |
-
|
431 |
-
# with gr.Tab("🔍 Evaluate your own usage"):
|
432 |
-
|
433 |
-
# with gr.Row():
|
434 |
-
# gr.Markdown("""
|
435 |
-
# # 🔍 Evaluate your own usage
|
436 |
-
# ⚠️ For now, only ChatGPT conversation import is available.
|
437 |
-
# You can always try out other models - however results might be inaccurate due to fixed parameters, such as tokenization method.
|
438 |
-
# """)
|
439 |
-
|
440 |
-
# def compute_own_impacts(amount_token, model):
|
441 |
-
# provider = model.split('/')[0].lower()
|
442 |
-
# model = model.split('/')[1]
|
443 |
-
# impacts = llm_impacts(
|
444 |
-
# provider=provider,
|
445 |
-
# model_name=model,
|
446 |
-
# output_token_count=amount_token,
|
447 |
-
# request_latency=100000
|
448 |
-
# )
|
449 |
-
|
450 |
-
# impacts = format_impacts(impacts)
|
451 |
-
|
452 |
-
# energy = f"""
|
453 |
-
# <h2 align="center">⚡️ Energy</h2>
|
454 |
-
# $$ \Large {impacts.energy.magnitude:.3g} \ \large {impacts.energy.units} $$
|
455 |
-
# <p align="center"><i>Evaluates the electricity consumption<i></p><br>
|
456 |
-
# """
|
457 |
-
|
458 |
-
# gwp = f"""
|
459 |
-
# <h2 align="center">🌍️ GHG Emissions</h2>
|
460 |
-
# $$ \Large {impacts.gwp.magnitude:.3g} \ \large {impacts.gwp.units} $$
|
461 |
-
# <p align="center"><i>Evaluates the effect on global warming<i></p><br>
|
462 |
-
# """
|
463 |
-
|
464 |
-
# adp = f"""
|
465 |
-
# <h2 align="center">🪨 Abiotic Resources</h2>
|
466 |
-
# $$ \Large {impacts.adpe.magnitude:.3g} \ \large {impacts.adpe.units} $$
|
467 |
-
# <p align="center"><i>Evaluates the use of metals and minerals<i></p><br>
|
468 |
-
# """
|
469 |
-
|
470 |
-
# pe = f"""
|
471 |
-
# <h2 align="center">⛽️ Primary Energy</h2>
|
472 |
-
# $$ \Large {impacts.pe.magnitude:.3g} \ \large {impacts.pe.units} $$
|
473 |
-
# <p align="center"><i>Evaluates the use of energy resources<i></p><br>
|
474 |
-
# """
|
475 |
-
|
476 |
-
# return energy, gwp, adp, pe
|
477 |
-
|
478 |
-
# def combined_function(text, model):
|
479 |
-
# n_token = process_input(text)
|
480 |
-
# energy, gwp, adp, pe = compute_own_impacts(n_token, model)
|
481 |
-
# return n_token, energy, gwp, adp, pe
|
482 |
-
|
483 |
-
# with gr.Blocks():
|
484 |
-
|
485 |
-
# text_input = gr.Textbox(label="Paste the URL here (must be on https://chatgpt.com/share/xxxx format)")
|
486 |
-
# model = gr.Dropdown(
|
487 |
-
# MODELS,
|
488 |
-
# label="Model name",
|
489 |
-
# value="openai/gpt-4o",
|
490 |
-
# filterable=True,
|
491 |
-
# interactive=True
|
492 |
-
# )
|
493 |
-
|
494 |
-
# process_button = gr.Button("Estimate this usage footprint")
|
495 |
-
|
496 |
-
# with gr.Accordion("ℹ️ Infos", open=False):
|
497 |
-
# n_token = gr.Textbox(label="Total amount of tokens :")
|
498 |
-
|
499 |
-
# with gr.Row():
|
500 |
-
# with gr.Column(scale=1, min_width=220):
|
501 |
-
# energy = gr.Markdown()
|
502 |
-
# with gr.Column(scale=1, min_width=220):
|
503 |
-
# gwp = gr.Markdown()
|
504 |
-
# with gr.Column(scale=1, min_width=220):
|
505 |
-
# adp = gr.Markdown()
|
506 |
-
# with gr.Column(scale=1, min_width=220):
|
507 |
-
# pe = gr.Markdown()
|
508 |
-
|
509 |
-
# process_button.click(
|
510 |
-
# fn=combined_function,
|
511 |
-
# inputs=[text_input, model],
|
512 |
-
# outputs=[n_token, energy, gwp, adp, pe]
|
513 |
-
# )
|
514 |
-
|
515 |
-
with gr.Tab("📖 Methodology"):
|
516 |
-
gr.Markdown(METHODOLOGY_TEXT,
|
517 |
-
elem_classes="descriptive-text",
|
518 |
-
latex_delimiters=[
|
519 |
-
{"left": "$$", "right": "$$", "display": True},
|
520 |
-
{"left": "$", "right": "$", "display": False}
|
521 |
-
])
|
522 |
-
|
523 |
-
with gr.Tab("ℹ️ About"):
|
524 |
-
gr.Markdown(ABOUT_TEXT, elem_classes="descriptive-text",)
|
525 |
-
|
526 |
-
with gr.Accordion("📚 Citation", open=False):
|
527 |
-
gr.Textbox(
|
528 |
-
value=CITATION_TEXT,
|
529 |
-
label=CITATION_LABEL,
|
530 |
-
interactive=False,
|
531 |
-
show_copy_button=True,
|
532 |
-
lines=len(CITATION_TEXT.split('\n')),
|
533 |
-
)
|
534 |
-
|
535 |
-
# License
|
536 |
-
gr.Markdown(LICENCE_TEXT)
|
537 |
-
|
538 |
-
if __name__ == '__main__':
|
539 |
-
demo.launch()
|
|
|
1 |
+
import streamlit as st
|
2 |
+
|
3 |
+
from src.content import (
|
4 |
+
HERO_TEXT,
|
5 |
+
ABOUT_TEXT,
|
6 |
+
CITATION_LABEL,
|
7 |
+
CITATION_TEXT,
|
8 |
+
LICENCE_TEXT,
|
9 |
+
INTRO_TEXT,
|
10 |
+
METHODOLOGY_TEXT
|
11 |
+
)
|
12 |
+
|
13 |
+
from src.expert import expert_mode
|
14 |
+
from src.calculator import calculator_mode
|
15 |
+
|
16 |
+
st.set_page_config(layout="wide",
|
17 |
+
page_title="ECOLOGITS",
|
18 |
+
page_icon='💬')
|
19 |
+
|
20 |
+
st.html(HERO_TEXT)
|
21 |
+
|
22 |
+
st.markdown(INTRO_TEXT)
|
23 |
+
|
24 |
+
tab_calculator, tab_expert, tab_method, tab_about = st.tabs(['🧮 Calculator', '🤓 Expert Mode', '📖 Methodology', 'ℹ️ About'])
|
25 |
+
|
26 |
+
with tab_calculator:
|
27 |
+
|
28 |
+
calculator_mode()
|
29 |
+
|
30 |
+
with tab_expert:
|
31 |
+
|
32 |
+
expert_mode()
|
33 |
+
|
34 |
+
with tab_method:
|
35 |
+
|
36 |
+
st.write(METHODOLOGY_TEXT)
|
37 |
+
|
38 |
+
with tab_about:
|
39 |
+
|
40 |
+
st.write(ABOUT_TEXT)
|
41 |
+
|
42 |
+
with st.expander('📚 Citation'):
|
43 |
+
st.html(CITATION_LABEL)
|
44 |
+
st.html(CITATION_TEXT)
|
45 |
+
|
46 |
+
st.html(LICENCE_TEXT)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
calculator.py
ADDED
@@ -0,0 +1,67 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import streamlit as st
|
2 |
+
import pandas as pd
|
3 |
+
|
4 |
+
from ecologits.tracers.utils import llm_impacts
|
5 |
+
from src.impacts import get_impacts, display_impacts, display_equivalent
|
6 |
+
from src.utils import format_impacts
|
7 |
+
from src.content import WARNING_CLOSED_SOURCE, WARNING_MULTI_MODAL, WARNING_BOTH
|
8 |
+
from src.models import load_models, clean_models_data
|
9 |
+
|
10 |
+
from src.constants import PROMPTS
|
11 |
+
|
12 |
+
def calculator_mode():
|
13 |
+
|
14 |
+
with st.container(border=True):
|
15 |
+
|
16 |
+
df = load_models()
|
17 |
+
|
18 |
+
col1, col2, col3 = st.columns(3)
|
19 |
+
|
20 |
+
with col1:
|
21 |
+
provider = st.selectbox(label = 'Provider',
|
22 |
+
options = [x for x in df['provider_clean'].unique()],
|
23 |
+
index = 9)
|
24 |
+
provider_raw = df[df['provider_clean'] == provider]['provider'].values[0]
|
25 |
+
|
26 |
+
with col2:
|
27 |
+
model = st.selectbox('Model', [x for x in df['name_clean'].unique() if x in df[df['provider_clean'] == provider]['name_clean'].unique()])
|
28 |
+
model_raw = df[(df['provider_clean'] == provider) & (df['name_clean'] == model)]['name'].values[0]
|
29 |
+
|
30 |
+
with col3:
|
31 |
+
output_tokens = st.selectbox('Example prompt', [x[0] for x in PROMPTS])
|
32 |
+
|
33 |
+
# WARNING DISPLAY
|
34 |
+
|
35 |
+
df_filtered = df[(df['provider_clean'] == provider) & (df['name_clean'] == model)]
|
36 |
+
|
37 |
+
if df_filtered['warning_arch'].values[0] and not df_filtered['warning_multi_modal'].values[0]:
|
38 |
+
st.warning(WARNING_CLOSED_SOURCE)
|
39 |
+
if df_filtered['warning_multi_modal'].values[0] and not df_filtered['warning_arch'].values[0]:
|
40 |
+
st.warning(WARNING_MULTI_MODAL)
|
41 |
+
if df_filtered['warning_arch'].values[0] and df_filtered['warning_multi_modal'].values[0]:
|
42 |
+
st.warning(WARNING_BOTH)
|
43 |
+
|
44 |
+
try:
|
45 |
+
impacts = llm_impacts(
|
46 |
+
provider=provider_raw,
|
47 |
+
model_name=model_raw,
|
48 |
+
output_token_count=[x[1] for x in PROMPTS if x[0] == output_tokens][0],
|
49 |
+
request_latency=100000
|
50 |
+
)
|
51 |
+
|
52 |
+
impacts, _, _ = format_impacts(impacts)
|
53 |
+
|
54 |
+
with st.container(border=True):
|
55 |
+
|
56 |
+
st.markdown('<h3 align = "center">Environmental impacts</h3>', unsafe_allow_html=True)
|
57 |
+
st.markdown('<p align = "center">To understand how the environmental impacts are computed go to the 📖 Methodology tab.</p>', unsafe_allow_html=True)
|
58 |
+
display_impacts(impacts)
|
59 |
+
|
60 |
+
with st.container(border=True):
|
61 |
+
|
62 |
+
st.markdown('<h3 align = "center">That\'s equivalent to ...</h3>', unsafe_allow_html=True)
|
63 |
+
st.markdown('<p align = "center">Making this request to the LLM is equivalent to the following actions :</p>', unsafe_allow_html=True)
|
64 |
+
display_equivalent(impacts)
|
65 |
+
|
66 |
+
except Exception as e:
|
67 |
+
st.error('Could not find the model in the repository. Please try another model.')
|
constants.py
ADDED
@@ -0,0 +1,106 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
PROVIDERS = [
|
2 |
+
("OpenAI", "openai"),
|
3 |
+
("Anthropic", "anthropic"),
|
4 |
+
("Cohere", "cohere"),
|
5 |
+
("Meta", "huggingface_hub/meta"),
|
6 |
+
("Mistral AI", "mistralai"),
|
7 |
+
]
|
8 |
+
|
9 |
+
OPENAI_MODELS = [
|
10 |
+
("GPT-4o", "gpt-4o"),
|
11 |
+
("GPT-4-Turbo", "gpt-4-turbo"),
|
12 |
+
("GPT-4", "gpt-4"),
|
13 |
+
("GPT-3.5-Turbo", "gpt-3.5-turbo"),
|
14 |
+
]
|
15 |
+
|
16 |
+
ANTHROPIC_MODELS = [
|
17 |
+
("Claude 3 Opus", "claude-3-opus-20240229"),
|
18 |
+
("Claude 3 Sonnet", "claude-3-sonnet-20240229"),
|
19 |
+
("Claude 3 Haiku", "claude-3-haiku-20240307"),
|
20 |
+
("Claude 2.1", "claude-2.1"),
|
21 |
+
("Claude 2.0", "claude-2.0"),
|
22 |
+
("Claude Instant 1.2", "claude-instant-1.2"),
|
23 |
+
]
|
24 |
+
|
25 |
+
COHERE_MODELS = [
|
26 |
+
("Command Light", "command-light"),
|
27 |
+
("Command", "command"),
|
28 |
+
("Command R", "command-r"),
|
29 |
+
("Command R+", "command-r-plus"),
|
30 |
+
]
|
31 |
+
|
32 |
+
META_MODELS = [
|
33 |
+
("Llama 3 8B", "meta-llama/Meta-Llama-3-8B"),
|
34 |
+
("Llama 3 70B", "meta-llama/Meta-Llama-3-70B"),
|
35 |
+
("Llama 2 7B", "meta-llama/Llama-2-7b-hf"),
|
36 |
+
("Llama 2 13B", "meta-llama/Llama-2-13b-hf"),
|
37 |
+
("Llama 2 70B", "meta-llama/Llama-2-70b-hf"),
|
38 |
+
]
|
39 |
+
|
40 |
+
MISTRALAI_MODELS = [
|
41 |
+
("Mistral 7B", "open-mistral-7b"),
|
42 |
+
("Mixtral 8x7B", "open-mixtral-8x7b"),
|
43 |
+
("Mixtral 8x22B", "open-mixtral-8x22b"),
|
44 |
+
("Tiny", "mistral-tiny-2312"),
|
45 |
+
("Small", "mistral-small-2402"),
|
46 |
+
("Medium", "mistral-medium-2312"),
|
47 |
+
("Large", "mistral-large-2402"),
|
48 |
+
]
|
49 |
+
|
50 |
+
PROMPTS = [
|
51 |
+
("Write a Tweet", 50),
|
52 |
+
("Write an email", 170),
|
53 |
+
("Write an article summary", 250),
|
54 |
+
("Small conversation with a chatbot", 400),
|
55 |
+
("Write a report of 5 pages", 5000),
|
56 |
+
("Write the code for this app", 10000)
|
57 |
+
]
|
58 |
+
PROMPTS = [(s + f" ({v} output tokens)", v) for (s, v) in PROMPTS]
|
59 |
+
|
60 |
+
CLOSED_SOURCE_MODELS = {
|
61 |
+
"openai/gpt-4o",
|
62 |
+
"openai/gpt-4-turbo",
|
63 |
+
"openai/gpt-4",
|
64 |
+
"openai/gpt-3.5-turbo",
|
65 |
+
"anthropic/claude-3-opus-20240229",
|
66 |
+
"anthropic/claude-3-sonnet-20240229",
|
67 |
+
"anthropic/claude-3-haiku-20240307",
|
68 |
+
"anthropic/claude-2.1",
|
69 |
+
"anthropic/claude-2.0",
|
70 |
+
"anthropic/claude-instant-1.2",
|
71 |
+
"mistralai/mistral-tiny-2312",
|
72 |
+
"mistralai/mistral-small-2402",
|
73 |
+
"mistralai/mistral-medium-2312",
|
74 |
+
"mistralai/mistral-large-2402",
|
75 |
+
}
|
76 |
+
|
77 |
+
MODELS = [
|
78 |
+
("OpenAI / GPT-4o", "openai/gpt-4o"),
|
79 |
+
("OpenAI / GPT-4-Turbo", "openai/gpt-4-turbo"),
|
80 |
+
("OpenAI / GPT-4", "openai/gpt-4"),
|
81 |
+
("OpenAI / GPT-3.5-Turbo", "openai/gpt-3.5-turbo"),
|
82 |
+
("Anthropic / Claude 3 Opus", "anthropic/claude-3-opus-20240229"),
|
83 |
+
("Anthropic / Claude 3 Sonnet", "anthropic/claude-3-sonnet-20240229"),
|
84 |
+
("Anthropic / Claude 3 Haiku", "anthropic/claude-3-haiku-20240307"),
|
85 |
+
("Anthropic / Claude 2.1", "anthropic/claude-2.1"),
|
86 |
+
("Anthropic / Claude 2.0", "anthropic/claude-2.0"),
|
87 |
+
("Anthropic / Claude Instant 1.2", "anthropic/claude-instant-1.2"),
|
88 |
+
("Mistral AI / Mistral 7B", "mistralai/open-mistral-7b"),
|
89 |
+
("Mistral AI / Mixtral 8x7B", "mistralai/open-mixtral-8x7b"),
|
90 |
+
("Mistral AI / Mixtral 8x22B", "mistralai/open-mixtral-8x22b"),
|
91 |
+
("Mistral AI / Tiny", "mistralai/mistral-tiny-2312"),
|
92 |
+
("Mistral AI / Small", "mistralai/mistral-small-2402"),
|
93 |
+
("Mistral AI / Medium", "mistralai/mistral-medium-2312"),
|
94 |
+
("Mistral AI / Large", "mistralai/mistral-large-2402"),
|
95 |
+
("Meta / Llama 3 8B", "huggingface_hub/meta-llama/Meta-Llama-3-8B"),
|
96 |
+
("Meta / Llama 3 70B", "huggingface_hub/meta-llama/Meta-Llama-3-70B"),
|
97 |
+
("Meta / Llama 2 7B", "huggingface_hub/meta-llama/Llama-2-7b-hf"),
|
98 |
+
("Meta / Llama 2 13B", "huggingface_hub/meta-llama/Llama-2-13b-hf"),
|
99 |
+
("Meta / Llama 2 70B", "huggingface_hub/meta-llama/Llama-2-70b-hf"),
|
100 |
+
("Cohere / Command Light", "cohere/command-light"),
|
101 |
+
("Cohere / Command", "cohere/command"),
|
102 |
+
("Cohere / Command R", "cohere/command-r"),
|
103 |
+
("Cohere / Command R+", "cohere/command-r-plus"),
|
104 |
+
]
|
105 |
+
|
106 |
+
MODEL_REPOSITORY_URL = "https://raw.githubusercontent.com/genai-impact/ecologits/refs/heads/main/ecologits/data/models.json"
|
content.py
ADDED
@@ -0,0 +1,232 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
HERO_TEXT = """
|
2 |
+
<div align="center">
|
3 |
+
<a href="https://ecologits.ai/">
|
4 |
+
<img style="max-height: 80px" alt="EcoLogits" src="https://raw.githubusercontent.com/genai-impact/ecologits/main/docs/assets/logo_light.png">
|
5 |
+
</a>
|
6 |
+
</div>
|
7 |
+
<h1 align="center">🧮 EcoLogits Calculator</h1>
|
8 |
+
<div align="center">
|
9 |
+
<p style="max-width: 500px; text-align: center">
|
10 |
+
<i><b>EcoLogits</b> is a python library that tracks the <b>energy consumption</b> and <b>environmental
|
11 |
+
footprint</b> of using <b>generative AI</b> models through APIs.</i>
|
12 |
+
</p>
|
13 |
+
</div>
|
14 |
+
<br>
|
15 |
+
"""
|
16 |
+
|
17 |
+
INTRO_TEXT = """
|
18 |
+
This tool is developed and maintained by [GenAI Impact](https://genai-impact.org/) non-profit. Learn more about
|
19 |
+
🌱 EcoLogits by reading the documentation on [ecologits.ai](https://ecologits.ai).
|
20 |
+
|
21 |
+
🩷 Support us by giving a ⭐️ on our [GitHub repository](https://github.com/genai-impact/ecologits) and by following our [LinkedIn page](https://www.linkedin.com/company/genai-impact/).
|
22 |
+
"""
|
23 |
+
|
24 |
+
WARNING_CLOSED_SOURCE = """
|
25 |
+
⚠️ The model architecture has not been publicly released, expect lower precision of estimations.
|
26 |
+
"""
|
27 |
+
|
28 |
+
WARNING_MULTI_MODAL = """
|
29 |
+
⚠️ The model architecture is multimodal, expect lower precision of estimations.
|
30 |
+
"""
|
31 |
+
|
32 |
+
WARNING_BOTH = """
|
33 |
+
⚠️ The model architecture has not been publicly released and is multimodal, expect lower precision of estimations.
|
34 |
+
"""
|
35 |
+
|
36 |
+
ABOUT_TEXT = r"""
|
37 |
+
## 🎯 Our goal
|
38 |
+
**The main goal of the EcoLogits Calculator is to raise awareness on the environmental impacts of LLM inference.**
|
39 |
+
The rapid evolution of generative AI is reshaping numerous industries and aspects of our daily lives. While these
|
40 |
+
advancements offer some benefits, they also **pose substantial environmental challenges that cannot be overlooked**.
|
41 |
+
Plus the issue of AI's environmental footprint has been mainly discussed at training stage but rarely at the inference
|
42 |
+
stage. That is an issue because **inference impacts for LLMs can largely overcome the training impacts when deployed
|
43 |
+
at large scales**.
|
44 |
+
At **[GenAI Impact](https://genai-impact.org/) we are dedicated to understanding and mitigating the environmental
|
45 |
+
impacts of generative AI** through rigorous research, innovative tools, and community engagement. Especially, in early
|
46 |
+
2024 we have launched an new open-source tool called [EcoLogits](https://github.com/genai-impact/ecologits) that tracks
|
47 |
+
the energy consumption and environmental footprint of using generative AI models through APIs.
|
48 |
+
## 🙋 FAQ
|
49 |
+
**How we assess the impacts of closed-source models?**
|
50 |
+
Environmental impacts are calculated based on model architecture and parameter count. For closed-source models, we
|
51 |
+
lack transparency from providers, so we estimate parameter counts using available information. For GPT models, we
|
52 |
+
based our estimates on leaked GPT-4 architecture and scaled parameters count for GPT-4-Turbo and GPT-4o based on
|
53 |
+
pricing differences. For other proprietary models like Anthropic's Claude, we assume similar impacts for models
|
54 |
+
released around the same time with similar performance on public benchmarks. Please note that these estimates are
|
55 |
+
based on assumptions and may not be exact. Our methods are open-source and transparent so you can always see the
|
56 |
+
hypotheses we use.
|
57 |
+
**Which generative AI models or providers are supported?**
|
58 |
+
To see the full list of **generative AI providers** currently supported by EcoLogits, see the following
|
59 |
+
[documentation page](https://ecologits.ai/providers/). As of today we only support LLMs but we plan to add support for
|
60 |
+
embeddings, image generation, multi-modal models and more. If you are interested don't hesitate to
|
61 |
+
[join us](https://genai-impact.org/contact/) and accelerate our work!
|
62 |
+
**How to reduce AI environmental impacts?**
|
63 |
+
* Look at **indirect impacts** of your project. Does the finality of your project is impacting negatively the
|
64 |
+
environment?
|
65 |
+
* **Be frugal** and question your usage or need of AI
|
66 |
+
* Do you really need AI to solve your problem?
|
67 |
+
* Do you really need GenAI to solve your problem? (you can read this [paper](https://aclanthology.org/2023.emnlp-industry.39.pdf))
|
68 |
+
* Use small and specialized models to solve your problem.
|
69 |
+
* Evaluate before, during and after the development of your project the environmental impacts with tools like
|
70 |
+
🌱 [EcoLogits](https://github.com/genai-impact/ecologits) or [CodeCarbon](https://github.com/mlco2/codecarbon)
|
71 |
+
(see [more tools](https://github.com/samuelrince/awesome-green-ai))
|
72 |
+
* Restrict the use case and limit the usage of your tool or feature to the desired purpose.
|
73 |
+
* Do NOT buy new GPUs / hardware
|
74 |
+
* Hardware manufacturing for data centers is around 50% of the impact.
|
75 |
+
* Use cloud instances that are located in low emissions / high energy efficiency data centers
|
76 |
+
(see [electricitymaps.com](https://app.electricitymaps.com/map))
|
77 |
+
* Optimize your models for production
|
78 |
+
* Quantize your models.
|
79 |
+
* Use inference optimization tricks.
|
80 |
+
* Prefer fine-tuning of small and existing models over generalist models.
|
81 |
+
**What is the difference between **EcoLogits** and [CodeCarbon](https://github.com/mlco2/codecarbon)?**
|
82 |
+
EcoLogits is focused on estimating the environmental impacts of generative AI (only LLMs for now) used **through API
|
83 |
+
providers (such as OpenAI, Anthropic, Cloud APIs...)** whereas CodeCarbon is more general tool to measure energy
|
84 |
+
consumption and estimate GHG emissions measurement. If you deploy LLMs locally we encourage you to use CodeCarbon to
|
85 |
+
get real numbers of your energy consumption.
|
86 |
+
## 🤗 Contributing
|
87 |
+
We are eager to get feedback from the community, don't hesitate to engage the discussion with us on this
|
88 |
+
[GitHub thread](https://github.com/genai-impact/ecologits/discussions/45) or message us on
|
89 |
+
[LinkedIn](https://www.linkedin.com/company/genai-impact/).
|
90 |
+
We also welcome any open-source contributions on 🌱 **[EcoLogits](https://github.com/genai-impact/ecologits)** or on
|
91 |
+
🧮 **EcoLogits Calculator**.
|
92 |
+
## ⚖️ License
|
93 |
+
<p xmlns:cc="http://creativecommons.org/ns#" >
|
94 |
+
This work is licensed under
|
95 |
+
<a href="https://creativecommons.org/licenses/by-sa/4.0/?ref=chooser-v1" target="_blank" rel="license noopener noreferrer" style="display:inline-block;">
|
96 |
+
CC BY-SA 4.0
|
97 |
+
</a>
|
98 |
+
<img style="display:inline-block;height:22px!important;margin-left:3px;vertical-align:text-bottom;" src="https://mirrors.creativecommons.org/presskit/icons/cc.svg?ref=chooser-v1" alt="">
|
99 |
+
<img style="display:inline-block;height:22px!important;margin-left:3px;vertical-align:text-bottom;" src="https://mirrors.creativecommons.org/presskit/icons/by.svg?ref=chooser-v1" alt="">
|
100 |
+
<img style="display:inline-block;height:22px!important;margin-left:3px;vertical-align:text-bottom;" src="https://mirrors.creativecommons.org/presskit/icons/sa.svg?ref=chooser-v1" alt="">
|
101 |
+
</p>
|
102 |
+
## 🙌 Acknowledgement
|
103 |
+
We thank [Data For Good](https://dataforgood.fr/) and [Boavizta](https://boavizta.org/en) for supporting the
|
104 |
+
development of this project. Their contributions of tools, best practices, and expertise in environmental impact
|
105 |
+
assessment have been invaluable.
|
106 |
+
We also extend our gratitude to the open-source contributions of 🤗 [Hugging Face](huggingface.com) on the LLM-Perf
|
107 |
+
Leaderboard.
|
108 |
+
## 🤝 Contact
|
109 |
+
For general question on the project, please use the [GitHub thread](https://github.com/genai-impact/ecologits/discussions/45).
|
110 |
+
Otherwise use our contact form on [genai-impact.org/contact](https://genai-impact.org/contact/).
|
111 |
+
"""
|
112 |
+
|
113 |
+
|
114 |
+
METHODOLOGY_TEXT = r"""
|
115 |
+
## 📖 Methodology
|
116 |
+
We have developed a methodology to **estimate the energy consumption and environmental impacts for an LLM inference**
|
117 |
+
based on request parameters and hypotheses on the data center location, the hardware used, the model architecture and
|
118 |
+
more.
|
119 |
+
In this section we will only cover the principles of the methodology related to the 🧮 **EcoLogits Calculator**. If
|
120 |
+
you wish to learn more on the environmental impacts modeling of an LLM request checkout the
|
121 |
+
🌱 [EcoLogits documentation page](https://ecologits.ai/methodology/).
|
122 |
+
### Modeling impacts of an LLM request
|
123 |
+
The environmental impacts of an LLM inference are split into the **usage impacts** $I_{request}^u$ to account for
|
124 |
+
electricity consumption and the **embodied impacts** $I_{request}^e$ that relates to resource extraction, hardware
|
125 |
+
manufacturing and transportation. In general terms it can be expressed as follow:
|
126 |
+
$$ I_{request} = I_{request}^u + I_{request}^e $$
|
127 |
+
$$ I_{request} = E_{request}*F_{em}+\frac{\Delta T}{\Delta L}*I_{server}^e $$
|
128 |
+
With,
|
129 |
+
* $E_{request}$ the estimated energy consumption of the server and its cooling system.
|
130 |
+
* $F_{em}$ the electricity mix that depends on the country and time.
|
131 |
+
* $\frac{\Delta T}{\Delta L}$ the hardware usage ratio i.e. the computation time over the lifetime of the hardware.
|
132 |
+
* $I_{server}^e$ the embodied impacts of the server.
|
133 |
+
Additionally, to ⚡️ **direct energy consumption** the environmental impacts are expressed in **three dimensions
|
134 |
+
(multi-criteria impacts)** that are:
|
135 |
+
* 🌍 **Global Warming Potential** (GWP): Potential impact on global warming in kgCO2eq (commonly known as GHG/carbon
|
136 |
+
emissions).
|
137 |
+
* 🪨 **Abiotic Depletion Potential for Elements** (ADPe): Impact on the depletion of non-living resources such as
|
138 |
+
minerals or metals in kgSbeq.
|
139 |
+
* ⛽️ **Primary Energy** (PE): Total energy consumed from primary sources in MJ.
|
140 |
+
### Principles, Data and Hypotheses
|
141 |
+
We use a **bottom-up methodology** to model impacts, meaning that we will estimate the impacts of low-level physical
|
142 |
+
components to then estimate the impacts at software level (in that case an LLM inference). We also rely on **Life
|
143 |
+
Cycle Approach (LCA) proxies and approach** to model both usage and embodied phases with multi-criteria impacts.
|
144 |
+
If you are interested in this approach we recommend you to read the following [Boavizta](https://boavizta.org/)
|
145 |
+
resources.
|
146 |
+
* [Digital & environment: How to evaluate server manufacturing footprint, beyond greenhouse gas emissions?](https://boavizta.org/en/blog/empreinte-de-la-fabrication-d-un-serveur)
|
147 |
+
* [Boavizta API automated evaluation of environmental impacts of ICT services and equipments](https://boavizta.org/en/blog/boavizta-api-automated-evaluation-of-ict-impacts-on-the-environment)
|
148 |
+
* [Boavizta API documentation](https://doc.api.boavizta.org/)
|
149 |
+
We leverage **open data to estimate the environmental impacts**, here is an exhaustive list of our data providers.
|
150 |
+
* [LLM-Perf Leaderboard](https://huggingface.co/spaces/optimum/llm-perf-leaderboard) to estimate GPU energy consumption
|
151 |
+
and latency based on the model architecture and number of output tokens.
|
152 |
+
* [Boavizta API](https://github.com/Boavizta/boaviztapi) to estimate server embodied impacts and base energy
|
153 |
+
consumption.
|
154 |
+
* [ADEME Base Empreinte®](https://base-empreinte.ademe.fr/) for electricity mix impacts per country.
|
155 |
+
Finally here are the **main hypotheses** we have made to compute the impacts.
|
156 |
+
* ⚠️ **We *"guesstimate"* the model architecture of proprietary LLMs when not disclosed by the provider.**
|
157 |
+
* Production setup: quantized models running on data center grade servers and GPUs such as A100.
|
158 |
+
* Electricity mix does not depend on time (help us enhance EcoLogits and work on this [issue](https://github.com/genai-impact/ecologits/issues/42))
|
159 |
+
* Ignore the following impacts: unused cloud resources, data center building, network and end-user devices... (for now)
|
160 |
+
## Equivalents
|
161 |
+
We have integrated impact equivalents to help people better understand the impacts and have reference points for
|
162 |
+
standard use cases and everyday activities.
|
163 |
+
### Request impacts
|
164 |
+
These equivalents are computed based on the request impacts only.
|
165 |
+
#### 🚶♂️➡️ Walking or 🏃♂️➡️ running distance
|
166 |
+
We compare the ⚡️ direct energy consumption with the energy consumption of someone 🚶♂️➡️ walking or 🏃♂️➡️ running.
|
167 |
+
From [runningtools.com](https://www.runningtools.com/energyusage.htm) we consider the following energy values per
|
168 |
+
physical activity (for someone weighing 70kg):
|
169 |
+
* 🚶♂️➡️ walking: $ 196\ kJ/km $ (speed of $ 3\ km/h $)
|
170 |
+
* 🏃♂️➡️ running: $ 294\ kJ/km $ (speed of $ 10\ km/h $)
|
171 |
+
We divide the request energy consumption by these values to compute the distance traveled.
|
172 |
+
#### 🔋 Electric Vehicle distance
|
173 |
+
We compare the ⚡️ direct energy consumption with the energy consumer by a EV car. From
|
174 |
+
[selectra.info](https://selectra.info/energie/actualites/insolite/consommation-vehicules-electriques-france-2040) or
|
175 |
+
[tesla.com](https://www.tesla.com/fr_fr/support/power-consumption) we consider an average value of energy consumed per
|
176 |
+
kilometer of: $ 0.17\ kWh/km $.
|
177 |
+
We divide the request energy consumption by this value to compute the distance driven by an EV.
|
178 |
+
#### ⏯️ Streaming time
|
179 |
+
We compare the 🌍 GHG emissions of the request and of streaming a video. From
|
180 |
+
[impactco2.fr](https://impactco2.fr/outils/comparateur?value=1&comparisons=streamingvideo), we consider that
|
181 |
+
$ 1\ kgCO2eq $ is equivalent to $ 15.6\ h $ of streaming.
|
182 |
+
We multiply that value by the GHG emissions of the request to get an equivalent in hours of video streaming.
|
183 |
+
### Scaled impacts
|
184 |
+
These equivalents are computed based on the request impacts scaled to a worldwide adoption use case. We imply that the
|
185 |
+
same request is done 1% of the planet everyday for 1 year, and then compute impact equivalents.
|
186 |
+
$$
|
187 |
+
I_{scaled} = I_{request} * [1 \\% \ \text{of}\ 8B\ \text{people on earth}] * 365\ \text{days}
|
188 |
+
$$
|
189 |
+
#### Number of 💨 wind turbines or ☢️ nuclear plants
|
190 |
+
We compare the ⚡️ direct energy consumption (scaled) by the energy production of wind turbines and nuclear power
|
191 |
+
plants. From [ecologie.gouv.fr](https://www.ecologie.gouv.fr/eolien-terrestre) we consider that a $ 2\ MW $ wind
|
192 |
+
turbine produces $ 4.2\ GWh $ a year. And from [edf.fr](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)
|
193 |
+
we learn that a $ 900\ MW $ nuclear power plant produces $ 6\ TWh $ a year.
|
194 |
+
We divide the scaled energy consumption by these values to get the number of wind turbines or nuclear power plants
|
195 |
+
needed.
|
196 |
+
#### Multiplier of 🇮🇪 Ireland electricity consumption
|
197 |
+
We compare the ⚡️ direct energy consumption (scaled) by the electricity consumption of Ireland per year. From
|
198 |
+
[wikipedia.org](https://en.wikipedia.org/wiki/List_of_countries_by_electricity_consumption) we consider the Ireland
|
199 |
+
electricity consumption to be $ 33\ TWh $ a year for a population of 5M.
|
200 |
+
We divide the scaled energy consumption by this value to get the equivalent number of "Ireland countries".
|
201 |
+
#### Number of ✈️ Paris ↔ New York City flights
|
202 |
+
We compare the 🌍 GHG emissions (scaled) of the request and of a return flight Paris ↔ New York City. From
|
203 |
+
[impactco2.fr](https://impactco2.fr/outils/comparateur?value=1&comparisons=&equivalent=avion-pny) we consider that a
|
204 |
+
return flight Paris → New York City → Paris for one passenger emits $ 1,770\ kgCO2eq $ and we consider an overall
|
205 |
+
average load of 100 passengers per flight.
|
206 |
+
We divide the scaled GHG emissions by this value to get the equivalent number of return flights.
|
207 |
+
|
208 |
+
#### If you are motivated to help us test and enhance this methodology [contact us](https://genai-impact.org/contact/)! 💪
|
209 |
+
"""
|
210 |
+
|
211 |
+
CITATION_LABEL = "BibTeX citation for EcoLogits Calculator and the EcoLogits library:"
|
212 |
+
CITATION_TEXT = r"""@misc{ecologits-calculator,
|
213 |
+
author={Samuel Rincé, Adrien Banse and Valentin Defour},
|
214 |
+
title={EcoLogits Calculator},
|
215 |
+
year={2025},
|
216 |
+
howpublished= {\url{https://huggingface.co/spaces/genai-impact/ecologits-calculator}},
|
217 |
+
}
|
218 |
+
@software{ecologits,
|
219 |
+
author = {Samuel Rincé, Adrien Banse, Vinh Nguyen and Luc Berton},
|
220 |
+
publisher = {GenAI Impact},
|
221 |
+
title = {EcoLogits: track the energy consumption and environmental footprint of using generative AI models through APIs.},
|
222 |
+
}"""
|
223 |
+
|
224 |
+
LICENCE_TEXT = """<p xmlns:cc="http://creativecommons.org/ns#" >
|
225 |
+
This work is licensed under
|
226 |
+
<a href="https://creativecommons.org/licenses/by-sa/4.0/?ref=chooser-v1" target="_blank" rel="license noopener noreferrer" style="display:inline-block;">
|
227 |
+
CC BY-SA 4.0
|
228 |
+
</a>
|
229 |
+
<img style="display:inline-block;height:22px!important;margin-left:3px;vertical-align:text-bottom;" src="https://mirrors.creativecommons.org/presskit/icons/cc.svg?ref=chooser-v1" alt="">
|
230 |
+
<img style="display:inline-block;height:22px!important;margin-left:3px;vertical-align:text-bottom;" src="https://mirrors.creativecommons.org/presskit/icons/by.svg?ref=chooser-v1" alt="">
|
231 |
+
<img style="display:inline-block;height:22px!important;margin-left:3px;vertical-align:text-bottom;" src="https://mirrors.creativecommons.org/presskit/icons/sa.svg?ref=chooser-v1" alt="">
|
232 |
+
</p>"""
|
{src → data}/electricity_mix.csv
RENAMED
@@ -1,4 +1,4 @@
|
|
1 |
-
name,unit,source,WOR,EEE,ZWE,ZMB,ZAF,YEM,VNM,VEN,UZB,URY,USA,UKR,TZA,TWN,TTO,TUR,TUN,TKM,TJK,THA,TGO,SYR,SLV,SEN,SVK,SVN,SGP,SWE,SDN,SAU,RUS,SCG,ROU,QAT,PRY,PRT,POL,PAK,PHL,PER,PAN,OMN,NZL,NPL,NOR,NLD,NIC,NGA,NAM,MOZ,MYS,MEX,MLT,MNG,MMR,MKD,MDA,MAR,LBY,LVA,LUX,LTU,LKA,LBN,KAZ,KWT,KOR,PRK,KHM,KGZ,KEN,JPN,JOR,JAM,ITA,ISL,IRN,IRQ,IND,ISR,IRL,IDN,HUN,HTI,HRV,HND,HKG,GTM,GRC,GIB,GHA,GEO,GBR,GAB,FRA,FIN,ETH,ESP,ERI,EGY,EST,ECU,DZA,DOM,DNK,DEU,CZE,CYP,CUB,CRI,COL,CHN,CMR,CHL,CIV,CHE,COG,COD,CAN,BLR,BWA,BRA,BOL,BRN,BEN,BHR,BGR,BEL,BGD,BIH,AZE,AUS,AUT,ARG,AGO,ANT,ARM,ALB,ARE
|
2 |
-
adpe,kg éq. Sb,ADEME Base IMPACTS ®,0.0000000737708,0.0000000642317,0.000000109502,0.000000162193,0.0000000862445,0.0000000163908,0.0000000945573,0.000000112811,0.000000103681,0.000000104586,0.0000000985548,0.0000000647907,0.000000132261,0.0000000578088,0.000000064552,0.0000000749765,0.0000000177021,0.000000131822,0.000000152621,0.0000000569593,0.000000134255,0.0000000268396,0.0000000472135,0.0000000470662,0.0000000606109,0.0000000992283,0.0000000198459,0.0000000777062,0.0000000955701,0.0000000134206,0.0000000960312,0.000000132772,0.0000000981761,0.00000001324,0.000000149181,0.0000000341863,0.000000101946,0.0000000842952,0.0000000595304,0.0000000952688,0.0000000790553,0.0000000374073,0.0000000720474,0.000000238273,0.000000127486,0.0000000329318,0.0000000414983,0.0000000621,0.000000128285,0.000000148382,0.000000044938,0.0000000578358,0.000000049475,0.000000176361,0.000000152699,0.000000119873,0.000000110674,0.0000000641089,0.0000000206592,0.000000153757,0.000000105692,0.0000000294596,0.0000000986932,0.0000000182134,0.000000135386,0.0000000141168,0.0000000518017,0.000000117457,0.0000000319202,0.000000181827,0.0000000958533,0.0000000596578,0.0000000147031,0.0000000196047,0.00000005439,0.0000000781905,0.0000000220304,0.0000000404306,0.000000100099,0.0000000610194,0.0000000219257,0.0000000610451,0.0000000644587,0.0000000937057,0.000000153989,0.0000000649373,0.0000000816213,0.0000000803251,0.0000000691645,0.0000000286211,0.000000156003,0.000000137999,0.0000000370973,0.000000113843,0.0000000485798,0.0000000805114,0.000000174161,0.0000000518326,0.0000000512406,0.000000033925,0.0000000990171,0.000000127168,0.0000000216438,0.0000000429285,0.0000000157411,0.0000000878733,0.0000000817565,0.0000000448771,0.0000000299542,0.0000000863908,0.000000122031,0.0000000851552,0.000000146313,0.000000105851,0.0000000949004,0.000000100467,0.000000265575,0.000000174647,0.0000000993179,0.0000000840478,0.0000000866014,0.00000010962,0.0000000969793,0.0000000185641,0.0000000239702,0.0000000135014,0.0000000823611,0.0000000337201,0.0000000394158,0.000000148007,0.000000092567,0.0000000790846,0.000000141124,0.0000000768612,0.000000124074,0.0000000449103,0.0000000854245,0.000000229556,0.0000000141548
|
3 |
-
pe,MJ,ADPf / (1-%renewable_energy),9.988,12.873,16.122,1.798,11.732,16.250,11.238,15.163,17.367,107.570,11.358,12.936,9.305,11.439,14.289,16.150,12.902,23.300,19.165,10.414,21.978,16.989,13.012,14.516,11.680,12.146,10.477,11.026,29.629,14.058,13.200,14.242,15.585,11.916,0.020,14.153,13.178,16.175,11.120,8.211,16.364,22.306,24.731,0.396,4.952,8.511,24.696,11.279,468.150,0.206,12.268,11.775,19.374,15.114,14.132,19.120,18.429,11.702,19.116,8.249,10.128,21.043,12.116,12.341,13.260,12.753,10.199,32.793,34.655,15.380,68.996,10.718,13.677,14.799,12.656,0.013,15.022,20.372,20.363,10.023,10.706,11.603,11.784,20.167,18.548,15.762,,14.340,14.487,,10.097,10.425,13.579,28.341,11.289,11.275,36.133,12.090,13.289,10.195,16.334,20.908,16.376,12.412,16.824,16.260,12.517,13.118,17.317,45.996,7.312,14.119,10.807,11.348,14.783,11.782,34.147,0.097,11.987,13.194,19.642,9.031,11.587,15.689,14.337,14.036,14.375,10.776,12.935,21.705,12.831,16.908,11.036,10.049,16.972,,13.380,0.201,19.032
|
4 |
gwp,kg éq. CO2,ADEME Base IMPACTS ®,0.590478,0.509427,0.842811,0.0141304,1.17562,1.06777,0.555572,0.497373,0.81178,0.296953,0.67978,0.646745,0.475635,0.845351,0.933059,0.706988,0.80722,1.38296,0.0426743,0.646174,0.545455,1.08778,0.473128,1.1195,0.309341,0.498523,0.655825,0.0464664,1.12472,0.913677,0.66131,1.07808,0.664245,0.722125,0.241601,0.571172,1.15075,0.748727,0.761317,0.284364,0.53403,1.41292,0.293397,0.0841323,0.023754,0.544803,0.941626,0.693123,0.357253,0.00880732,0.832206,0.739214,1.31149,1.47192,0.48193,1.24074,1.04213,0.933694,1.35361,0.234273,0.490016,0.154229,0.709185,0.883627,1.128,0.885084,0.599585,0.797361,1.41054,0.156039,0.589603,0.540891,0.781372,1.07345,0.621329,0.0194609,0.930385,1.48728,1.58299,0.901842,0.648118,0.875394,0.541558,1.3858,0.535759,0.692837,0.95888,0.645801,1.13127,0.977477,0.540126,0.132046,0.602137,0.732511,0.0813225,0.322068,0.251299,0.467803,1.13153,0.587775,1.51492,0.627714,1.02318,0.909252,0.633534,0.657374,0.799077,0.978041,1.28325,0.224471,0.214014,1.05738,0.456622,0.574415,0.928583,0.0448568,0.904053,0.0613102,0.238191,0.795697,2.12572,0.278647,0.585131,0.997577,1.19128,0.804567,0.827087,0.256537,0.795168,1.56025,0.726126,1.12326,0.245573,0.476811,0.412014,1.13161,0.252002,0.0207635,1.09088
|
|
|
1 |
+
name,unit,source,WOR,EEE,ZWE,ZMB,ZAF,YEM,VNM,VEN,UZB,URY,USA,UKR,TZA,TWN,TTO,TUR,TUN,TKM,TJK,THA,TGO,SYR,SLV,SEN,SVK,SVN,SGP,SWE,SDN,SAU,RUS,SCG,ROU,QAT,PRY,PRT,POL,PAK,PHL,PER,PAN,OMN,NZL,NPL,NOR,NLD,NIC,NGA,NAM,MOZ,MYS,MEX,MLT,MNG,MMR,MKD,MDA,MAR,LBY,LVA,LUX,LTU,LKA,LBN,KAZ,KWT,KOR,PRK,KHM,KGZ,KEN,JPN,JOR,JAM,ITA,ISL,IRN,IRQ,IND,ISR,IRL,IDN,HUN,HTI,HRV,HND,HKG,GTM,GRC,GIB,GHA,GEO,GBR,GAB,FRA,FIN,ETH,ESP,ERI,EGY,EST,ECU,DZA,DOM,DNK,DEU,CZE,CYP,CUB,CRI,COL,CHN,CMR,CHL,CIV,CHE,COG,COD,CAN,BLR,BWA,BRA,BOL,BRN,BEN,BHR,BGR,BEL,BGD,BIH,AZE,AUS,AUT,ARG,AGO,ANT,ARM,ALB,ARE
|
2 |
+
adpe,kg éq. Sb,ADEME Base IMPACTS ®,0.0000000737708,0.0000000642317,0.000000109502,0.000000162193,0.0000000862445,0.0000000163908,0.0000000945573,0.000000112811,0.000000103681,0.000000104586,0.0000000985548,0.0000000647907,0.000000132261,0.0000000578088,0.000000064552,0.0000000749765,0.0000000177021,0.000000131822,0.000000152621,0.0000000569593,0.000000134255,0.0000000268396,0.0000000472135,0.0000000470662,0.0000000606109,0.0000000992283,0.0000000198459,0.0000000777062,0.0000000955701,0.0000000134206,0.0000000960312,0.000000132772,0.0000000981761,0.00000001324,0.000000149181,0.0000000341863,0.000000101946,0.0000000842952,0.0000000595304,0.0000000952688,0.0000000790553,0.0000000374073,0.0000000720474,0.000000238273,0.000000127486,0.0000000329318,0.0000000414983,0.0000000621,0.000000128285,0.000000148382,0.000000044938,0.0000000578358,0.000000049475,0.000000176361,0.000000152699,0.000000119873,0.000000110674,0.0000000641089,0.0000000206592,0.000000153757,0.000000105692,0.0000000294596,0.0000000986932,0.0000000182134,0.000000135386,0.0000000141168,0.0000000518017,0.000000117457,0.0000000319202,0.000000181827,0.0000000958533,0.0000000596578,0.0000000147031,0.0000000196047,0.00000005439,0.0000000781905,0.0000000220304,0.0000000404306,0.000000100099,0.0000000610194,0.0000000219257,0.0000000610451,0.0000000644587,0.0000000937057,0.000000153989,0.0000000649373,0.0000000816213,0.0000000803251,0.0000000691645,0.0000000286211,0.000000156003,0.000000137999,0.0000000370973,0.000000113843,0.0000000485798,0.0000000805114,0.000000174161,0.0000000518326,0.0000000512406,0.000000033925,0.0000000990171,0.000000127168,0.0000000216438,0.0000000429285,0.0000000157411,0.0000000878733,0.0000000817565,0.0000000448771,0.0000000299542,0.0000000863908,0.000000122031,0.0000000851552,0.000000146313,0.000000105851,0.0000000949004,0.000000100467,0.000000265575,0.000000174647,0.0000000993179,0.0000000840478,0.0000000866014,0.00000010962,0.0000000969793,0.0000000185641,0.0000000239702,0.0000000135014,0.0000000823611,0.0000000337201,0.0000000394158,0.000000148007,0.000000092567,0.0000000790846,0.000000141124,0.0000000768612,0.000000124074,0.0000000449103,0.0000000854245,0.000000229556,0.0000000141548
|
3 |
+
pe,MJ,ADPf / (1-%renewable_energy),9.988,12.873,16.122,1.798,11.732,16.250,11.238,15.163,17.367,107.570,11.358,12.936,9.305,11.439,14.289,16.150,12.902,23.300,19.165,10.414,21.978,16.989,13.012,14.516,11.680,12.146,10.477,11.026,29.629,14.058,13.200,14.242,15.585,11.916,0.020,14.153,13.178,16.175,11.120,8.211,16.364,22.306,24.731,0.396,4.952,8.511,24.696,11.279,468.150,0.206,12.268,11.775,19.374,15.114,14.132,19.120,18.429,11.702,19.116,8.249,10.128,21.043,12.116,12.341,13.260,12.753,10.199,32.793,34.655,15.380,68.996,10.718,13.677,14.799,12.656,0.013,15.022,20.372,20.363,10.023,10.706,11.603,11.784,20.167,18.548,15.762,,14.340,14.487,,10.097,10.425,13.579,28.341,11.289,11.275,36.133,12.090,13.289,10.195,16.334,20.908,16.376,12.412,16.824,16.260,12.517,13.118,17.317,45.996,7.312,14.119,10.807,11.348,14.783,11.782,34.147,0.097,11.987,13.194,19.642,9.031,11.587,15.689,14.337,14.036,14.375,10.776,12.935,21.705,12.831,16.908,11.036,10.049,16.972,,13.380,0.201,19.032
|
4 |
gwp,kg éq. CO2,ADEME Base IMPACTS ®,0.590478,0.509427,0.842811,0.0141304,1.17562,1.06777,0.555572,0.497373,0.81178,0.296953,0.67978,0.646745,0.475635,0.845351,0.933059,0.706988,0.80722,1.38296,0.0426743,0.646174,0.545455,1.08778,0.473128,1.1195,0.309341,0.498523,0.655825,0.0464664,1.12472,0.913677,0.66131,1.07808,0.664245,0.722125,0.241601,0.571172,1.15075,0.748727,0.761317,0.284364,0.53403,1.41292,0.293397,0.0841323,0.023754,0.544803,0.941626,0.693123,0.357253,0.00880732,0.832206,0.739214,1.31149,1.47192,0.48193,1.24074,1.04213,0.933694,1.35361,0.234273,0.490016,0.154229,0.709185,0.883627,1.128,0.885084,0.599585,0.797361,1.41054,0.156039,0.589603,0.540891,0.781372,1.07345,0.621329,0.0194609,0.930385,1.48728,1.58299,0.901842,0.648118,0.875394,0.541558,1.3858,0.535759,0.692837,0.95888,0.645801,1.13127,0.977477,0.540126,0.132046,0.602137,0.732511,0.0813225,0.322068,0.251299,0.467803,1.13153,0.587775,1.51492,0.627714,1.02318,0.909252,0.633534,0.657374,0.799077,0.978041,1.28325,0.224471,0.214014,1.05738,0.456622,0.574415,0.928583,0.0448568,0.904053,0.0613102,0.238191,0.795697,2.12572,0.278647,0.585131,0.997577,1.19128,0.804567,0.827087,0.256537,0.795168,1.56025,0.726126,1.12326,0.245573,0.476811,0.412014,1.13161,0.252002,0.0207635,1.09088
|
electricity_mix.py
ADDED
@@ -0,0 +1,175 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from csv import DictReader
|
2 |
+
import pandas as pd
|
3 |
+
|
4 |
+
PATH = "src/data/electricity_mix.csv"
|
5 |
+
|
6 |
+
COUNTRY_CODES = [
|
7 |
+
("🌎 World", "WOR"),
|
8 |
+
("🇪🇺 Europe", "EEE"),
|
9 |
+
("🇿🇼 Zimbabwe", "ZWE"),
|
10 |
+
("🇿🇲 Zambia", "ZMB"),
|
11 |
+
("🇿🇦 South Africa", "ZAF"),
|
12 |
+
("🇾🇪 Yemen", "YEM"),
|
13 |
+
("🇻🇳 Vietnam", "VNM"),
|
14 |
+
("🇻🇪 Venezuela", "VEN"),
|
15 |
+
("🇺🇿 Uzbekistan", "UZB"),
|
16 |
+
("🇺🇾 Uruguay", "URY"),
|
17 |
+
("🇺🇸 United States", "USA"),
|
18 |
+
("🇺🇦 Ukraine", "UKR"),
|
19 |
+
("🇹🇿 Tanzania", "TZA"),
|
20 |
+
("🇹🇼 Taiwan", "TWN"),
|
21 |
+
("🇹🇹 Trinidad and Tobago", "TTO"),
|
22 |
+
("🇹🇷 Turkey", "TUR"),
|
23 |
+
("🇹🇳 Tunisia", "TUN"),
|
24 |
+
("🇹🇲 Turkmenistan", "TKM"),
|
25 |
+
("🇹🇯 Tajikistan", "TJK"),
|
26 |
+
("🇹🇭 Thailand", "THA"),
|
27 |
+
("🇹🇬 Togo", "TGO"),
|
28 |
+
("🇸🇾 Syrian Arab Republic", "SYR"),
|
29 |
+
("🇸🇻 El Salvador", "SLV"),
|
30 |
+
("🇸🇳 Senegal", "SEN"),
|
31 |
+
("🇸🇰 Slovak Republic", "SVK"),
|
32 |
+
("🇸🇮 Slovenia", "SVN"),
|
33 |
+
("🇸🇬 Singapore", "SGP"),
|
34 |
+
("🇸🇪 Sweden", "SWE"),
|
35 |
+
("🇸🇩 Sudan", "SDN"),
|
36 |
+
("🇸🇦 Saudi Arabia", "SAU"),
|
37 |
+
("🇷🇺 Russian Federation", "RUS"),
|
38 |
+
("🇷🇸 Serbia and Montenegro", "SCG"),
|
39 |
+
("🇷🇴 Romania", "ROU"),
|
40 |
+
("🇶🇦 Qatar", "QAT"),
|
41 |
+
("🇵🇾 Paraguay", "PRY"),
|
42 |
+
("🇵🇹 Portugal", "PRT"),
|
43 |
+
("🇵🇱 Poland", "POL"),
|
44 |
+
("🇵🇰 Pakistan", "PAK"),
|
45 |
+
("🇵🇭 Philippines", "PHL"),
|
46 |
+
("🇵🇪 Peru", "PER"),
|
47 |
+
("🇵🇦 Panama", "PAN"),
|
48 |
+
("🇴🇲 Oman", "OMN"),
|
49 |
+
("🇳🇿 New Zealand", "NZL"),
|
50 |
+
("🇳🇵 Nepal", "NPL"),
|
51 |
+
("🇳🇴 Norway", "NOR"),
|
52 |
+
("🇳🇱 Netherlands", "NLD"),
|
53 |
+
("🇳🇮 Nicaragua", "NIC"),
|
54 |
+
("🇳🇬 Nigeria", "NGA"),
|
55 |
+
("🇳🇦 Namibia", "NAM"),
|
56 |
+
("🇲🇿 Mozambique", "MOZ"),
|
57 |
+
("🇲🇾 Malaysia", "MYS"),
|
58 |
+
("🇲🇽 Mexico", "MEX"),
|
59 |
+
("🇲🇹 Malta", "MLT"),
|
60 |
+
("🇲🇳 Mongolia", "MNG"),
|
61 |
+
("🇲🇲 Myanmar", "MMR"),
|
62 |
+
("🇲🇰 North Macedonia", "MKD"),
|
63 |
+
("🇲🇩 Moldova", "MDA"),
|
64 |
+
("🇲🇦 Morocco", "MAR"),
|
65 |
+
("🇱🇾 Libya", "LBY"),
|
66 |
+
("🇱🇻 Latvia", "LVA"),
|
67 |
+
("🇱🇺 Luxembourg", "LUX"),
|
68 |
+
("🇱🇹 Lithuania", "LTU"),
|
69 |
+
("🇱🇰 Sri Lanka", "LKA"),
|
70 |
+
("🇱🇧 Lebanon", "LBN"),
|
71 |
+
("🇰🇿 Kazakhstan", "KAZ"),
|
72 |
+
("🇰🇼 Kuwait", "KWT"),
|
73 |
+
("🇰🇷 South Korea", "KOR"),
|
74 |
+
("🇰🇵 North Korea", "PRK"),
|
75 |
+
("🇰🇭 Cambodia", "KHM"),
|
76 |
+
("🇰🇬 Kyrgyz Republic", "KGZ"),
|
77 |
+
("🇰🇪 Kenya", "KEN"),
|
78 |
+
("🇯🇵 Japan", "JPN"),
|
79 |
+
("🇯🇴 Jordan", "JOR"),
|
80 |
+
("🇯🇲 Jamaica", "JAM"),
|
81 |
+
("🇮🇹 Italy", "ITA"),
|
82 |
+
("🇮🇸 Iceland", "ISL"),
|
83 |
+
("🇮🇷 Iran", "IRN"),
|
84 |
+
("🇮🇶 Iraq", "IRQ"),
|
85 |
+
("🇮🇳 India", "IND"),
|
86 |
+
("🇮🇱 Israel", "ISR"),
|
87 |
+
("🇮🇪 Ireland", "IRL"),
|
88 |
+
("🇮🇩 Indonesia", "IDN"),
|
89 |
+
("🇭🇺 Hungary", "HUN"),
|
90 |
+
("🇭🇹 Haiti", "HTI"),
|
91 |
+
("🇭🇷 Croatia", "HRV"),
|
92 |
+
("🇭🇳 Honduras", "HND"),
|
93 |
+
("🇭🇰 Hong Kong", "HKG"),
|
94 |
+
("🇬🇹 Guatemala", "GTM"),
|
95 |
+
("🇬🇷 Greece", "GRC"),
|
96 |
+
("🇬🇮 Gibraltar", "GIB"),
|
97 |
+
("🇬🇭 Ghana", "GHA"),
|
98 |
+
("🇬🇪 Georgia", "GEO"),
|
99 |
+
("🇬🇧 United Kingdom", "GBR"),
|
100 |
+
("🇬🇦 Gabon", "GAB"),
|
101 |
+
("🇫🇷 France", "FRA"),
|
102 |
+
("🇫🇮 Finland", "FIN"),
|
103 |
+
("🇪🇹 Ethiopia", "ETH"),
|
104 |
+
("🇪🇸 Spain", "ESP"),
|
105 |
+
("🇪🇷 Eritrea", "ERI"),
|
106 |
+
("🇪🇬 Egypt", "EGY"),
|
107 |
+
("🇪🇪 Estonia", "EST"),
|
108 |
+
("🇪🇨 Ecuador", "ECU"),
|
109 |
+
("🇩🇿 Algeria", "DZA"),
|
110 |
+
("🇩🇴 Dominican Republic", "DOM"),
|
111 |
+
("🇩🇰 Denmark", "DNK"),
|
112 |
+
("🇩🇪 Germany", "DEU"),
|
113 |
+
("🇨🇿 Czech Republic", "CZE"),
|
114 |
+
("🇨🇾 Cyprus", "CYP"),
|
115 |
+
("🇨🇺 Cuba", "CUB"),
|
116 |
+
("🇨🇷 Costa Rica", "CRI"),
|
117 |
+
("🇨🇴 Colombia", "COL"),
|
118 |
+
("🇨🇳 China", "CHN"),
|
119 |
+
("🇨🇲 Cameroon", "CMR"),
|
120 |
+
("🇨🇱 Chile", "CHL"),
|
121 |
+
("🇨🇮 Cote d'Ivoire", "CIV"),
|
122 |
+
("🇨🇭 Switzerland", "CHE"),
|
123 |
+
("🇨🇬 Congo", "COG"),
|
124 |
+
("🇨🇩 Democratic Republic of the Congo", "COD"),
|
125 |
+
("🇨🇦 Canada", "CAN"),
|
126 |
+
("🇧🇾 Belarus", "BLR"),
|
127 |
+
("🇧🇼 Botswana", "BWA"),
|
128 |
+
("🇧🇷 Brazil", "BRA"),
|
129 |
+
("🇧🇴 Bolivia", "BOL"),
|
130 |
+
("🇧🇳 Brunei", "BRN"),
|
131 |
+
("🇧🇯 Benin", "BEN"),
|
132 |
+
("🇧🇭 Bahrain", "BHR"),
|
133 |
+
("🇧🇬 Bulgaria", "BGR"),
|
134 |
+
("🇧🇪 Belgium", "BEL"),
|
135 |
+
("🇧🇩 Bangladesh", "BGD"),
|
136 |
+
("🇧🇦 Bosnia and Herzegovina", "BIH"),
|
137 |
+
("🇦🇿 Azerbaijan", "AZE"),
|
138 |
+
("🇦🇺 Australia", "AUS"),
|
139 |
+
("🇦🇹 Austria", "AUT"),
|
140 |
+
("🇦🇷 Argentina", "ARG"),
|
141 |
+
("🇦🇴 Angola", "AGO"),
|
142 |
+
("🇦 Netherlands Antilles", "ANT"),
|
143 |
+
("🇦🇲 Armenia", "ARM"),
|
144 |
+
("🇦🇱 Albania", "ALB"),
|
145 |
+
("🇦🇪 United Arab Emirates", "ARE")
|
146 |
+
]
|
147 |
+
|
148 |
+
|
149 |
+
def find_electricity_mix(code: str):
|
150 |
+
# TODO: Maybe more optimal to construct database at the beginning of the app
|
151 |
+
# in the same fashion as find_model
|
152 |
+
res = []
|
153 |
+
with open(PATH) as fd:
|
154 |
+
csv = DictReader(fd)
|
155 |
+
for row in csv:
|
156 |
+
res += [float(row[code])]
|
157 |
+
return res
|
158 |
+
|
159 |
+
def dataframe_electricity_mix(countries: list):
|
160 |
+
|
161 |
+
df = pd.read_csv('src/data/electricity_mix.csv')
|
162 |
+
df['name_unit'] = df['name'] + ' (' + df['unit'] + ')'
|
163 |
+
df = df[['name_unit'] + [x[1] for x in COUNTRY_CODES if x[0] in countries]]
|
164 |
+
|
165 |
+
df_melted = df.melt(
|
166 |
+
id_vars=['name_unit'],
|
167 |
+
value_vars=[x[1] for x in COUNTRY_CODES if x[0] in countries],
|
168 |
+
var_name='country',
|
169 |
+
value_name='value')
|
170 |
+
|
171 |
+
df = df_melted.pivot(columns='name_unit',
|
172 |
+
index='country',
|
173 |
+
values='value')
|
174 |
+
|
175 |
+
return df
|
expert.py
ADDED
@@ -0,0 +1,156 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import streamlit as st
|
2 |
+
import pandas as pd
|
3 |
+
from ecologits.impacts.llm import compute_llm_impacts
|
4 |
+
|
5 |
+
from src.utils import format_impacts, average_range_impacts, format_impacts_expert, model_active_params_fn, model_total_params_fn
|
6 |
+
from src.impacts import display_impacts
|
7 |
+
#from src.constants import PROVIDERS, MODELS
|
8 |
+
from src.electricity_mix import COUNTRY_CODES, find_electricity_mix, dataframe_electricity_mix
|
9 |
+
from ecologits.model_repository import models
|
10 |
+
|
11 |
+
import plotly.express as px
|
12 |
+
|
13 |
+
def reset_model():
|
14 |
+
model = 'CUSTOM'
|
15 |
+
|
16 |
+
def expert_mode():
|
17 |
+
|
18 |
+
st.markdown("### 🤓 Expert mode")
|
19 |
+
|
20 |
+
with st.container(border = True):
|
21 |
+
|
22 |
+
########## Model info ##########
|
23 |
+
|
24 |
+
# col1, col2, col3 = st.columns(3)
|
25 |
+
|
26 |
+
# with col1:
|
27 |
+
# provider = st.selectbox(label = 'Provider expert',
|
28 |
+
# options = [x[0] for x in PROVIDERS],
|
29 |
+
# index = 0)
|
30 |
+
# provider = [x[1] for x in PROVIDERS if x[0] == provider][0]
|
31 |
+
# if 'huggingface_hub' in provider:
|
32 |
+
# provider = 'huggingface_hub'
|
33 |
+
|
34 |
+
# with col2:
|
35 |
+
# model = st.selectbox('Model expert', [x[0] for x in MODELS if provider in x[1]])
|
36 |
+
# model = [x[1] for x in MODELS if x[0] == model][0].split('/', 1)[1]
|
37 |
+
|
38 |
+
########## Model parameters ##########
|
39 |
+
|
40 |
+
col11, col22, col33 = st.columns(3)
|
41 |
+
|
42 |
+
with col11:
|
43 |
+
# st.write(provider, model)
|
44 |
+
# st.write(models.find_model(provider, model))
|
45 |
+
# st.write(model_active_params_fn(provider, model, 45))
|
46 |
+
active_params = st.number_input('Active parameters (B)', 0, None, 45)
|
47 |
+
|
48 |
+
with col22:
|
49 |
+
total_params = st.number_input('Total parameters (B)', 0, None, 45)
|
50 |
+
|
51 |
+
with col33:
|
52 |
+
output_tokens = st.number_input('Output completion tokens', 100)
|
53 |
+
|
54 |
+
########## Electricity mix ##########
|
55 |
+
|
56 |
+
location = st.selectbox('Location', [x[0] for x in COUNTRY_CODES])
|
57 |
+
|
58 |
+
col4, col5, col6 = st.columns(3)
|
59 |
+
|
60 |
+
with col4:
|
61 |
+
mix_gwp = st.number_input('Electricity mix - GHG emissions [kgCO2eq / kWh]', find_electricity_mix([x[1] for x in COUNTRY_CODES if x[0] ==location][0])[2], format="%0.6f")
|
62 |
+
#disp_ranges = st.toggle('Display impact ranges', False)
|
63 |
+
with col5:
|
64 |
+
mix_adpe = st.number_input('Electricity mix - Abiotic resources [kgSbeq / kWh]', find_electricity_mix([x[1] for x in COUNTRY_CODES if x[0] ==location][0])[0], format="%0.13f")
|
65 |
+
with col6:
|
66 |
+
mix_pe = st.number_input('Electricity mix - Primary energy [MJ / kWh]', find_electricity_mix([x[1] for x in COUNTRY_CODES if x[0] ==location][0])[1], format="%0.3f")
|
67 |
+
|
68 |
+
impacts = compute_llm_impacts(model_active_parameter_count=active_params,
|
69 |
+
model_total_parameter_count=total_params,
|
70 |
+
output_token_count=output_tokens,
|
71 |
+
request_latency=100000,
|
72 |
+
if_electricity_mix_gwp=mix_gwp,
|
73 |
+
if_electricity_mix_adpe=mix_adpe,
|
74 |
+
if_electricity_mix_pe=mix_pe
|
75 |
+
)
|
76 |
+
|
77 |
+
impacts, usage, embodied = format_impacts(impacts)
|
78 |
+
|
79 |
+
with st.container(border = True):
|
80 |
+
|
81 |
+
st.markdown('<h3 align="center">Environmental Impacts</h2>', unsafe_allow_html = True)
|
82 |
+
|
83 |
+
display_impacts(impacts)
|
84 |
+
|
85 |
+
with st.expander('⚖️ Usage vs Embodied'):
|
86 |
+
|
87 |
+
st.markdown('<h3 align="center">Embodied vs Usage comparison</h2>', unsafe_allow_html = True)
|
88 |
+
|
89 |
+
st.markdown('The usage impacts account for the electricity consumption of the model while the embodied impacts account for resource extraction (e.g., minerals and metals), manufacturing, and transportation of the hardware.')
|
90 |
+
|
91 |
+
col_ghg_comparison, col_adpe_comparison, col_pe_comparison = st.columns(3)
|
92 |
+
|
93 |
+
with col_ghg_comparison:
|
94 |
+
fig_gwp = px.pie(
|
95 |
+
values = [average_range_impacts(usage.gwp.value), average_range_impacts(embodied.gwp.value)],
|
96 |
+
names = ['usage', 'embodied'],
|
97 |
+
title = 'GHG emissions',
|
98 |
+
color_discrete_sequence=["#636EFA", "#00CC96"],
|
99 |
+
width = 100
|
100 |
+
)
|
101 |
+
fig_gwp.update_layout(showlegend=False, title_x=0.5)
|
102 |
+
|
103 |
+
st.plotly_chart(fig_gwp)
|
104 |
+
|
105 |
+
with col_adpe_comparison:
|
106 |
+
fig_adpe = px.pie(
|
107 |
+
values = [average_range_impacts(usage.adpe.value), average_range_impacts(embodied.adpe.value)],
|
108 |
+
names = ['usage', 'embodied'],
|
109 |
+
title = 'Abiotic depletion',
|
110 |
+
color_discrete_sequence=["#00CC96","#636EFA"],
|
111 |
+
width = 100)
|
112 |
+
fig_adpe.update_layout(
|
113 |
+
showlegend=True,
|
114 |
+
legend=dict(yanchor="bottom", x = 0.35, y = -0.1),
|
115 |
+
title_x=0.5)
|
116 |
+
|
117 |
+
st.plotly_chart(fig_adpe)
|
118 |
+
|
119 |
+
with col_pe_comparison:
|
120 |
+
fig_pe = px.pie(
|
121 |
+
values = [average_range_impacts(usage.pe.value), average_range_impacts(embodied.pe.value)],
|
122 |
+
names = ['usage', 'embodied'],
|
123 |
+
title = 'Primary energy',
|
124 |
+
color_discrete_sequence=["#636EFA", "#00CC96"],
|
125 |
+
width = 100)
|
126 |
+
fig_pe.update_layout(showlegend=False, title_x=0.5)
|
127 |
+
|
128 |
+
st.plotly_chart(fig_pe)
|
129 |
+
|
130 |
+
with st.expander('🌍️ Location impact'):
|
131 |
+
|
132 |
+
st.markdown('<h4 align="center">How can location impact the footprint ?</h4>', unsafe_allow_html = True)
|
133 |
+
|
134 |
+
countries_to_compare = st.multiselect(
|
135 |
+
label = 'Countries to compare',
|
136 |
+
options = [x[0] for x in COUNTRY_CODES],
|
137 |
+
default = ["🇫🇷 France", "🇺🇸 United States", "🇨🇳 China"]
|
138 |
+
)
|
139 |
+
|
140 |
+
try:
|
141 |
+
|
142 |
+
df = dataframe_electricity_mix(countries_to_compare)
|
143 |
+
|
144 |
+
impact_type = st.selectbox(
|
145 |
+
label='Select an impact type to compare',
|
146 |
+
options=[x for x in df.columns if x!='country'],
|
147 |
+
index=1)
|
148 |
+
|
149 |
+
df.sort_values(by = impact_type, inplace = True)
|
150 |
+
|
151 |
+
fig_2 = px.bar(df, x = df.index, y = impact_type, text = impact_type, color = impact_type)
|
152 |
+
st.plotly_chart(fig_2)
|
153 |
+
|
154 |
+
except:
|
155 |
+
|
156 |
+
st.warning("Can't display chart with no values.")
|
impacts.py
ADDED
@@ -0,0 +1,116 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import streamlit as st
|
2 |
+
import ecologits
|
3 |
+
from src.utils import (
|
4 |
+
format_energy_eq_electric_vehicle,
|
5 |
+
format_energy_eq_electricity_consumption_ireland,
|
6 |
+
format_energy_eq_electricity_production,
|
7 |
+
format_energy_eq_physical_activity,
|
8 |
+
format_gwp_eq_airplane_paris_nyc,
|
9 |
+
format_gwp_eq_streaming,
|
10 |
+
PhysicalActivity,
|
11 |
+
EnergyProduction
|
12 |
+
)
|
13 |
+
|
14 |
+
############################################################################################################
|
15 |
+
|
16 |
+
def get_impacts(model, active_params, total_params, mix_ghg, mix_adpe, mix_pe):
|
17 |
+
|
18 |
+
return 1
|
19 |
+
|
20 |
+
############################################################################################################
|
21 |
+
|
22 |
+
|
23 |
+
def display_impacts(impacts):
|
24 |
+
|
25 |
+
st.divider()
|
26 |
+
|
27 |
+
col_energy, col_ghg, col_adpe, col_pe, col_water = st.columns(5)
|
28 |
+
|
29 |
+
with col_energy:
|
30 |
+
st.markdown('<h4 align="center">⚡️ Energy</h4>', unsafe_allow_html = True)
|
31 |
+
st.latex(f'\Large {impacts.energy.magnitude:.3g} \ \large {impacts.energy.units}')
|
32 |
+
st.markdown(f'<p align="center"><i>Evaluates the electricity consumption<i></p>', unsafe_allow_html = True)
|
33 |
+
|
34 |
+
with col_ghg:
|
35 |
+
st.markdown('<h4 align="center">🌍️ GHG Emissions</h4>', unsafe_allow_html = True)
|
36 |
+
st.latex(f'\Large {impacts.gwp.magnitude:.3g} \ \large {impacts.gwp.units}')
|
37 |
+
st.markdown(f'<p align="center"><i>Evaluates the effect on global warming<i></p>', unsafe_allow_html = True)
|
38 |
+
|
39 |
+
with col_adpe:
|
40 |
+
st.markdown('<h4 align="center">🪨 Abiotic Resources</h4>', unsafe_allow_html = True)
|
41 |
+
st.latex(f'\Large {impacts.adpe.magnitude:.3g} \ \large {impacts.adpe.units}')
|
42 |
+
st.markdown(f'<p align="center"><i>Evaluates the use of metals and minerals<i></p>', unsafe_allow_html = True)
|
43 |
+
|
44 |
+
with col_pe:
|
45 |
+
st.markdown('<h4 align="center">⛽️ Primary Energy</h4>', unsafe_allow_html = True)
|
46 |
+
st.latex(f'\Large {impacts.pe.magnitude:.3g} \ \large {impacts.pe.units}')
|
47 |
+
st.markdown(f'<p align="center"><i>Evaluates the use of energy resources<i></p>', unsafe_allow_html = True)
|
48 |
+
|
49 |
+
with col_water:
|
50 |
+
st.markdown('<h4 align="center">🚰 Water</h4>', unsafe_allow_html = True)
|
51 |
+
st.latex('\Large Upcoming...')
|
52 |
+
st.markdown(f'<p align="center"><i>Evaluates the use of water<i></p>', unsafe_allow_html = True)
|
53 |
+
|
54 |
+
############################################################################################################
|
55 |
+
|
56 |
+
def display_equivalent(impacts):
|
57 |
+
|
58 |
+
st.divider()
|
59 |
+
|
60 |
+
ev_eq = format_energy_eq_electric_vehicle(impacts.energy)
|
61 |
+
|
62 |
+
streaming_eq = format_gwp_eq_streaming(impacts.gwp)
|
63 |
+
|
64 |
+
col1, col2, col3 = st.columns(3)
|
65 |
+
|
66 |
+
with col1:
|
67 |
+
physical_activity, distance = format_energy_eq_physical_activity(impacts.energy)
|
68 |
+
if physical_activity == PhysicalActivity.WALKING:
|
69 |
+
physical_activity = "🚶 " + physical_activity.capitalize()
|
70 |
+
if physical_activity == PhysicalActivity.RUNNING:
|
71 |
+
physical_activity = "🏃 " + physical_activity.capitalize()
|
72 |
+
|
73 |
+
st.markdown(f'<h4 align="center">{physical_activity}</h4>', unsafe_allow_html = True)
|
74 |
+
st.latex(f'\Large {distance.magnitude:.3g} \ \large {distance.units}')
|
75 |
+
st.markdown(f'<p align="center"><i>Based on energy consumption<i></p>', unsafe_allow_html = True)
|
76 |
+
|
77 |
+
with col2:
|
78 |
+
ev_eq = format_energy_eq_electric_vehicle(impacts.energy)
|
79 |
+
st.markdown(f'<h4 align="center">🔋 Electric Vehicle</h4>', unsafe_allow_html = True)
|
80 |
+
st.latex(f'\Large {ev_eq.magnitude:.3g} \ \large {ev_eq.units}')
|
81 |
+
st.markdown(f'<p align="center"><i>Based on energy consumption<i></p>', unsafe_allow_html = True)
|
82 |
+
|
83 |
+
with col3:
|
84 |
+
streaming_eq = format_gwp_eq_streaming(impacts.gwp)
|
85 |
+
st.markdown(f'<h4 align="center">⏯️ Streaming</h4>', unsafe_allow_html = True)
|
86 |
+
st.latex(f'\Large {streaming_eq.magnitude:.3g} \ \large {streaming_eq.units}')
|
87 |
+
st.markdown(f'<p align="center"><i>Based on GHG emissions<i></p>', unsafe_allow_html = True)
|
88 |
+
|
89 |
+
st.divider()
|
90 |
+
|
91 |
+
st.markdown('<h3 align="center">What if 1% of the planet does this request everyday for 1 year ?</h3>', unsafe_allow_html = True)
|
92 |
+
st.markdown('<p align="center">If this use case is largely deployed around the world, the equivalent impacts would be the impacts of this request x 1% of 8 billion people x 365 days in a year.</p>', unsafe_allow_html = True)
|
93 |
+
|
94 |
+
col4, col5, col6 = st.columns(3)
|
95 |
+
|
96 |
+
with col4:
|
97 |
+
|
98 |
+
electricity_production, count = format_energy_eq_electricity_production(impacts.energy)
|
99 |
+
if electricity_production == EnergyProduction.NUCLEAR:
|
100 |
+
emoji = "☢️"
|
101 |
+
name = "Nuclear power plants"
|
102 |
+
if electricity_production == EnergyProduction.WIND:
|
103 |
+
emoji = "💨️ "
|
104 |
+
name = "Wind turbines"
|
105 |
+
st.markdown(f'<h4 align="center">{emoji} {count.magnitude:.0f} {name} (yearly)</h4>', unsafe_allow_html = True)
|
106 |
+
st.markdown(f'<p align="center"><i>Based on energy consumption<i></p>', unsafe_allow_html = True)
|
107 |
+
|
108 |
+
with col5:
|
109 |
+
ireland_count = format_energy_eq_electricity_consumption_ireland(impacts.energy)
|
110 |
+
st.markdown(f'<h4 align="center">🇮🇪 {ireland_count.magnitude:.3f} x Ireland <span style="font-size: 12px">(yearly ⚡️ cons.)</span></h2></h4>', unsafe_allow_html = True)
|
111 |
+
st.markdown(f'<p align="center"><i>Based on energy consumption<i></p>', unsafe_allow_html = True)
|
112 |
+
|
113 |
+
with col6:
|
114 |
+
paris_nyc_airplane = format_gwp_eq_airplane_paris_nyc(impacts.gwp)
|
115 |
+
st.markdown(f'<h4 align="center">✈️ {round(paris_nyc_airplane.magnitude):,} Paris ↔ NYC</h4>', unsafe_allow_html = True)
|
116 |
+
st.markdown(f'<p align="center"><i>Based on GHG emissions<i></p>', unsafe_allow_html = True)
|
models.py
ADDED
@@ -0,0 +1,46 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import requests
|
2 |
+
import json
|
3 |
+
import pandas as pd
|
4 |
+
from src.constants import MODEL_REPOSITORY_URL
|
5 |
+
|
6 |
+
def clean_models_data(df):
|
7 |
+
|
8 |
+
dict_providers = {
|
9 |
+
'google': 'Google',
|
10 |
+
'mistralai': 'MistralAI',
|
11 |
+
'meta-llama': 'Meta',
|
12 |
+
'openai': 'OpenAI',
|
13 |
+
'anthropic': 'Anthropic',
|
14 |
+
'cohere': 'Cohere',
|
15 |
+
'microsoft': 'Microsoft',
|
16 |
+
'mistral-community': 'Mistral Community',
|
17 |
+
'databricks': 'Databricks'
|
18 |
+
}
|
19 |
+
|
20 |
+
df.drop('type', axis=1, inplace=True)
|
21 |
+
|
22 |
+
df.loc[df['name'].str.contains('/'), 'name_clean'] = df.loc[df['name'].str.contains('/'), 'name'].str.split('/').str[1]
|
23 |
+
df['name_clean'] = df['name_clean'].fillna(df['name'])
|
24 |
+
df['name_clean'] = df['name_clean'].replace({'-': ' '}, regex = True)
|
25 |
+
|
26 |
+
df.loc[df['provider'] == 'huggingface_hub', 'provider_clean'] = df.loc[df['provider'] == 'huggingface_hub', 'name'].str.split('/').str[0]
|
27 |
+
df['provider_clean'] = df['provider_clean'].fillna(df['provider'])
|
28 |
+
df['provider_clean'] = df['provider_clean'].replace(dict_providers, regex = True)
|
29 |
+
|
30 |
+
df['architecture_type'] = df['architecture'].apply(lambda x: x['type'])
|
31 |
+
df['architecture_parameters'] = df['architecture'].apply(lambda x: x['parameters'])
|
32 |
+
|
33 |
+
df['warnings'] = df['warnings'].apply(lambda x: ', '.join(x) if x else None).fillna('none')
|
34 |
+
df['warning_arch'] = df['warnings'].apply(lambda x: 'model-arch-not-released' in x)
|
35 |
+
df['warning_multi_modal'] = df['warnings'].apply(lambda x: 'model-arch-multimodal' in x)
|
36 |
+
|
37 |
+
return df[['provider', 'provider_clean', 'name', 'name_clean', 'architecture_type', 'architecture_parameters', 'warning_arch', 'warning_multi_modal']]
|
38 |
+
|
39 |
+
def load_models():
|
40 |
+
|
41 |
+
resp = requests.get(MODEL_REPOSITORY_URL)
|
42 |
+
data = json.loads(resp.text)
|
43 |
+
df = pd.DataFrame(data['models'])
|
44 |
+
|
45 |
+
return clean_models_data(df)
|
46 |
+
|
pyproject.toml
ADDED
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
[project]
|
2 |
+
name = "ecologits-calculator-streamlit"
|
3 |
+
version = "0.1.0"
|
4 |
+
description = "Add your description here"
|
5 |
+
readme = "README.md"
|
6 |
+
requires-python = ">=3.12"
|
7 |
+
dependencies = [
|
8 |
+
"ecologits>=0.6.1",
|
9 |
+
"pint>=0.24.4",
|
10 |
+
"plotly>=6.0.0",
|
11 |
+
"streamlit>=1.43.1",
|
12 |
+
]
|
requirements-dev.txt
DELETED
@@ -1,6 +0,0 @@
|
|
1 |
-
gradio
|
2 |
-
ecologits==0.5.1
|
3 |
-
pint
|
4 |
-
beautifulsoup4
|
5 |
-
requests
|
6 |
-
tiktoken
|
|
|
|
|
|
|
|
|
|
|
|
|
|
requirements.txt
CHANGED
@@ -1,5 +1,4 @@
|
|
1 |
-
|
|
|
2 |
pint
|
3 |
-
|
4 |
-
requests
|
5 |
-
tiktoken
|
|
|
1 |
+
streamlit
|
2 |
+
ecologits
|
3 |
pint
|
4 |
+
plotly
|
|
|
|
src/__init__.py
ADDED
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from .content import *
|
2 |
+
from .constants import *
|
3 |
+
from .expert import expert_mode
|
4 |
+
from .utils import *
|
5 |
+
from .calculator import calculator_mode
|
6 |
+
from .impacts import get_impacts, display_impacts
|
7 |
+
from .models import load_models
|
8 |
+
from .electricity_mix import *
|
src/__pycache__/__init__.cpython-312.pyc
ADDED
Binary file (489 Bytes). View file
|
|
src/__pycache__/calculator.cpython-312.pyc
ADDED
Binary file (4.67 kB). View file
|
|
src/__pycache__/constants.cpython-312.pyc
ADDED
Binary file (3.38 kB). View file
|
|
src/__pycache__/content.cpython-312.pyc
ADDED
Binary file (17 kB). View file
|
|
src/__pycache__/electricity_mix.cpython-312.pyc
ADDED
Binary file (5.73 kB). View file
|
|
src/__pycache__/expert.cpython-312.pyc
ADDED
Binary file (8.13 kB). View file
|
|
src/__pycache__/impacts.cpython-312.pyc
ADDED
Binary file (7.9 kB). View file
|
|
src/__pycache__/models.cpython-312.pyc
ADDED
Binary file (3.66 kB). View file
|
|
src/__pycache__/utils.cpython-312.pyc
ADDED
Binary file (12.9 kB). View file
|
|
src/assets.py
DELETED
@@ -1,17 +0,0 @@
|
|
1 |
-
custom_css = """
|
2 |
-
|
3 |
-
.descriptive-text span {
|
4 |
-
font-size: 16px !important;
|
5 |
-
}
|
6 |
-
|
7 |
-
|
8 |
-
.warning-box p {
|
9 |
-
background-color: #ff91001a;
|
10 |
-
border: 1px solid #f19637;
|
11 |
-
border-radius: 8px;
|
12 |
-
padding: 4px 8px;
|
13 |
-
margin: 4px 0px;
|
14 |
-
font-size: 14px !important;
|
15 |
-
font-weight: bold !important;
|
16 |
-
}
|
17 |
-
"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/calculator.py
ADDED
@@ -0,0 +1,67 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import streamlit as st
|
2 |
+
import pandas as pd
|
3 |
+
|
4 |
+
from ecologits.tracers.utils import llm_impacts
|
5 |
+
from src.impacts import get_impacts, display_impacts, display_equivalent
|
6 |
+
from src.utils import format_impacts
|
7 |
+
from src.content import WARNING_CLOSED_SOURCE, WARNING_MULTI_MODAL, WARNING_BOTH
|
8 |
+
from src.models import load_models, clean_models_data
|
9 |
+
|
10 |
+
from src.constants import PROMPTS
|
11 |
+
|
12 |
+
def calculator_mode():
|
13 |
+
|
14 |
+
with st.container(border=True):
|
15 |
+
|
16 |
+
df = load_models()
|
17 |
+
|
18 |
+
col1, col2, col3 = st.columns(3)
|
19 |
+
|
20 |
+
with col1:
|
21 |
+
provider = st.selectbox(label = 'Provider',
|
22 |
+
options = [x for x in df['provider_clean'].unique()],
|
23 |
+
index = 9)
|
24 |
+
provider_raw = df[df['provider_clean'] == provider]['provider'].values[0]
|
25 |
+
|
26 |
+
with col2:
|
27 |
+
model = st.selectbox('Model', [x for x in df['name_clean'].unique() if x in df[df['provider_clean'] == provider]['name_clean'].unique()])
|
28 |
+
model_raw = df[(df['provider_clean'] == provider) & (df['name_clean'] == model)]['name'].values[0]
|
29 |
+
|
30 |
+
with col3:
|
31 |
+
output_tokens = st.selectbox('Example prompt', [x[0] for x in PROMPTS])
|
32 |
+
|
33 |
+
# WARNING DISPLAY
|
34 |
+
|
35 |
+
df_filtered = df[(df['provider_clean'] == provider) & (df['name_clean'] == model)]
|
36 |
+
|
37 |
+
if df_filtered['warning_arch'].values[0] and not df_filtered['warning_multi_modal'].values[0]:
|
38 |
+
st.warning(WARNING_CLOSED_SOURCE)
|
39 |
+
if df_filtered['warning_multi_modal'].values[0] and not df_filtered['warning_arch'].values[0]:
|
40 |
+
st.warning(WARNING_MULTI_MODAL)
|
41 |
+
if df_filtered['warning_arch'].values[0] and df_filtered['warning_multi_modal'].values[0]:
|
42 |
+
st.warning(WARNING_BOTH)
|
43 |
+
|
44 |
+
try:
|
45 |
+
impacts = llm_impacts(
|
46 |
+
provider=provider_raw,
|
47 |
+
model_name=model_raw,
|
48 |
+
output_token_count=[x[1] for x in PROMPTS if x[0] == output_tokens][0],
|
49 |
+
request_latency=100000
|
50 |
+
)
|
51 |
+
|
52 |
+
impacts, _, _ = format_impacts(impacts)
|
53 |
+
|
54 |
+
with st.container(border=True):
|
55 |
+
|
56 |
+
st.markdown('<h3 align = "center">Environmental impacts</h3>', unsafe_allow_html=True)
|
57 |
+
st.markdown('<p align = "center">To understand how the environmental impacts are computed go to the 📖 Methodology tab.</p>', unsafe_allow_html=True)
|
58 |
+
display_impacts(impacts)
|
59 |
+
|
60 |
+
with st.container(border=True):
|
61 |
+
|
62 |
+
st.markdown('<h3 align = "center">That\'s equivalent to ...</h3>', unsafe_allow_html=True)
|
63 |
+
st.markdown('<p align = "center">Making this request to the LLM is equivalent to the following actions :</p>', unsafe_allow_html=True)
|
64 |
+
display_equivalent(impacts)
|
65 |
+
|
66 |
+
except Exception as e:
|
67 |
+
st.error('Could not find the model in the repository. Please try another model.')
|
src/constants.py
CHANGED
@@ -1,103 +1,106 @@
|
|
1 |
-
PROVIDERS = [
|
2 |
-
("OpenAI", "openai"),
|
3 |
-
("Anthropic", "anthropic"),
|
4 |
-
("Cohere", "cohere"),
|
5 |
-
("Meta", "huggingface_hub/meta"),
|
6 |
-
("Mistral AI", "mistralai"),
|
7 |
-
]
|
8 |
-
|
9 |
-
OPENAI_MODELS = [
|
10 |
-
("GPT-4o", "gpt-4o"),
|
11 |
-
("GPT-4-Turbo", "gpt-4-turbo"),
|
12 |
-
("GPT-4", "gpt-4"),
|
13 |
-
("GPT-3.5-Turbo", "gpt-3.5-turbo"),
|
14 |
-
]
|
15 |
-
|
16 |
-
ANTHROPIC_MODELS = [
|
17 |
-
("Claude 3 Opus", "claude-3-opus-20240229"),
|
18 |
-
("Claude 3 Sonnet", "claude-3-sonnet-20240229"),
|
19 |
-
("Claude 3 Haiku", "claude-3-haiku-20240307"),
|
20 |
-
("Claude 2.1", "claude-2.1"),
|
21 |
-
("Claude 2.0", "claude-2.0"),
|
22 |
-
("Claude Instant 1.2", "claude-instant-1.2"),
|
23 |
-
]
|
24 |
-
|
25 |
-
COHERE_MODELS = [
|
26 |
-
("Command Light", "command-light"),
|
27 |
-
("Command", "command"),
|
28 |
-
("Command R", "command-r"),
|
29 |
-
("Command R+", "command-r-plus"),
|
30 |
-
]
|
31 |
-
|
32 |
-
META_MODELS = [
|
33 |
-
("Llama 3 8B", "meta-llama/Meta-Llama-3-8B"),
|
34 |
-
("Llama 3 70B", "meta-llama/Meta-Llama-3-70B"),
|
35 |
-
("Llama 2 7B", "meta-llama/Llama-2-7b-hf"),
|
36 |
-
("Llama 2 13B", "meta-llama/Llama-2-13b-hf"),
|
37 |
-
("Llama 2 70B", "meta-llama/Llama-2-70b-hf"),
|
38 |
-
]
|
39 |
-
|
40 |
-
MISTRALAI_MODELS = [
|
41 |
-
("Mistral 7B", "open-mistral-7b"),
|
42 |
-
("Mixtral 8x7B", "open-mixtral-8x7b"),
|
43 |
-
("Mixtral 8x22B", "open-mixtral-8x22b"),
|
44 |
-
("Tiny", "mistral-tiny-2312"),
|
45 |
-
("Small", "mistral-small-2402"),
|
46 |
-
("Medium", "mistral-medium-2312"),
|
47 |
-
("Large", "mistral-large-2402"),
|
48 |
-
]
|
49 |
-
|
50 |
-
PROMPTS = [
|
51 |
-
("Write a Tweet", 50),
|
52 |
-
("Write an email", 170),
|
53 |
-
("Write an article summary", 250),
|
54 |
-
("Small conversation with a chatbot", 400),
|
55 |
-
("Write a report of 5 pages", 5000),
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
"openai/gpt-
|
62 |
-
"openai/gpt-4",
|
63 |
-
"openai/gpt-
|
64 |
-
"
|
65 |
-
"anthropic/claude-3-
|
66 |
-
"anthropic/claude-3-
|
67 |
-
"anthropic/claude-
|
68 |
-
"anthropic/claude-2.
|
69 |
-
"anthropic/claude-
|
70 |
-
"
|
71 |
-
"mistralai/mistral-
|
72 |
-
"mistralai/mistral-
|
73 |
-
"mistralai/mistral-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
("OpenAI / GPT-
|
79 |
-
("OpenAI / GPT-4", "openai/gpt-4"),
|
80 |
-
("OpenAI / GPT-
|
81 |
-
("
|
82 |
-
("Anthropic / Claude 3
|
83 |
-
("Anthropic / Claude 3
|
84 |
-
("Anthropic / Claude
|
85 |
-
("Anthropic / Claude 2.
|
86 |
-
("Anthropic / Claude
|
87 |
-
("
|
88 |
-
("Mistral AI /
|
89 |
-
("Mistral AI / Mixtral
|
90 |
-
("Mistral AI /
|
91 |
-
("Mistral AI /
|
92 |
-
("Mistral AI /
|
93 |
-
("Mistral AI /
|
94 |
-
("
|
95 |
-
("Meta / Llama 3
|
96 |
-
("Meta / Llama
|
97 |
-
("Meta / Llama 2
|
98 |
-
("Meta / Llama 2
|
99 |
-
("
|
100 |
-
("Cohere / Command", "cohere/command"),
|
101 |
-
("Cohere / Command
|
102 |
-
("Cohere / Command R
|
103 |
-
|
|
|
|
|
|
|
|
1 |
+
PROVIDERS = [
|
2 |
+
("OpenAI", "openai"),
|
3 |
+
("Anthropic", "anthropic"),
|
4 |
+
("Cohere", "cohere"),
|
5 |
+
("Meta", "huggingface_hub/meta"),
|
6 |
+
("Mistral AI", "mistralai"),
|
7 |
+
]
|
8 |
+
|
9 |
+
OPENAI_MODELS = [
|
10 |
+
("GPT-4o", "gpt-4o"),
|
11 |
+
("GPT-4-Turbo", "gpt-4-turbo"),
|
12 |
+
("GPT-4", "gpt-4"),
|
13 |
+
("GPT-3.5-Turbo", "gpt-3.5-turbo"),
|
14 |
+
]
|
15 |
+
|
16 |
+
ANTHROPIC_MODELS = [
|
17 |
+
("Claude 3 Opus", "claude-3-opus-20240229"),
|
18 |
+
("Claude 3 Sonnet", "claude-3-sonnet-20240229"),
|
19 |
+
("Claude 3 Haiku", "claude-3-haiku-20240307"),
|
20 |
+
("Claude 2.1", "claude-2.1"),
|
21 |
+
("Claude 2.0", "claude-2.0"),
|
22 |
+
("Claude Instant 1.2", "claude-instant-1.2"),
|
23 |
+
]
|
24 |
+
|
25 |
+
COHERE_MODELS = [
|
26 |
+
("Command Light", "command-light"),
|
27 |
+
("Command", "command"),
|
28 |
+
("Command R", "command-r"),
|
29 |
+
("Command R+", "command-r-plus"),
|
30 |
+
]
|
31 |
+
|
32 |
+
META_MODELS = [
|
33 |
+
("Llama 3 8B", "meta-llama/Meta-Llama-3-8B"),
|
34 |
+
("Llama 3 70B", "meta-llama/Meta-Llama-3-70B"),
|
35 |
+
("Llama 2 7B", "meta-llama/Llama-2-7b-hf"),
|
36 |
+
("Llama 2 13B", "meta-llama/Llama-2-13b-hf"),
|
37 |
+
("Llama 2 70B", "meta-llama/Llama-2-70b-hf"),
|
38 |
+
]
|
39 |
+
|
40 |
+
MISTRALAI_MODELS = [
|
41 |
+
("Mistral 7B", "open-mistral-7b"),
|
42 |
+
("Mixtral 8x7B", "open-mixtral-8x7b"),
|
43 |
+
("Mixtral 8x22B", "open-mixtral-8x22b"),
|
44 |
+
("Tiny", "mistral-tiny-2312"),
|
45 |
+
("Small", "mistral-small-2402"),
|
46 |
+
("Medium", "mistral-medium-2312"),
|
47 |
+
("Large", "mistral-large-2402"),
|
48 |
+
]
|
49 |
+
|
50 |
+
PROMPTS = [
|
51 |
+
("Write a Tweet", 50),
|
52 |
+
("Write an email", 170),
|
53 |
+
("Write an article summary", 250),
|
54 |
+
("Small conversation with a chatbot", 400),
|
55 |
+
("Write a report of 5 pages", 5000),
|
56 |
+
("Write the code for this app", 10000)
|
57 |
+
]
|
58 |
+
PROMPTS = [(s + f" ({v} output tokens)", v) for (s, v) in PROMPTS]
|
59 |
+
|
60 |
+
CLOSED_SOURCE_MODELS = {
|
61 |
+
"openai/gpt-4o",
|
62 |
+
"openai/gpt-4-turbo",
|
63 |
+
"openai/gpt-4",
|
64 |
+
"openai/gpt-3.5-turbo",
|
65 |
+
"anthropic/claude-3-opus-20240229",
|
66 |
+
"anthropic/claude-3-sonnet-20240229",
|
67 |
+
"anthropic/claude-3-haiku-20240307",
|
68 |
+
"anthropic/claude-2.1",
|
69 |
+
"anthropic/claude-2.0",
|
70 |
+
"anthropic/claude-instant-1.2",
|
71 |
+
"mistralai/mistral-tiny-2312",
|
72 |
+
"mistralai/mistral-small-2402",
|
73 |
+
"mistralai/mistral-medium-2312",
|
74 |
+
"mistralai/mistral-large-2402",
|
75 |
+
}
|
76 |
+
|
77 |
+
MODELS = [
|
78 |
+
("OpenAI / GPT-4o", "openai/gpt-4o"),
|
79 |
+
("OpenAI / GPT-4-Turbo", "openai/gpt-4-turbo"),
|
80 |
+
("OpenAI / GPT-4", "openai/gpt-4"),
|
81 |
+
("OpenAI / GPT-3.5-Turbo", "openai/gpt-3.5-turbo"),
|
82 |
+
("Anthropic / Claude 3 Opus", "anthropic/claude-3-opus-20240229"),
|
83 |
+
("Anthropic / Claude 3 Sonnet", "anthropic/claude-3-sonnet-20240229"),
|
84 |
+
("Anthropic / Claude 3 Haiku", "anthropic/claude-3-haiku-20240307"),
|
85 |
+
("Anthropic / Claude 2.1", "anthropic/claude-2.1"),
|
86 |
+
("Anthropic / Claude 2.0", "anthropic/claude-2.0"),
|
87 |
+
("Anthropic / Claude Instant 1.2", "anthropic/claude-instant-1.2"),
|
88 |
+
("Mistral AI / Mistral 7B", "mistralai/open-mistral-7b"),
|
89 |
+
("Mistral AI / Mixtral 8x7B", "mistralai/open-mixtral-8x7b"),
|
90 |
+
("Mistral AI / Mixtral 8x22B", "mistralai/open-mixtral-8x22b"),
|
91 |
+
("Mistral AI / Tiny", "mistralai/mistral-tiny-2312"),
|
92 |
+
("Mistral AI / Small", "mistralai/mistral-small-2402"),
|
93 |
+
("Mistral AI / Medium", "mistralai/mistral-medium-2312"),
|
94 |
+
("Mistral AI / Large", "mistralai/mistral-large-2402"),
|
95 |
+
("Meta / Llama 3 8B", "huggingface_hub/meta-llama/Meta-Llama-3-8B"),
|
96 |
+
("Meta / Llama 3 70B", "huggingface_hub/meta-llama/Meta-Llama-3-70B"),
|
97 |
+
("Meta / Llama 2 7B", "huggingface_hub/meta-llama/Llama-2-7b-hf"),
|
98 |
+
("Meta / Llama 2 13B", "huggingface_hub/meta-llama/Llama-2-13b-hf"),
|
99 |
+
("Meta / Llama 2 70B", "huggingface_hub/meta-llama/Llama-2-70b-hf"),
|
100 |
+
("Cohere / Command Light", "cohere/command-light"),
|
101 |
+
("Cohere / Command", "cohere/command"),
|
102 |
+
("Cohere / Command R", "cohere/command-r"),
|
103 |
+
("Cohere / Command R+", "cohere/command-r-plus"),
|
104 |
+
]
|
105 |
+
|
106 |
+
MODEL_REPOSITORY_URL = "https://raw.githubusercontent.com/genai-impact/ecologits/refs/heads/main/ecologits/data/models.json"
|
src/content.py
CHANGED
@@ -1,286 +1,232 @@
|
|
1 |
-
|
2 |
-
|
3 |
-
<
|
4 |
-
|
5 |
-
|
6 |
-
|
7 |
-
</
|
8 |
-
|
9 |
-
<
|
10 |
-
<
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
This tool is developed and maintained by [GenAI Impact](https://genai-impact.org/) non-profit. Learn more about
|
19 |
-
🌱 EcoLogits by reading the documentation on [ecologits.ai](https://ecologits.ai).
|
20 |
-
|
21 |
-
🩷 Support us by giving a ⭐️ on our [GitHub repository](https://github.com/genai-impact/ecologits) and by following our [LinkedIn page](https://www.linkedin.com/company/genai-impact/).
|
22 |
-
"""
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
The
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
the
|
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 |
-
EcoLogits is focused on estimating the environmental impacts of generative AI (only LLMs for now) used **through API
|
83 |
-
providers (such as OpenAI, Anthropic, Cloud APIs...)** whereas CodeCarbon is more general tool to measure energy
|
84 |
-
consumption and estimate GHG emissions measurement. If you deploy LLMs locally we encourage you to use CodeCarbon to
|
85 |
-
get real numbers of your energy consumption.
|
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 |
-
We
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
We
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
We divide the
|
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 |
-
#### Number of 💨 wind turbines or ☢️ nuclear plants
|
235 |
-
|
236 |
-
We compare the ⚡️ direct energy consumption (scaled) by the energy production of wind turbines and nuclear power
|
237 |
-
plants. From [ecologie.gouv.fr](https://www.ecologie.gouv.fr/eolien-terrestre) we consider that a $ 2\ MW $ wind
|
238 |
-
turbine produces $ 4.2\ GWh $ a year. And from [edf.fr](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)
|
239 |
-
we learn that a $ 900\ MW $ nuclear power plant produces $ 6\ TWh $ a year.
|
240 |
-
|
241 |
-
We divide the scaled energy consumption by these values to get the number of wind turbines or nuclear power plants
|
242 |
-
needed.
|
243 |
-
|
244 |
-
#### Multiplier of 🇮🇪 Ireland electricity consumption
|
245 |
-
|
246 |
-
We compare the ⚡️ direct energy consumption (scaled) by the electricity consumption of Ireland per year. From
|
247 |
-
[wikipedia.org](https://en.wikipedia.org/wiki/List_of_countries_by_electricity_consumption) we consider the Ireland
|
248 |
-
electricity consumption to be $ 33\ TWh $ a year for a population of 5M.
|
249 |
-
|
250 |
-
We divide the scaled energy consumption by this value to get the equivalent number of "Ireland countries".
|
251 |
-
|
252 |
-
#### Number of ✈️ Paris ↔ New York City flights
|
253 |
-
|
254 |
-
We compare the 🌍 GHG emissions (scaled) of the request and of a return flight Paris ↔ New York City. From
|
255 |
-
[impactco2.fr](https://impactco2.fr/outils/comparateur?value=1&comparisons=&equivalent=avion-pny) we consider that a
|
256 |
-
return flight Paris → New York City → Paris for one passenger emits $ 1,770\ kgCO2eq $ and we consider an overall
|
257 |
-
average load of 100 passengers per flight.
|
258 |
-
|
259 |
-
We divide the scaled GHG emissions by this value to get the equivalent number of return flights.
|
260 |
-
|
261 |
-
**If you are motivated to help us test and enhance this methodology
|
262 |
-
[contact us](https://genai-impact.org/contact/)!** 💪
|
263 |
-
"""
|
264 |
-
|
265 |
-
CITATION_LABEL = "BibTeX citation for EcoLogits Calculator and the EcoLogits library:"
|
266 |
-
CITATION_TEXT = r"""@misc{ecologits-calculator,
|
267 |
-
author={Samuel Rincé, Adrien Banse and Valentin Defour},
|
268 |
-
title={EcoLogits Calculator},
|
269 |
-
year={2024},
|
270 |
-
howpublished= {\url{https://huggingface.co/spaces/genai-impact/ecologits-calculator}},
|
271 |
-
}
|
272 |
-
@software{ecologits,
|
273 |
-
author = {Samuel Rincé, Adrien Banse, Vinh Nguyen and Luc Berton},
|
274 |
-
publisher = {GenAI Impact},
|
275 |
-
title = {EcoLogits: track the energy consumption and environmental footprint of using generative AI models through APIs.},
|
276 |
-
}"""
|
277 |
-
|
278 |
-
LICENCE_TEXT = """<p xmlns:cc="http://creativecommons.org/ns#" >
|
279 |
-
This work is licensed under
|
280 |
-
<a href="https://creativecommons.org/licenses/by-sa/4.0/?ref=chooser-v1" target="_blank" rel="license noopener noreferrer" style="display:inline-block;">
|
281 |
-
CC BY-SA 4.0
|
282 |
-
</a>
|
283 |
-
<img style="display:inline-block;height:22px!important;margin-left:3px;vertical-align:text-bottom;" src="https://mirrors.creativecommons.org/presskit/icons/cc.svg?ref=chooser-v1" alt="">
|
284 |
-
<img style="display:inline-block;height:22px!important;margin-left:3px;vertical-align:text-bottom;" src="https://mirrors.creativecommons.org/presskit/icons/by.svg?ref=chooser-v1" alt="">
|
285 |
-
<img style="display:inline-block;height:22px!important;margin-left:3px;vertical-align:text-bottom;" src="https://mirrors.creativecommons.org/presskit/icons/sa.svg?ref=chooser-v1" alt="">
|
286 |
-
</p>"""
|
|
|
1 |
+
HERO_TEXT = """
|
2 |
+
<div align="center">
|
3 |
+
<a href="https://ecologits.ai/">
|
4 |
+
<img style="max-height: 80px" alt="EcoLogits" src="https://raw.githubusercontent.com/genai-impact/ecologits/main/docs/assets/logo_light.png">
|
5 |
+
</a>
|
6 |
+
</div>
|
7 |
+
<h1 align="center">🧮 EcoLogits Calculator</h1>
|
8 |
+
<div align="center">
|
9 |
+
<p style="max-width: 500px; text-align: center">
|
10 |
+
<i><b>EcoLogits</b> is a python library that tracks the <b>energy consumption</b> and <b>environmental
|
11 |
+
footprint</b> of using <b>generative AI</b> models through APIs.</i>
|
12 |
+
</p>
|
13 |
+
</div>
|
14 |
+
<br>
|
15 |
+
"""
|
16 |
+
|
17 |
+
INTRO_TEXT = """
|
18 |
+
This tool is developed and maintained by [GenAI Impact](https://genai-impact.org/) non-profit. Learn more about
|
19 |
+
🌱 EcoLogits by reading the documentation on [ecologits.ai](https://ecologits.ai).
|
20 |
+
|
21 |
+
🩷 Support us by giving a ⭐️ on our [GitHub repository](https://github.com/genai-impact/ecologits) and by following our [LinkedIn page](https://www.linkedin.com/company/genai-impact/).
|
22 |
+
"""
|
23 |
+
|
24 |
+
WARNING_CLOSED_SOURCE = """
|
25 |
+
⚠️ The model architecture has not been publicly released, expect lower precision of estimations.
|
26 |
+
"""
|
27 |
+
|
28 |
+
WARNING_MULTI_MODAL = """
|
29 |
+
⚠️ The model architecture is multimodal, expect lower precision of estimations.
|
30 |
+
"""
|
31 |
+
|
32 |
+
WARNING_BOTH = """
|
33 |
+
⚠️ The model architecture has not been publicly released and is multimodal, expect lower precision of estimations.
|
34 |
+
"""
|
35 |
+
|
36 |
+
ABOUT_TEXT = r"""
|
37 |
+
## 🎯 Our goal
|
38 |
+
**The main goal of the EcoLogits Calculator is to raise awareness on the environmental impacts of LLM inference.**
|
39 |
+
The rapid evolution of generative AI is reshaping numerous industries and aspects of our daily lives. While these
|
40 |
+
advancements offer some benefits, they also **pose substantial environmental challenges that cannot be overlooked**.
|
41 |
+
Plus the issue of AI's environmental footprint has been mainly discussed at training stage but rarely at the inference
|
42 |
+
stage. That is an issue because **inference impacts for LLMs can largely overcome the training impacts when deployed
|
43 |
+
at large scales**.
|
44 |
+
At **[GenAI Impact](https://genai-impact.org/) we are dedicated to understanding and mitigating the environmental
|
45 |
+
impacts of generative AI** through rigorous research, innovative tools, and community engagement. Especially, in early
|
46 |
+
2024 we have launched an new open-source tool called [EcoLogits](https://github.com/genai-impact/ecologits) that tracks
|
47 |
+
the energy consumption and environmental footprint of using generative AI models through APIs.
|
48 |
+
## 🙋 FAQ
|
49 |
+
**How we assess the impacts of closed-source models?**
|
50 |
+
Environmental impacts are calculated based on model architecture and parameter count. For closed-source models, we
|
51 |
+
lack transparency from providers, so we estimate parameter counts using available information. For GPT models, we
|
52 |
+
based our estimates on leaked GPT-4 architecture and scaled parameters count for GPT-4-Turbo and GPT-4o based on
|
53 |
+
pricing differences. For other proprietary models like Anthropic's Claude, we assume similar impacts for models
|
54 |
+
released around the same time with similar performance on public benchmarks. Please note that these estimates are
|
55 |
+
based on assumptions and may not be exact. Our methods are open-source and transparent so you can always see the
|
56 |
+
hypotheses we use.
|
57 |
+
**Which generative AI models or providers are supported?**
|
58 |
+
To see the full list of **generative AI providers** currently supported by EcoLogits, see the following
|
59 |
+
[documentation page](https://ecologits.ai/providers/). As of today we only support LLMs but we plan to add support for
|
60 |
+
embeddings, image generation, multi-modal models and more. If you are interested don't hesitate to
|
61 |
+
[join us](https://genai-impact.org/contact/) and accelerate our work!
|
62 |
+
**How to reduce AI environmental impacts?**
|
63 |
+
* Look at **indirect impacts** of your project. Does the finality of your project is impacting negatively the
|
64 |
+
environment?
|
65 |
+
* **Be frugal** and question your usage or need of AI
|
66 |
+
* Do you really need AI to solve your problem?
|
67 |
+
* Do you really need GenAI to solve your problem? (you can read this [paper](https://aclanthology.org/2023.emnlp-industry.39.pdf))
|
68 |
+
* Use small and specialized models to solve your problem.
|
69 |
+
* Evaluate before, during and after the development of your project the environmental impacts with tools like
|
70 |
+
🌱 [EcoLogits](https://github.com/genai-impact/ecologits) or [CodeCarbon](https://github.com/mlco2/codecarbon)
|
71 |
+
(see [more tools](https://github.com/samuelrince/awesome-green-ai))
|
72 |
+
* Restrict the use case and limit the usage of your tool or feature to the desired purpose.
|
73 |
+
* Do NOT buy new GPUs / hardware
|
74 |
+
* Hardware manufacturing for data centers is around 50% of the impact.
|
75 |
+
* Use cloud instances that are located in low emissions / high energy efficiency data centers
|
76 |
+
(see [electricitymaps.com](https://app.electricitymaps.com/map))
|
77 |
+
* Optimize your models for production
|
78 |
+
* Quantize your models.
|
79 |
+
* Use inference optimization tricks.
|
80 |
+
* Prefer fine-tuning of small and existing models over generalist models.
|
81 |
+
**What is the difference between **EcoLogits** and [CodeCarbon](https://github.com/mlco2/codecarbon)?**
|
82 |
+
EcoLogits is focused on estimating the environmental impacts of generative AI (only LLMs for now) used **through API
|
83 |
+
providers (such as OpenAI, Anthropic, Cloud APIs...)** whereas CodeCarbon is more general tool to measure energy
|
84 |
+
consumption and estimate GHG emissions measurement. If you deploy LLMs locally we encourage you to use CodeCarbon to
|
85 |
+
get real numbers of your energy consumption.
|
86 |
+
## 🤗 Contributing
|
87 |
+
We are eager to get feedback from the community, don't hesitate to engage the discussion with us on this
|
88 |
+
[GitHub thread](https://github.com/genai-impact/ecologits/discussions/45) or message us on
|
89 |
+
[LinkedIn](https://www.linkedin.com/company/genai-impact/).
|
90 |
+
We also welcome any open-source contributions on 🌱 **[EcoLogits](https://github.com/genai-impact/ecologits)** or on
|
91 |
+
🧮 **EcoLogits Calculator**.
|
92 |
+
## ⚖️ License
|
93 |
+
<p xmlns:cc="http://creativecommons.org/ns#" >
|
94 |
+
This work is licensed under
|
95 |
+
<a href="https://creativecommons.org/licenses/by-sa/4.0/?ref=chooser-v1" target="_blank" rel="license noopener noreferrer" style="display:inline-block;">
|
96 |
+
CC BY-SA 4.0
|
97 |
+
</a>
|
98 |
+
<img style="display:inline-block;height:22px!important;margin-left:3px;vertical-align:text-bottom;" src="https://mirrors.creativecommons.org/presskit/icons/cc.svg?ref=chooser-v1" alt="">
|
99 |
+
<img style="display:inline-block;height:22px!important;margin-left:3px;vertical-align:text-bottom;" src="https://mirrors.creativecommons.org/presskit/icons/by.svg?ref=chooser-v1" alt="">
|
100 |
+
<img style="display:inline-block;height:22px!important;margin-left:3px;vertical-align:text-bottom;" src="https://mirrors.creativecommons.org/presskit/icons/sa.svg?ref=chooser-v1" alt="">
|
101 |
+
</p>
|
102 |
+
## 🙌 Acknowledgement
|
103 |
+
We thank [Data For Good](https://dataforgood.fr/) and [Boavizta](https://boavizta.org/en) for supporting the
|
104 |
+
development of this project. Their contributions of tools, best practices, and expertise in environmental impact
|
105 |
+
assessment have been invaluable.
|
106 |
+
We also extend our gratitude to the open-source contributions of 🤗 [Hugging Face](huggingface.com) on the LLM-Perf
|
107 |
+
Leaderboard.
|
108 |
+
## 🤝 Contact
|
109 |
+
For general question on the project, please use the [GitHub thread](https://github.com/genai-impact/ecologits/discussions/45).
|
110 |
+
Otherwise use our contact form on [genai-impact.org/contact](https://genai-impact.org/contact/).
|
111 |
+
"""
|
112 |
+
|
113 |
+
|
114 |
+
METHODOLOGY_TEXT = r"""
|
115 |
+
## 📖 Methodology
|
116 |
+
We have developed a methodology to **estimate the energy consumption and environmental impacts for an LLM inference**
|
117 |
+
based on request parameters and hypotheses on the data center location, the hardware used, the model architecture and
|
118 |
+
more.
|
119 |
+
In this section we will only cover the principles of the methodology related to the 🧮 **EcoLogits Calculator**. If
|
120 |
+
you wish to learn more on the environmental impacts modeling of an LLM request checkout the
|
121 |
+
🌱 [EcoLogits documentation page](https://ecologits.ai/methodology/).
|
122 |
+
### Modeling impacts of an LLM request
|
123 |
+
The environmental impacts of an LLM inference are split into the **usage impacts** $I_{request}^u$ to account for
|
124 |
+
electricity consumption and the **embodied impacts** $I_{request}^e$ that relates to resource extraction, hardware
|
125 |
+
manufacturing and transportation. In general terms it can be expressed as follow:
|
126 |
+
$$ I_{request} = I_{request}^u + I_{request}^e $$
|
127 |
+
$$ I_{request} = E_{request}*F_{em}+\frac{\Delta T}{\Delta L}*I_{server}^e $$
|
128 |
+
With,
|
129 |
+
* $E_{request}$ the estimated energy consumption of the server and its cooling system.
|
130 |
+
* $F_{em}$ the electricity mix that depends on the country and time.
|
131 |
+
* $\frac{\Delta T}{\Delta L}$ the hardware usage ratio i.e. the computation time over the lifetime of the hardware.
|
132 |
+
* $I_{server}^e$ the embodied impacts of the server.
|
133 |
+
Additionally, to ⚡️ **direct energy consumption** the environmental impacts are expressed in **three dimensions
|
134 |
+
(multi-criteria impacts)** that are:
|
135 |
+
* 🌍 **Global Warming Potential** (GWP): Potential impact on global warming in kgCO2eq (commonly known as GHG/carbon
|
136 |
+
emissions).
|
137 |
+
* 🪨 **Abiotic Depletion Potential for Elements** (ADPe): Impact on the depletion of non-living resources such as
|
138 |
+
minerals or metals in kgSbeq.
|
139 |
+
* ⛽️ **Primary Energy** (PE): Total energy consumed from primary sources in MJ.
|
140 |
+
### Principles, Data and Hypotheses
|
141 |
+
We use a **bottom-up methodology** to model impacts, meaning that we will estimate the impacts of low-level physical
|
142 |
+
components to then estimate the impacts at software level (in that case an LLM inference). We also rely on **Life
|
143 |
+
Cycle Approach (LCA) proxies and approach** to model both usage and embodied phases with multi-criteria impacts.
|
144 |
+
If you are interested in this approach we recommend you to read the following [Boavizta](https://boavizta.org/)
|
145 |
+
resources.
|
146 |
+
* [Digital & environment: How to evaluate server manufacturing footprint, beyond greenhouse gas emissions?](https://boavizta.org/en/blog/empreinte-de-la-fabrication-d-un-serveur)
|
147 |
+
* [Boavizta API automated evaluation of environmental impacts of ICT services and equipments](https://boavizta.org/en/blog/boavizta-api-automated-evaluation-of-ict-impacts-on-the-environment)
|
148 |
+
* [Boavizta API documentation](https://doc.api.boavizta.org/)
|
149 |
+
We leverage **open data to estimate the environmental impacts**, here is an exhaustive list of our data providers.
|
150 |
+
* [LLM-Perf Leaderboard](https://huggingface.co/spaces/optimum/llm-perf-leaderboard) to estimate GPU energy consumption
|
151 |
+
and latency based on the model architecture and number of output tokens.
|
152 |
+
* [Boavizta API](https://github.com/Boavizta/boaviztapi) to estimate server embodied impacts and base energy
|
153 |
+
consumption.
|
154 |
+
* [ADEME Base Empreinte®](https://base-empreinte.ademe.fr/) for electricity mix impacts per country.
|
155 |
+
Finally here are the **main hypotheses** we have made to compute the impacts.
|
156 |
+
* ⚠️ **We *"guesstimate"* the model architecture of proprietary LLMs when not disclosed by the provider.**
|
157 |
+
* Production setup: quantized models running on data center grade servers and GPUs such as A100.
|
158 |
+
* Electricity mix does not depend on time (help us enhance EcoLogits and work on this [issue](https://github.com/genai-impact/ecologits/issues/42))
|
159 |
+
* Ignore the following impacts: unused cloud resources, data center building, network and end-user devices... (for now)
|
160 |
+
## Equivalents
|
161 |
+
We have integrated impact equivalents to help people better understand the impacts and have reference points for
|
162 |
+
standard use cases and everyday activities.
|
163 |
+
### Request impacts
|
164 |
+
These equivalents are computed based on the request impacts only.
|
165 |
+
#### 🚶♂️➡️ Walking or 🏃♂️➡️ running distance
|
166 |
+
We compare the ⚡️ direct energy consumption with the energy consumption of someone 🚶♂️➡️ walking or 🏃♂️➡️ running.
|
167 |
+
From [runningtools.com](https://www.runningtools.com/energyusage.htm) we consider the following energy values per
|
168 |
+
physical activity (for someone weighing 70kg):
|
169 |
+
* 🚶♂️➡️ walking: $ 196\ kJ/km $ (speed of $ 3\ km/h $)
|
170 |
+
* 🏃♂️➡️ running: $ 294\ kJ/km $ (speed of $ 10\ km/h $)
|
171 |
+
We divide the request energy consumption by these values to compute the distance traveled.
|
172 |
+
#### 🔋 Electric Vehicle distance
|
173 |
+
We compare the ⚡️ direct energy consumption with the energy consumer by a EV car. From
|
174 |
+
[selectra.info](https://selectra.info/energie/actualites/insolite/consommation-vehicules-electriques-france-2040) or
|
175 |
+
[tesla.com](https://www.tesla.com/fr_fr/support/power-consumption) we consider an average value of energy consumed per
|
176 |
+
kilometer of: $ 0.17\ kWh/km $.
|
177 |
+
We divide the request energy consumption by this value to compute the distance driven by an EV.
|
178 |
+
#### ⏯️ Streaming time
|
179 |
+
We compare the 🌍 GHG emissions of the request and of streaming a video. From
|
180 |
+
[impactco2.fr](https://impactco2.fr/outils/comparateur?value=1&comparisons=streamingvideo), we consider that
|
181 |
+
$ 1\ kgCO2eq $ is equivalent to $ 15.6\ h $ of streaming.
|
182 |
+
We multiply that value by the GHG emissions of the request to get an equivalent in hours of video streaming.
|
183 |
+
### Scaled impacts
|
184 |
+
These equivalents are computed based on the request impacts scaled to a worldwide adoption use case. We imply that the
|
185 |
+
same request is done 1% of the planet everyday for 1 year, and then compute impact equivalents.
|
186 |
+
$$
|
187 |
+
I_{scaled} = I_{request} * [1 \\% \ \text{of}\ 8B\ \text{people on earth}] * 365\ \text{days}
|
188 |
+
$$
|
189 |
+
#### Number of 💨 wind turbines or ☢️ nuclear plants
|
190 |
+
We compare the ⚡️ direct energy consumption (scaled) by the energy production of wind turbines and nuclear power
|
191 |
+
plants. From [ecologie.gouv.fr](https://www.ecologie.gouv.fr/eolien-terrestre) we consider that a $ 2\ MW $ wind
|
192 |
+
turbine produces $ 4.2\ GWh $ a year. And from [edf.fr](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)
|
193 |
+
we learn that a $ 900\ MW $ nuclear power plant produces $ 6\ TWh $ a year.
|
194 |
+
We divide the scaled energy consumption by these values to get the number of wind turbines or nuclear power plants
|
195 |
+
needed.
|
196 |
+
#### Multiplier of 🇮🇪 Ireland electricity consumption
|
197 |
+
We compare the ⚡️ direct energy consumption (scaled) by the electricity consumption of Ireland per year. From
|
198 |
+
[wikipedia.org](https://en.wikipedia.org/wiki/List_of_countries_by_electricity_consumption) we consider the Ireland
|
199 |
+
electricity consumption to be $ 33\ TWh $ a year for a population of 5M.
|
200 |
+
We divide the scaled energy consumption by this value to get the equivalent number of "Ireland countries".
|
201 |
+
#### Number of ✈️ Paris ↔ New York City flights
|
202 |
+
We compare the 🌍 GHG emissions (scaled) of the request and of a return flight Paris ↔ New York City. From
|
203 |
+
[impactco2.fr](https://impactco2.fr/outils/comparateur?value=1&comparisons=&equivalent=avion-pny) we consider that a
|
204 |
+
return flight Paris → New York City → Paris for one passenger emits $ 1,770\ kgCO2eq $ and we consider an overall
|
205 |
+
average load of 100 passengers per flight.
|
206 |
+
We divide the scaled GHG emissions by this value to get the equivalent number of return flights.
|
207 |
+
|
208 |
+
#### If you are motivated to help us test and enhance this methodology [contact us](https://genai-impact.org/contact/)! 💪
|
209 |
+
"""
|
210 |
+
|
211 |
+
CITATION_LABEL = "BibTeX citation for EcoLogits Calculator and the EcoLogits library:"
|
212 |
+
CITATION_TEXT = r"""@misc{ecologits-calculator,
|
213 |
+
author={Samuel Rincé, Adrien Banse and Valentin Defour},
|
214 |
+
title={EcoLogits Calculator},
|
215 |
+
year={2025},
|
216 |
+
howpublished= {\url{https://huggingface.co/spaces/genai-impact/ecologits-calculator}},
|
217 |
+
}
|
218 |
+
@software{ecologits,
|
219 |
+
author = {Samuel Rincé, Adrien Banse, Vinh Nguyen and Luc Berton},
|
220 |
+
publisher = {GenAI Impact},
|
221 |
+
title = {EcoLogits: track the energy consumption and environmental footprint of using generative AI models through APIs.},
|
222 |
+
}"""
|
223 |
+
|
224 |
+
LICENCE_TEXT = """<p xmlns:cc="http://creativecommons.org/ns#" >
|
225 |
+
This work is licensed under
|
226 |
+
<a href="https://creativecommons.org/licenses/by-sa/4.0/?ref=chooser-v1" target="_blank" rel="license noopener noreferrer" style="display:inline-block;">
|
227 |
+
CC BY-SA 4.0
|
228 |
+
</a>
|
229 |
+
<img style="display:inline-block;height:22px!important;margin-left:3px;vertical-align:text-bottom;" src="https://mirrors.creativecommons.org/presskit/icons/cc.svg?ref=chooser-v1" alt="">
|
230 |
+
<img style="display:inline-block;height:22px!important;margin-left:3px;vertical-align:text-bottom;" src="https://mirrors.creativecommons.org/presskit/icons/by.svg?ref=chooser-v1" alt="">
|
231 |
+
<img style="display:inline-block;height:22px!important;margin-left:3px;vertical-align:text-bottom;" src="https://mirrors.creativecommons.org/presskit/icons/sa.svg?ref=chooser-v1" alt="">
|
232 |
+
</p>"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/data/electricity_mix.csv
ADDED
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
|
|
1 |
+
name,unit,source,WOR,EEE,ZWE,ZMB,ZAF,YEM,VNM,VEN,UZB,URY,USA,UKR,TZA,TWN,TTO,TUR,TUN,TKM,TJK,THA,TGO,SYR,SLV,SEN,SVK,SVN,SGP,SWE,SDN,SAU,RUS,SCG,ROU,QAT,PRY,PRT,POL,PAK,PHL,PER,PAN,OMN,NZL,NPL,NOR,NLD,NIC,NGA,NAM,MOZ,MYS,MEX,MLT,MNG,MMR,MKD,MDA,MAR,LBY,LVA,LUX,LTU,LKA,LBN,KAZ,KWT,KOR,PRK,KHM,KGZ,KEN,JPN,JOR,JAM,ITA,ISL,IRN,IRQ,IND,ISR,IRL,IDN,HUN,HTI,HRV,HND,HKG,GTM,GRC,GIB,GHA,GEO,GBR,GAB,FRA,FIN,ETH,ESP,ERI,EGY,EST,ECU,DZA,DOM,DNK,DEU,CZE,CYP,CUB,CRI,COL,CHN,CMR,CHL,CIV,CHE,COG,COD,CAN,BLR,BWA,BRA,BOL,BRN,BEN,BHR,BGR,BEL,BGD,BIH,AZE,AUS,AUT,ARG,AGO,ANT,ARM,ALB,ARE
|
2 |
+
adpe,kg éq. Sb,ADEME Base IMPACTS ®,0.0000000737708,0.0000000642317,0.000000109502,0.000000162193,0.0000000862445,0.0000000163908,0.0000000945573,0.000000112811,0.000000103681,0.000000104586,0.0000000985548,0.0000000647907,0.000000132261,0.0000000578088,0.000000064552,0.0000000749765,0.0000000177021,0.000000131822,0.000000152621,0.0000000569593,0.000000134255,0.0000000268396,0.0000000472135,0.0000000470662,0.0000000606109,0.0000000992283,0.0000000198459,0.0000000777062,0.0000000955701,0.0000000134206,0.0000000960312,0.000000132772,0.0000000981761,0.00000001324,0.000000149181,0.0000000341863,0.000000101946,0.0000000842952,0.0000000595304,0.0000000952688,0.0000000790553,0.0000000374073,0.0000000720474,0.000000238273,0.000000127486,0.0000000329318,0.0000000414983,0.0000000621,0.000000128285,0.000000148382,0.000000044938,0.0000000578358,0.000000049475,0.000000176361,0.000000152699,0.000000119873,0.000000110674,0.0000000641089,0.0000000206592,0.000000153757,0.000000105692,0.0000000294596,0.0000000986932,0.0000000182134,0.000000135386,0.0000000141168,0.0000000518017,0.000000117457,0.0000000319202,0.000000181827,0.0000000958533,0.0000000596578,0.0000000147031,0.0000000196047,0.00000005439,0.0000000781905,0.0000000220304,0.0000000404306,0.000000100099,0.0000000610194,0.0000000219257,0.0000000610451,0.0000000644587,0.0000000937057,0.000000153989,0.0000000649373,0.0000000816213,0.0000000803251,0.0000000691645,0.0000000286211,0.000000156003,0.000000137999,0.0000000370973,0.000000113843,0.0000000485798,0.0000000805114,0.000000174161,0.0000000518326,0.0000000512406,0.000000033925,0.0000000990171,0.000000127168,0.0000000216438,0.0000000429285,0.0000000157411,0.0000000878733,0.0000000817565,0.0000000448771,0.0000000299542,0.0000000863908,0.000000122031,0.0000000851552,0.000000146313,0.000000105851,0.0000000949004,0.000000100467,0.000000265575,0.000000174647,0.0000000993179,0.0000000840478,0.0000000866014,0.00000010962,0.0000000969793,0.0000000185641,0.0000000239702,0.0000000135014,0.0000000823611,0.0000000337201,0.0000000394158,0.000000148007,0.000000092567,0.0000000790846,0.000000141124,0.0000000768612,0.000000124074,0.0000000449103,0.0000000854245,0.000000229556,0.0000000141548
|
3 |
+
pe,MJ,ADPf / (1-%renewable_energy),9.988,12.873,16.122,1.798,11.732,16.250,11.238,15.163,17.367,107.570,11.358,12.936,9.305,11.439,14.289,16.150,12.902,23.300,19.165,10.414,21.978,16.989,13.012,14.516,11.680,12.146,10.477,11.026,29.629,14.058,13.200,14.242,15.585,11.916,0.020,14.153,13.178,16.175,11.120,8.211,16.364,22.306,24.731,0.396,4.952,8.511,24.696,11.279,468.150,0.206,12.268,11.775,19.374,15.114,14.132,19.120,18.429,11.702,19.116,8.249,10.128,21.043,12.116,12.341,13.260,12.753,10.199,32.793,34.655,15.380,68.996,10.718,13.677,14.799,12.656,0.013,15.022,20.372,20.363,10.023,10.706,11.603,11.784,20.167,18.548,15.762,,14.340,14.487,,10.097,10.425,13.579,28.341,11.289,11.275,36.133,12.090,13.289,10.195,16.334,20.908,16.376,12.412,16.824,16.260,12.517,13.118,17.317,45.996,7.312,14.119,10.807,11.348,14.783,11.782,34.147,0.097,11.987,13.194,19.642,9.031,11.587,15.689,14.337,14.036,14.375,10.776,12.935,21.705,12.831,16.908,11.036,10.049,16.972,,13.380,0.201,19.032
|
4 |
+
gwp,kg éq. CO2,ADEME Base IMPACTS ®,0.590478,0.509427,0.842811,0.0141304,1.17562,1.06777,0.555572,0.497373,0.81178,0.296953,0.67978,0.646745,0.475635,0.845351,0.933059,0.706988,0.80722,1.38296,0.0426743,0.646174,0.545455,1.08778,0.473128,1.1195,0.309341,0.498523,0.655825,0.0464664,1.12472,0.913677,0.66131,1.07808,0.664245,0.722125,0.241601,0.571172,1.15075,0.748727,0.761317,0.284364,0.53403,1.41292,0.293397,0.0841323,0.023754,0.544803,0.941626,0.693123,0.357253,0.00880732,0.832206,0.739214,1.31149,1.47192,0.48193,1.24074,1.04213,0.933694,1.35361,0.234273,0.490016,0.154229,0.709185,0.883627,1.128,0.885084,0.599585,0.797361,1.41054,0.156039,0.589603,0.540891,0.781372,1.07345,0.621329,0.0194609,0.930385,1.48728,1.58299,0.901842,0.648118,0.875394,0.541558,1.3858,0.535759,0.692837,0.95888,0.645801,1.13127,0.977477,0.540126,0.132046,0.602137,0.732511,0.0813225,0.322068,0.251299,0.467803,1.13153,0.587775,1.51492,0.627714,1.02318,0.909252,0.633534,0.657374,0.799077,0.978041,1.28325,0.224471,0.214014,1.05738,0.456622,0.574415,0.928583,0.0448568,0.904053,0.0613102,0.238191,0.795697,2.12572,0.278647,0.585131,0.997577,1.19128,0.804567,0.827087,0.256537,0.795168,1.56025,0.726126,1.12326,0.245573,0.476811,0.412014,1.13161,0.252002,0.0207635,1.09088
|
src/electricity_mix.py
CHANGED
@@ -1,155 +1,175 @@
|
|
1 |
-
from csv import DictReader
|
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 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from csv import DictReader
|
2 |
+
import pandas as pd
|
3 |
+
|
4 |
+
PATH = "src/data/electricity_mix.csv"
|
5 |
+
|
6 |
+
COUNTRY_CODES = [
|
7 |
+
("🌎 World", "WOR"),
|
8 |
+
("🇪🇺 Europe", "EEE"),
|
9 |
+
("🇿🇼 Zimbabwe", "ZWE"),
|
10 |
+
("🇿🇲 Zambia", "ZMB"),
|
11 |
+
("🇿🇦 South Africa", "ZAF"),
|
12 |
+
("🇾🇪 Yemen", "YEM"),
|
13 |
+
("🇻🇳 Vietnam", "VNM"),
|
14 |
+
("🇻🇪 Venezuela", "VEN"),
|
15 |
+
("🇺🇿 Uzbekistan", "UZB"),
|
16 |
+
("🇺🇾 Uruguay", "URY"),
|
17 |
+
("🇺🇸 United States", "USA"),
|
18 |
+
("🇺🇦 Ukraine", "UKR"),
|
19 |
+
("🇹🇿 Tanzania", "TZA"),
|
20 |
+
("🇹🇼 Taiwan", "TWN"),
|
21 |
+
("🇹🇹 Trinidad and Tobago", "TTO"),
|
22 |
+
("🇹🇷 Turkey", "TUR"),
|
23 |
+
("🇹🇳 Tunisia", "TUN"),
|
24 |
+
("🇹🇲 Turkmenistan", "TKM"),
|
25 |
+
("🇹🇯 Tajikistan", "TJK"),
|
26 |
+
("🇹🇭 Thailand", "THA"),
|
27 |
+
("🇹🇬 Togo", "TGO"),
|
28 |
+
("🇸🇾 Syrian Arab Republic", "SYR"),
|
29 |
+
("🇸🇻 El Salvador", "SLV"),
|
30 |
+
("🇸🇳 Senegal", "SEN"),
|
31 |
+
("🇸🇰 Slovak Republic", "SVK"),
|
32 |
+
("🇸🇮 Slovenia", "SVN"),
|
33 |
+
("🇸🇬 Singapore", "SGP"),
|
34 |
+
("🇸🇪 Sweden", "SWE"),
|
35 |
+
("🇸🇩 Sudan", "SDN"),
|
36 |
+
("🇸🇦 Saudi Arabia", "SAU"),
|
37 |
+
("🇷🇺 Russian Federation", "RUS"),
|
38 |
+
("🇷🇸 Serbia and Montenegro", "SCG"),
|
39 |
+
("🇷🇴 Romania", "ROU"),
|
40 |
+
("🇶🇦 Qatar", "QAT"),
|
41 |
+
("🇵🇾 Paraguay", "PRY"),
|
42 |
+
("🇵🇹 Portugal", "PRT"),
|
43 |
+
("🇵🇱 Poland", "POL"),
|
44 |
+
("🇵🇰 Pakistan", "PAK"),
|
45 |
+
("🇵🇭 Philippines", "PHL"),
|
46 |
+
("🇵🇪 Peru", "PER"),
|
47 |
+
("🇵🇦 Panama", "PAN"),
|
48 |
+
("🇴🇲 Oman", "OMN"),
|
49 |
+
("🇳🇿 New Zealand", "NZL"),
|
50 |
+
("🇳🇵 Nepal", "NPL"),
|
51 |
+
("🇳🇴 Norway", "NOR"),
|
52 |
+
("🇳🇱 Netherlands", "NLD"),
|
53 |
+
("🇳🇮 Nicaragua", "NIC"),
|
54 |
+
("🇳🇬 Nigeria", "NGA"),
|
55 |
+
("🇳🇦 Namibia", "NAM"),
|
56 |
+
("🇲🇿 Mozambique", "MOZ"),
|
57 |
+
("🇲🇾 Malaysia", "MYS"),
|
58 |
+
("🇲🇽 Mexico", "MEX"),
|
59 |
+
("🇲🇹 Malta", "MLT"),
|
60 |
+
("🇲🇳 Mongolia", "MNG"),
|
61 |
+
("🇲🇲 Myanmar", "MMR"),
|
62 |
+
("🇲🇰 North Macedonia", "MKD"),
|
63 |
+
("🇲🇩 Moldova", "MDA"),
|
64 |
+
("🇲🇦 Morocco", "MAR"),
|
65 |
+
("🇱🇾 Libya", "LBY"),
|
66 |
+
("🇱🇻 Latvia", "LVA"),
|
67 |
+
("🇱🇺 Luxembourg", "LUX"),
|
68 |
+
("🇱🇹 Lithuania", "LTU"),
|
69 |
+
("🇱🇰 Sri Lanka", "LKA"),
|
70 |
+
("🇱🇧 Lebanon", "LBN"),
|
71 |
+
("🇰🇿 Kazakhstan", "KAZ"),
|
72 |
+
("🇰🇼 Kuwait", "KWT"),
|
73 |
+
("🇰🇷 South Korea", "KOR"),
|
74 |
+
("🇰🇵 North Korea", "PRK"),
|
75 |
+
("🇰🇭 Cambodia", "KHM"),
|
76 |
+
("🇰🇬 Kyrgyz Republic", "KGZ"),
|
77 |
+
("🇰🇪 Kenya", "KEN"),
|
78 |
+
("🇯🇵 Japan", "JPN"),
|
79 |
+
("🇯🇴 Jordan", "JOR"),
|
80 |
+
("🇯🇲 Jamaica", "JAM"),
|
81 |
+
("🇮🇹 Italy", "ITA"),
|
82 |
+
("🇮🇸 Iceland", "ISL"),
|
83 |
+
("🇮🇷 Iran", "IRN"),
|
84 |
+
("🇮🇶 Iraq", "IRQ"),
|
85 |
+
("🇮🇳 India", "IND"),
|
86 |
+
("🇮🇱 Israel", "ISR"),
|
87 |
+
("🇮🇪 Ireland", "IRL"),
|
88 |
+
("🇮🇩 Indonesia", "IDN"),
|
89 |
+
("🇭🇺 Hungary", "HUN"),
|
90 |
+
("🇭🇹 Haiti", "HTI"),
|
91 |
+
("🇭🇷 Croatia", "HRV"),
|
92 |
+
("🇭🇳 Honduras", "HND"),
|
93 |
+
("🇭🇰 Hong Kong", "HKG"),
|
94 |
+
("🇬🇹 Guatemala", "GTM"),
|
95 |
+
("🇬🇷 Greece", "GRC"),
|
96 |
+
("🇬🇮 Gibraltar", "GIB"),
|
97 |
+
("🇬🇭 Ghana", "GHA"),
|
98 |
+
("🇬🇪 Georgia", "GEO"),
|
99 |
+
("🇬🇧 United Kingdom", "GBR"),
|
100 |
+
("🇬🇦 Gabon", "GAB"),
|
101 |
+
("🇫🇷 France", "FRA"),
|
102 |
+
("🇫🇮 Finland", "FIN"),
|
103 |
+
("🇪🇹 Ethiopia", "ETH"),
|
104 |
+
("🇪🇸 Spain", "ESP"),
|
105 |
+
("🇪🇷 Eritrea", "ERI"),
|
106 |
+
("🇪🇬 Egypt", "EGY"),
|
107 |
+
("🇪🇪 Estonia", "EST"),
|
108 |
+
("🇪🇨 Ecuador", "ECU"),
|
109 |
+
("🇩🇿 Algeria", "DZA"),
|
110 |
+
("🇩🇴 Dominican Republic", "DOM"),
|
111 |
+
("🇩🇰 Denmark", "DNK"),
|
112 |
+
("🇩🇪 Germany", "DEU"),
|
113 |
+
("🇨🇿 Czech Republic", "CZE"),
|
114 |
+
("🇨🇾 Cyprus", "CYP"),
|
115 |
+
("🇨🇺 Cuba", "CUB"),
|
116 |
+
("🇨🇷 Costa Rica", "CRI"),
|
117 |
+
("🇨🇴 Colombia", "COL"),
|
118 |
+
("🇨🇳 China", "CHN"),
|
119 |
+
("🇨🇲 Cameroon", "CMR"),
|
120 |
+
("🇨🇱 Chile", "CHL"),
|
121 |
+
("🇨🇮 Cote d'Ivoire", "CIV"),
|
122 |
+
("🇨🇭 Switzerland", "CHE"),
|
123 |
+
("🇨🇬 Congo", "COG"),
|
124 |
+
("🇨🇩 Democratic Republic of the Congo", "COD"),
|
125 |
+
("🇨🇦 Canada", "CAN"),
|
126 |
+
("🇧🇾 Belarus", "BLR"),
|
127 |
+
("🇧🇼 Botswana", "BWA"),
|
128 |
+
("🇧🇷 Brazil", "BRA"),
|
129 |
+
("🇧🇴 Bolivia", "BOL"),
|
130 |
+
("🇧🇳 Brunei", "BRN"),
|
131 |
+
("🇧🇯 Benin", "BEN"),
|
132 |
+
("🇧🇭 Bahrain", "BHR"),
|
133 |
+
("🇧🇬 Bulgaria", "BGR"),
|
134 |
+
("🇧🇪 Belgium", "BEL"),
|
135 |
+
("🇧🇩 Bangladesh", "BGD"),
|
136 |
+
("🇧🇦 Bosnia and Herzegovina", "BIH"),
|
137 |
+
("🇦🇿 Azerbaijan", "AZE"),
|
138 |
+
("🇦🇺 Australia", "AUS"),
|
139 |
+
("🇦🇹 Austria", "AUT"),
|
140 |
+
("🇦🇷 Argentina", "ARG"),
|
141 |
+
("🇦🇴 Angola", "AGO"),
|
142 |
+
("🇦 Netherlands Antilles", "ANT"),
|
143 |
+
("🇦🇲 Armenia", "ARM"),
|
144 |
+
("🇦🇱 Albania", "ALB"),
|
145 |
+
("🇦🇪 United Arab Emirates", "ARE")
|
146 |
+
]
|
147 |
+
|
148 |
+
|
149 |
+
def find_electricity_mix(code: str):
|
150 |
+
# TODO: Maybe more optimal to construct database at the beginning of the app
|
151 |
+
# in the same fashion as find_model
|
152 |
+
res = []
|
153 |
+
with open(PATH) as fd:
|
154 |
+
csv = DictReader(fd)
|
155 |
+
for row in csv:
|
156 |
+
res += [float(row[code])]
|
157 |
+
return res
|
158 |
+
|
159 |
+
def dataframe_electricity_mix(countries: list):
|
160 |
+
|
161 |
+
df = pd.read_csv('src/data/electricity_mix.csv')
|
162 |
+
df['name_unit'] = df['name'] + ' (' + df['unit'] + ')'
|
163 |
+
df = df[['name_unit'] + [x[1] for x in COUNTRY_CODES if x[0] in countries]]
|
164 |
+
|
165 |
+
df_melted = df.melt(
|
166 |
+
id_vars=['name_unit'],
|
167 |
+
value_vars=[x[1] for x in COUNTRY_CODES if x[0] in countries],
|
168 |
+
var_name='country',
|
169 |
+
value_name='value')
|
170 |
+
|
171 |
+
df = df_melted.pivot(columns='name_unit',
|
172 |
+
index='country',
|
173 |
+
values='value')
|
174 |
+
|
175 |
+
return df
|
src/expert.py
ADDED
@@ -0,0 +1,156 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import streamlit as st
|
2 |
+
import pandas as pd
|
3 |
+
from ecologits.impacts.llm import compute_llm_impacts
|
4 |
+
|
5 |
+
from src.utils import format_impacts, average_range_impacts, format_impacts_expert, model_active_params_fn, model_total_params_fn
|
6 |
+
from src.impacts import display_impacts
|
7 |
+
#from src.constants import PROVIDERS, MODELS
|
8 |
+
from src.electricity_mix import COUNTRY_CODES, find_electricity_mix, dataframe_electricity_mix
|
9 |
+
from ecologits.model_repository import models
|
10 |
+
|
11 |
+
import plotly.express as px
|
12 |
+
|
13 |
+
def reset_model():
|
14 |
+
model = 'CUSTOM'
|
15 |
+
|
16 |
+
def expert_mode():
|
17 |
+
|
18 |
+
st.markdown("### 🤓 Expert mode")
|
19 |
+
|
20 |
+
with st.container(border = True):
|
21 |
+
|
22 |
+
########## Model info ##########
|
23 |
+
|
24 |
+
# col1, col2, col3 = st.columns(3)
|
25 |
+
|
26 |
+
# with col1:
|
27 |
+
# provider = st.selectbox(label = 'Provider expert',
|
28 |
+
# options = [x[0] for x in PROVIDERS],
|
29 |
+
# index = 0)
|
30 |
+
# provider = [x[1] for x in PROVIDERS if x[0] == provider][0]
|
31 |
+
# if 'huggingface_hub' in provider:
|
32 |
+
# provider = 'huggingface_hub'
|
33 |
+
|
34 |
+
# with col2:
|
35 |
+
# model = st.selectbox('Model expert', [x[0] for x in MODELS if provider in x[1]])
|
36 |
+
# model = [x[1] for x in MODELS if x[0] == model][0].split('/', 1)[1]
|
37 |
+
|
38 |
+
########## Model parameters ##########
|
39 |
+
|
40 |
+
col11, col22, col33 = st.columns(3)
|
41 |
+
|
42 |
+
with col11:
|
43 |
+
# st.write(provider, model)
|
44 |
+
# st.write(models.find_model(provider, model))
|
45 |
+
# st.write(model_active_params_fn(provider, model, 45))
|
46 |
+
active_params = st.number_input('Active parameters (B)', 0, None, 45)
|
47 |
+
|
48 |
+
with col22:
|
49 |
+
total_params = st.number_input('Total parameters (B)', 0, None, 45)
|
50 |
+
|
51 |
+
with col33:
|
52 |
+
output_tokens = st.number_input('Output completion tokens', 100)
|
53 |
+
|
54 |
+
########## Electricity mix ##########
|
55 |
+
|
56 |
+
location = st.selectbox('Location', [x[0] for x in COUNTRY_CODES])
|
57 |
+
|
58 |
+
col4, col5, col6 = st.columns(3)
|
59 |
+
|
60 |
+
with col4:
|
61 |
+
mix_gwp = st.number_input('Electricity mix - GHG emissions [kgCO2eq / kWh]', find_electricity_mix([x[1] for x in COUNTRY_CODES if x[0] ==location][0])[2], format="%0.6f")
|
62 |
+
#disp_ranges = st.toggle('Display impact ranges', False)
|
63 |
+
with col5:
|
64 |
+
mix_adpe = st.number_input('Electricity mix - Abiotic resources [kgSbeq / kWh]', find_electricity_mix([x[1] for x in COUNTRY_CODES if x[0] ==location][0])[0], format="%0.13f")
|
65 |
+
with col6:
|
66 |
+
mix_pe = st.number_input('Electricity mix - Primary energy [MJ / kWh]', find_electricity_mix([x[1] for x in COUNTRY_CODES if x[0] ==location][0])[1], format="%0.3f")
|
67 |
+
|
68 |
+
impacts = compute_llm_impacts(model_active_parameter_count=active_params,
|
69 |
+
model_total_parameter_count=total_params,
|
70 |
+
output_token_count=output_tokens,
|
71 |
+
request_latency=100000,
|
72 |
+
if_electricity_mix_gwp=mix_gwp,
|
73 |
+
if_electricity_mix_adpe=mix_adpe,
|
74 |
+
if_electricity_mix_pe=mix_pe
|
75 |
+
)
|
76 |
+
|
77 |
+
impacts, usage, embodied = format_impacts(impacts)
|
78 |
+
|
79 |
+
with st.container(border = True):
|
80 |
+
|
81 |
+
st.markdown('<h3 align="center">Environmental Impacts</h2>', unsafe_allow_html = True)
|
82 |
+
|
83 |
+
display_impacts(impacts)
|
84 |
+
|
85 |
+
with st.expander('⚖️ Usage vs Embodied'):
|
86 |
+
|
87 |
+
st.markdown('<h3 align="center">Embodied vs Usage comparison</h2>', unsafe_allow_html = True)
|
88 |
+
|
89 |
+
st.markdown('The usage impacts account for the electricity consumption of the model while the embodied impacts account for resource extraction (e.g., minerals and metals), manufacturing, and transportation of the hardware.')
|
90 |
+
|
91 |
+
col_ghg_comparison, col_adpe_comparison, col_pe_comparison = st.columns(3)
|
92 |
+
|
93 |
+
with col_ghg_comparison:
|
94 |
+
fig_gwp = px.pie(
|
95 |
+
values = [average_range_impacts(usage.gwp.value), average_range_impacts(embodied.gwp.value)],
|
96 |
+
names = ['usage', 'embodied'],
|
97 |
+
title = 'GHG emissions',
|
98 |
+
color_discrete_sequence=["#636EFA", "#00CC96"],
|
99 |
+
width = 100
|
100 |
+
)
|
101 |
+
fig_gwp.update_layout(showlegend=False, title_x=0.5)
|
102 |
+
|
103 |
+
st.plotly_chart(fig_gwp)
|
104 |
+
|
105 |
+
with col_adpe_comparison:
|
106 |
+
fig_adpe = px.pie(
|
107 |
+
values = [average_range_impacts(usage.adpe.value), average_range_impacts(embodied.adpe.value)],
|
108 |
+
names = ['usage', 'embodied'],
|
109 |
+
title = 'Abiotic depletion',
|
110 |
+
color_discrete_sequence=["#00CC96","#636EFA"],
|
111 |
+
width = 100)
|
112 |
+
fig_adpe.update_layout(
|
113 |
+
showlegend=True,
|
114 |
+
legend=dict(yanchor="bottom", x = 0.35, y = -0.1),
|
115 |
+
title_x=0.5)
|
116 |
+
|
117 |
+
st.plotly_chart(fig_adpe)
|
118 |
+
|
119 |
+
with col_pe_comparison:
|
120 |
+
fig_pe = px.pie(
|
121 |
+
values = [average_range_impacts(usage.pe.value), average_range_impacts(embodied.pe.value)],
|
122 |
+
names = ['usage', 'embodied'],
|
123 |
+
title = 'Primary energy',
|
124 |
+
color_discrete_sequence=["#636EFA", "#00CC96"],
|
125 |
+
width = 100)
|
126 |
+
fig_pe.update_layout(showlegend=False, title_x=0.5)
|
127 |
+
|
128 |
+
st.plotly_chart(fig_pe)
|
129 |
+
|
130 |
+
with st.expander('🌍️ Location impact'):
|
131 |
+
|
132 |
+
st.markdown('<h4 align="center">How can location impact the footprint ?</h4>', unsafe_allow_html = True)
|
133 |
+
|
134 |
+
countries_to_compare = st.multiselect(
|
135 |
+
label = 'Countries to compare',
|
136 |
+
options = [x[0] for x in COUNTRY_CODES],
|
137 |
+
default = ["🇫🇷 France", "🇺🇸 United States", "🇨🇳 China"]
|
138 |
+
)
|
139 |
+
|
140 |
+
try:
|
141 |
+
|
142 |
+
df = dataframe_electricity_mix(countries_to_compare)
|
143 |
+
|
144 |
+
impact_type = st.selectbox(
|
145 |
+
label='Select an impact type to compare',
|
146 |
+
options=[x for x in df.columns if x!='country'],
|
147 |
+
index=1)
|
148 |
+
|
149 |
+
df.sort_values(by = impact_type, inplace = True)
|
150 |
+
|
151 |
+
fig_2 = px.bar(df, x = df.index, y = impact_type, text = impact_type, color = impact_type)
|
152 |
+
st.plotly_chart(fig_2)
|
153 |
+
|
154 |
+
except:
|
155 |
+
|
156 |
+
st.warning("Can't display chart with no values.")
|
src/impacts.py
ADDED
@@ -0,0 +1,116 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import streamlit as st
|
2 |
+
import ecologits
|
3 |
+
from src.utils import (
|
4 |
+
format_energy_eq_electric_vehicle,
|
5 |
+
format_energy_eq_electricity_consumption_ireland,
|
6 |
+
format_energy_eq_electricity_production,
|
7 |
+
format_energy_eq_physical_activity,
|
8 |
+
format_gwp_eq_airplane_paris_nyc,
|
9 |
+
format_gwp_eq_streaming,
|
10 |
+
PhysicalActivity,
|
11 |
+
EnergyProduction
|
12 |
+
)
|
13 |
+
|
14 |
+
############################################################################################################
|
15 |
+
|
16 |
+
def get_impacts(model, active_params, total_params, mix_ghg, mix_adpe, mix_pe):
|
17 |
+
|
18 |
+
return 1
|
19 |
+
|
20 |
+
############################################################################################################
|
21 |
+
|
22 |
+
|
23 |
+
def display_impacts(impacts):
|
24 |
+
|
25 |
+
st.divider()
|
26 |
+
|
27 |
+
col_energy, col_ghg, col_adpe, col_pe, col_water = st.columns(5)
|
28 |
+
|
29 |
+
with col_energy:
|
30 |
+
st.markdown('<h4 align="center">⚡️ Energy</h4>', unsafe_allow_html = True)
|
31 |
+
st.latex(f'\Large {impacts.energy.magnitude:.3g} \ \large {impacts.energy.units}')
|
32 |
+
st.markdown(f'<p align="center"><i>Evaluates the electricity consumption<i></p>', unsafe_allow_html = True)
|
33 |
+
|
34 |
+
with col_ghg:
|
35 |
+
st.markdown('<h4 align="center">🌍️ GHG Emissions</h4>', unsafe_allow_html = True)
|
36 |
+
st.latex(f'\Large {impacts.gwp.magnitude:.3g} \ \large {impacts.gwp.units}')
|
37 |
+
st.markdown(f'<p align="center"><i>Evaluates the effect on global warming<i></p>', unsafe_allow_html = True)
|
38 |
+
|
39 |
+
with col_adpe:
|
40 |
+
st.markdown('<h4 align="center">🪨 Abiotic Resources</h4>', unsafe_allow_html = True)
|
41 |
+
st.latex(f'\Large {impacts.adpe.magnitude:.3g} \ \large {impacts.adpe.units}')
|
42 |
+
st.markdown(f'<p align="center"><i>Evaluates the use of metals and minerals<i></p>', unsafe_allow_html = True)
|
43 |
+
|
44 |
+
with col_pe:
|
45 |
+
st.markdown('<h4 align="center">⛽️ Primary Energy</h4>', unsafe_allow_html = True)
|
46 |
+
st.latex(f'\Large {impacts.pe.magnitude:.3g} \ \large {impacts.pe.units}')
|
47 |
+
st.markdown(f'<p align="center"><i>Evaluates the use of energy resources<i></p>', unsafe_allow_html = True)
|
48 |
+
|
49 |
+
with col_water:
|
50 |
+
st.markdown('<h4 align="center">🚰 Water</h4>', unsafe_allow_html = True)
|
51 |
+
st.latex('\Large Upcoming...')
|
52 |
+
st.markdown(f'<p align="center"><i>Evaluates the use of water<i></p>', unsafe_allow_html = True)
|
53 |
+
|
54 |
+
############################################################################################################
|
55 |
+
|
56 |
+
def display_equivalent(impacts):
|
57 |
+
|
58 |
+
st.divider()
|
59 |
+
|
60 |
+
ev_eq = format_energy_eq_electric_vehicle(impacts.energy)
|
61 |
+
|
62 |
+
streaming_eq = format_gwp_eq_streaming(impacts.gwp)
|
63 |
+
|
64 |
+
col1, col2, col3 = st.columns(3)
|
65 |
+
|
66 |
+
with col1:
|
67 |
+
physical_activity, distance = format_energy_eq_physical_activity(impacts.energy)
|
68 |
+
if physical_activity == PhysicalActivity.WALKING:
|
69 |
+
physical_activity = "🚶 " + physical_activity.capitalize()
|
70 |
+
if physical_activity == PhysicalActivity.RUNNING:
|
71 |
+
physical_activity = "🏃 " + physical_activity.capitalize()
|
72 |
+
|
73 |
+
st.markdown(f'<h4 align="center">{physical_activity}</h4>', unsafe_allow_html = True)
|
74 |
+
st.latex(f'\Large {distance.magnitude:.3g} \ \large {distance.units}')
|
75 |
+
st.markdown(f'<p align="center"><i>Based on energy consumption<i></p>', unsafe_allow_html = True)
|
76 |
+
|
77 |
+
with col2:
|
78 |
+
ev_eq = format_energy_eq_electric_vehicle(impacts.energy)
|
79 |
+
st.markdown(f'<h4 align="center">🔋 Electric Vehicle</h4>', unsafe_allow_html = True)
|
80 |
+
st.latex(f'\Large {ev_eq.magnitude:.3g} \ \large {ev_eq.units}')
|
81 |
+
st.markdown(f'<p align="center"><i>Based on energy consumption<i></p>', unsafe_allow_html = True)
|
82 |
+
|
83 |
+
with col3:
|
84 |
+
streaming_eq = format_gwp_eq_streaming(impacts.gwp)
|
85 |
+
st.markdown(f'<h4 align="center">⏯️ Streaming</h4>', unsafe_allow_html = True)
|
86 |
+
st.latex(f'\Large {streaming_eq.magnitude:.3g} \ \large {streaming_eq.units}')
|
87 |
+
st.markdown(f'<p align="center"><i>Based on GHG emissions<i></p>', unsafe_allow_html = True)
|
88 |
+
|
89 |
+
st.divider()
|
90 |
+
|
91 |
+
st.markdown('<h3 align="center">What if 1% of the planet does this request everyday for 1 year ?</h3>', unsafe_allow_html = True)
|
92 |
+
st.markdown('<p align="center">If this use case is largely deployed around the world, the equivalent impacts would be the impacts of this request x 1% of 8 billion people x 365 days in a year.</p>', unsafe_allow_html = True)
|
93 |
+
|
94 |
+
col4, col5, col6 = st.columns(3)
|
95 |
+
|
96 |
+
with col4:
|
97 |
+
|
98 |
+
electricity_production, count = format_energy_eq_electricity_production(impacts.energy)
|
99 |
+
if electricity_production == EnergyProduction.NUCLEAR:
|
100 |
+
emoji = "☢️"
|
101 |
+
name = "Nuclear power plants"
|
102 |
+
if electricity_production == EnergyProduction.WIND:
|
103 |
+
emoji = "💨️ "
|
104 |
+
name = "Wind turbines"
|
105 |
+
st.markdown(f'<h4 align="center">{emoji} {count.magnitude:.0f} {name} (yearly)</h4>', unsafe_allow_html = True)
|
106 |
+
st.markdown(f'<p align="center"><i>Based on energy consumption<i></p>', unsafe_allow_html = True)
|
107 |
+
|
108 |
+
with col5:
|
109 |
+
ireland_count = format_energy_eq_electricity_consumption_ireland(impacts.energy)
|
110 |
+
st.markdown(f'<h4 align="center">🇮🇪 {ireland_count.magnitude:.3f} x Ireland <span style="font-size: 12px">(yearly ⚡️ cons.)</span></h2></h4>', unsafe_allow_html = True)
|
111 |
+
st.markdown(f'<p align="center"><i>Based on energy consumption<i></p>', unsafe_allow_html = True)
|
112 |
+
|
113 |
+
with col6:
|
114 |
+
paris_nyc_airplane = format_gwp_eq_airplane_paris_nyc(impacts.gwp)
|
115 |
+
st.markdown(f'<h4 align="center">✈️ {round(paris_nyc_airplane.magnitude):,} Paris ↔ NYC</h4>', unsafe_allow_html = True)
|
116 |
+
st.markdown(f'<p align="center"><i>Based on GHG emissions<i></p>', unsafe_allow_html = True)
|
src/models.py
ADDED
@@ -0,0 +1,46 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import requests
|
2 |
+
import json
|
3 |
+
import pandas as pd
|
4 |
+
from src.constants import MODEL_REPOSITORY_URL
|
5 |
+
|
6 |
+
def clean_models_data(df):
|
7 |
+
|
8 |
+
dict_providers = {
|
9 |
+
'google': 'Google',
|
10 |
+
'mistralai': 'MistralAI',
|
11 |
+
'meta-llama': 'Meta',
|
12 |
+
'openai': 'OpenAI',
|
13 |
+
'anthropic': 'Anthropic',
|
14 |
+
'cohere': 'Cohere',
|
15 |
+
'microsoft': 'Microsoft',
|
16 |
+
'mistral-community': 'Mistral Community',
|
17 |
+
'databricks': 'Databricks'
|
18 |
+
}
|
19 |
+
|
20 |
+
df.drop('type', axis=1, inplace=True)
|
21 |
+
|
22 |
+
df.loc[df['name'].str.contains('/'), 'name_clean'] = df.loc[df['name'].str.contains('/'), 'name'].str.split('/').str[1]
|
23 |
+
df['name_clean'] = df['name_clean'].fillna(df['name'])
|
24 |
+
df['name_clean'] = df['name_clean'].replace({'-': ' '}, regex = True)
|
25 |
+
|
26 |
+
df.loc[df['provider'] == 'huggingface_hub', 'provider_clean'] = df.loc[df['provider'] == 'huggingface_hub', 'name'].str.split('/').str[0]
|
27 |
+
df['provider_clean'] = df['provider_clean'].fillna(df['provider'])
|
28 |
+
df['provider_clean'] = df['provider_clean'].replace(dict_providers, regex = True)
|
29 |
+
|
30 |
+
df['architecture_type'] = df['architecture'].apply(lambda x: x['type'])
|
31 |
+
df['architecture_parameters'] = df['architecture'].apply(lambda x: x['parameters'])
|
32 |
+
|
33 |
+
df['warnings'] = df['warnings'].apply(lambda x: ', '.join(x) if x else None).fillna('none')
|
34 |
+
df['warning_arch'] = df['warnings'].apply(lambda x: 'model-arch-not-released' in x)
|
35 |
+
df['warning_multi_modal'] = df['warnings'].apply(lambda x: 'model-arch-multimodal' in x)
|
36 |
+
|
37 |
+
return df[['provider', 'provider_clean', 'name', 'name_clean', 'architecture_type', 'architecture_parameters', 'warning_arch', 'warning_multi_modal']]
|
38 |
+
|
39 |
+
def load_models():
|
40 |
+
|
41 |
+
resp = requests.get(MODEL_REPOSITORY_URL)
|
42 |
+
data = json.loads(resp.text)
|
43 |
+
df = pd.DataFrame(data['models'])
|
44 |
+
|
45 |
+
return clean_models_data(df)
|
46 |
+
|
src/scrapper.py
DELETED
@@ -1,33 +0,0 @@
|
|
1 |
-
import requests
|
2 |
-
from bs4 import BeautifulSoup
|
3 |
-
import tiktoken
|
4 |
-
|
5 |
-
tokenizer = tiktoken.get_encoding('cl100k_base')
|
6 |
-
|
7 |
-
def process_input(text):
|
8 |
-
|
9 |
-
r = requests.get(text, verify=False)
|
10 |
-
|
11 |
-
soup = BeautifulSoup(r.text, "html.parser")
|
12 |
-
print(soup)
|
13 |
-
list_text = str(soup).split('parts":["')
|
14 |
-
#print(list_text)
|
15 |
-
s = ''
|
16 |
-
for item in list_text[1:int(len(list_text)/2)]:
|
17 |
-
if list_text.index(item)%2 == 1:
|
18 |
-
s = s + item.split('"]')[0]
|
19 |
-
|
20 |
-
amout_token = tiktoken_len(s)
|
21 |
-
|
22 |
-
return amout_token
|
23 |
-
|
24 |
-
def tiktoken_len(text):
|
25 |
-
tokens = tokenizer.encode(
|
26 |
-
text,
|
27 |
-
disallowed_special=()
|
28 |
-
)
|
29 |
-
return len(tokens)
|
30 |
-
|
31 |
-
answer = process_input('https://chatgpt.com/share/6737b9b5-56fc-8002-a212-35339f5b1d5a')
|
32 |
-
|
33 |
-
print(answer)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/utils.py
CHANGED
@@ -1,197 +1,262 @@
|
|
1 |
-
from dataclasses import dataclass
|
2 |
-
from enum import Enum
|
3 |
-
|
4 |
-
import pandas as pd
|
5 |
-
|
6 |
-
from ecologits.impacts.modeling import Impacts, Energy, GWP, ADPe, PE
|
7 |
-
from ecologits.tracers.utils import llm_impacts
|
8 |
-
from pint import UnitRegistry, Quantity
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
u
|
15 |
-
u.define('
|
16 |
-
u.define('
|
17 |
-
u.define('
|
18 |
-
u.define('
|
19 |
-
u.define('
|
20 |
-
u.define('
|
21 |
-
u.define('
|
22 |
-
u.define('
|
23 |
-
u.define('
|
24 |
-
u.define('
|
25 |
-
u.define('
|
26 |
-
u.define('
|
27 |
-
u.define('
|
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 |
-
# From https://www.runningtools.com/energyusage.htm
|
63 |
-
RUNNING_ENERGY_EQ = q("294 kJ / km") # running 1 km at 10 km/h with a weight of 70 kg
|
64 |
-
WALKING_ENERGY_EQ = q("196 kJ / km") # walking 1 km at 3 km/h with a weight of 70 kg
|
65 |
-
|
66 |
-
# From https://selectra.info/energie/actualites/insolite/consommation-vehicules-electriques-france-2040
|
67 |
-
# and https://www.tesla.com/fr_fr/support/power-consumption
|
68 |
-
EV_ENERGY_EQ = q("0.17 kWh / km")
|
69 |
-
|
70 |
-
# From https://impactco2.fr/outils/comparateur?value=1&comparisons=streamingvideo
|
71 |
-
STREAMING_GWP_EQ = q("15.6 h / kgCO2eq")
|
72 |
-
|
73 |
-
# From https://ourworldindata.org/population-growth
|
74 |
-
ONE_PERCENT_WORLD_POPULATION = 80_000_000
|
75 |
-
|
76 |
-
DAYS_IN_YEAR = 365
|
77 |
-
|
78 |
-
# For a 900 MW nuclear plant -> 500 000 MWh / month
|
79 |
-
# 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
|
80 |
-
YEARLY_NUCLEAR_ENERGY_EQ = q("6 TWh")
|
81 |
-
|
82 |
-
# For a 2MW wind turbine
|
83 |
-
# https://www.ecologie.gouv.fr/eolien-terrestre
|
84 |
-
YEARLY_WIND_ENERGY_EQ = q("4.2 GWh")
|
85 |
-
|
86 |
-
# Ireland yearly electricity consumption
|
87 |
-
# From https://en.wikipedia.org/wiki/List_of_countries_by_electricity_consumption
|
88 |
-
YEARLY_IRELAND_ELECTRICITY_CONSUMPTION = q("33 TWh")
|
89 |
-
IRELAND_POPULATION_MILLION = 5
|
90 |
-
|
91 |
-
# From https://impactco2.fr/outils/comparateur?value=1&comparisons=&equivalent=avion-pny
|
92 |
-
AIRPLANE_PARIS_NYC_GWP_EQ = q("177000 kgCO2eq")
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
val
|
115 |
-
|
116 |
-
|
117 |
-
return
|
118 |
-
|
119 |
-
def
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
)
|
131 |
-
|
132 |
-
return QImpacts(
|
133 |
-
energy=format_energy(impacts.energy),
|
134 |
-
gwp=format_gwp(impacts.gwp),
|
135 |
-
adpe=format_adpe(impacts.adpe),
|
136 |
-
pe=format_pe(impacts.pe)
|
137 |
-
)
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
def
|
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 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from dataclasses import dataclass
|
2 |
+
from enum import Enum
|
3 |
+
|
4 |
+
import pandas as pd
|
5 |
+
from ecologits.model_repository import models
|
6 |
+
from ecologits.impacts.modeling import Impacts, Energy, GWP, ADPe, PE
|
7 |
+
#from ecologits.tracers.utils import llm_impacts
|
8 |
+
from pint import UnitRegistry, Quantity
|
9 |
+
|
10 |
+
#####################################################################################
|
11 |
+
### UNITS DEFINITION
|
12 |
+
#####################################################################################
|
13 |
+
|
14 |
+
u = UnitRegistry()
|
15 |
+
u.define('Wh = watt_hour')
|
16 |
+
u.define('kWh = kilowatt_hour')
|
17 |
+
u.define('MWh = megawatt_hour')
|
18 |
+
u.define('GWh = gigawatt_hour')
|
19 |
+
u.define('TWh = terawatt_hour')
|
20 |
+
u.define('gCO2eq = gram')
|
21 |
+
u.define('kgCO2eq = kilogram')
|
22 |
+
u.define('tCO2eq = metricton')
|
23 |
+
u.define('kgSbeq = kilogram')
|
24 |
+
u.define('kJ = kilojoule')
|
25 |
+
u.define('MJ = megajoule')
|
26 |
+
u.define('m = meter')
|
27 |
+
u.define('km = kilometer')
|
28 |
+
u.define('s = second')
|
29 |
+
u.define('min = minute')
|
30 |
+
u.define('h = hour')
|
31 |
+
q = u.Quantity
|
32 |
+
|
33 |
+
@dataclass
|
34 |
+
class QImpacts:
|
35 |
+
energy: Quantity
|
36 |
+
gwp: Quantity
|
37 |
+
adpe: Quantity
|
38 |
+
pe: Quantity
|
39 |
+
|
40 |
+
|
41 |
+
class PhysicalActivity(str, Enum):
|
42 |
+
RUNNING = "running"
|
43 |
+
WALKING = "walking"
|
44 |
+
|
45 |
+
|
46 |
+
class EnergyProduction(str, Enum):
|
47 |
+
NUCLEAR = "nuclear"
|
48 |
+
WIND = "wind"
|
49 |
+
|
50 |
+
|
51 |
+
COUNTRIES = [
|
52 |
+
("cook_islands", 38.81, 9_556),
|
53 |
+
("tonga", 51.15, 104_490),
|
54 |
+
("comoros", 100, 821_632),
|
55 |
+
("samoa", 100, 821_632),
|
56 |
+
]
|
57 |
+
|
58 |
+
#####################################################################################
|
59 |
+
### EQUIVALENT RAW DATA
|
60 |
+
#####################################################################################
|
61 |
+
|
62 |
+
# From https://www.runningtools.com/energyusage.htm
|
63 |
+
RUNNING_ENERGY_EQ = q("294 kJ / km") # running 1 km at 10 km/h with a weight of 70 kg
|
64 |
+
WALKING_ENERGY_EQ = q("196 kJ / km") # walking 1 km at 3 km/h with a weight of 70 kg
|
65 |
+
|
66 |
+
# From https://selectra.info/energie/actualites/insolite/consommation-vehicules-electriques-france-2040
|
67 |
+
# and https://www.tesla.com/fr_fr/support/power-consumption
|
68 |
+
EV_ENERGY_EQ = q("0.17 kWh / km")
|
69 |
+
|
70 |
+
# From https://impactco2.fr/outils/comparateur?value=1&comparisons=streamingvideo
|
71 |
+
STREAMING_GWP_EQ = q("15.6 h / kgCO2eq")
|
72 |
+
|
73 |
+
# From https://ourworldindata.org/population-growth
|
74 |
+
ONE_PERCENT_WORLD_POPULATION = 80_000_000
|
75 |
+
|
76 |
+
DAYS_IN_YEAR = 365
|
77 |
+
|
78 |
+
# For a 900 MW nuclear plant -> 500 000 MWh / month
|
79 |
+
# 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
|
80 |
+
YEARLY_NUCLEAR_ENERGY_EQ = q("6 TWh")
|
81 |
+
|
82 |
+
# For a 2MW wind turbine
|
83 |
+
# https://www.ecologie.gouv.fr/eolien-terrestre
|
84 |
+
YEARLY_WIND_ENERGY_EQ = q("4.2 GWh")
|
85 |
+
|
86 |
+
# Ireland yearly electricity consumption
|
87 |
+
# From https://en.wikipedia.org/wiki/List_of_countries_by_electricity_consumption
|
88 |
+
YEARLY_IRELAND_ELECTRICITY_CONSUMPTION = q("33 TWh")
|
89 |
+
IRELAND_POPULATION_MILLION = 5
|
90 |
+
|
91 |
+
# From https://impactco2.fr/outils/comparateur?value=1&comparisons=&equivalent=avion-pny
|
92 |
+
AIRPLANE_PARIS_NYC_GWP_EQ = q("177000 kgCO2eq")
|
93 |
+
|
94 |
+
def filter_models(provider, list_models):
|
95 |
+
|
96 |
+
model = 1
|
97 |
+
|
98 |
+
return model
|
99 |
+
|
100 |
+
#####################################################################################
|
101 |
+
### IMPACTS FORMATING
|
102 |
+
#####################################################################################
|
103 |
+
|
104 |
+
def format_energy(energy: Energy) -> Quantity:
|
105 |
+
val = q(energy.value, energy.unit)
|
106 |
+
if val < q("1 kWh"):
|
107 |
+
val = val.to("Wh")
|
108 |
+
return val
|
109 |
+
|
110 |
+
def format_gwp(gwp: GWP) -> Quantity:
|
111 |
+
val = q(gwp.value, gwp.unit)
|
112 |
+
if val < q("1 kgCO2eq"):
|
113 |
+
val = val.to("gCO2eq")
|
114 |
+
return val
|
115 |
+
|
116 |
+
def format_adpe(adpe: ADPe) -> Quantity:
|
117 |
+
return q(adpe.value, adpe.unit)
|
118 |
+
|
119 |
+
def format_pe(pe: PE) -> Quantity:
|
120 |
+
val = q(pe.value, pe.unit)
|
121 |
+
if val < q("1 MJ"):
|
122 |
+
val = val.to("kJ")
|
123 |
+
return val
|
124 |
+
|
125 |
+
def format_impacts(impacts: Impacts) -> QImpacts:
|
126 |
+
|
127 |
+
try:
|
128 |
+
impacts.energy.value = (impacts.energy.value.max + impacts.energy.value.min)/2
|
129 |
+
impacts.gwp.value = (impacts.gwp.value.max + impacts.gwp.value.min)/2
|
130 |
+
impacts.adpe.value = (impacts.adpe.value.max + impacts.adpe.value.min)/2
|
131 |
+
impacts.pe.value = (impacts.pe.value.max + impacts.pe.value.min)/2
|
132 |
+
return QImpacts(
|
133 |
+
energy=format_energy(impacts.energy),
|
134 |
+
gwp=format_gwp(impacts.gwp),
|
135 |
+
adpe=format_adpe(impacts.adpe),
|
136 |
+
pe=format_pe(impacts.pe)
|
137 |
+
), impacts.usage, impacts.embodied
|
138 |
+
except: #when no range
|
139 |
+
return QImpacts(
|
140 |
+
energy=format_energy(impacts.energy),
|
141 |
+
gwp=format_gwp(impacts.gwp),
|
142 |
+
adpe=format_adpe(impacts.adpe),
|
143 |
+
pe=format_pe(impacts.pe)
|
144 |
+
), impacts.usage, impacts.embodied
|
145 |
+
|
146 |
+
def split_impacts_u_e(impacts: Impacts) -> QImpacts:
|
147 |
+
return impacts.usage, impacts.embodied
|
148 |
+
|
149 |
+
def average_range_impacts(RangeValue):
|
150 |
+
return (RangeValue.max + RangeValue.min)/2
|
151 |
+
|
152 |
+
def format_impacts_expert(impacts: Impacts, display_range: bool) -> QImpacts:
|
153 |
+
|
154 |
+
if display_range:
|
155 |
+
return QImpacts(
|
156 |
+
energy=format_energy(impacts.energy),
|
157 |
+
gwp=format_gwp(impacts.gwp),
|
158 |
+
adpe=format_adpe(impacts.adpe),
|
159 |
+
pe=format_pe(impacts.pe)
|
160 |
+
), impacts.usage, impacts.embodied
|
161 |
+
|
162 |
+
else:
|
163 |
+
energy = {"value":(impacts.energy.value.max + impacts.energy.value.min)/2, "unit":impacts.energy.unit}
|
164 |
+
gwp = (impacts.gwp.value.max + impacts.gwp.value.min)/2
|
165 |
+
adpe = (impacts.adpe.value.max + impacts.adpe.value.min)/2
|
166 |
+
pe = (impacts.pe.value.max + impacts.pe.value.min)/2
|
167 |
+
return QImpacts(
|
168 |
+
energy=format_energy(energy),
|
169 |
+
gwp=format_gwp(gwp),
|
170 |
+
adpe=format_adpe(adpe),
|
171 |
+
pe=format_pe(pe)
|
172 |
+
), impacts.usage, impacts.embodied
|
173 |
+
|
174 |
+
#####################################################################################
|
175 |
+
### EQUIVALENT FORMATING
|
176 |
+
#####################################################################################
|
177 |
+
|
178 |
+
def format_energy_eq_physical_activity(energy: Quantity) -> tuple[PhysicalActivity, Quantity]:
|
179 |
+
energy = energy.to("kJ")
|
180 |
+
running_eq = energy / RUNNING_ENERGY_EQ
|
181 |
+
if running_eq > q("1 km"):
|
182 |
+
return PhysicalActivity.RUNNING, running_eq
|
183 |
+
|
184 |
+
walking_eq = energy / WALKING_ENERGY_EQ
|
185 |
+
if walking_eq < q("1 km"):
|
186 |
+
walking_eq = walking_eq.to("meter")
|
187 |
+
return PhysicalActivity.WALKING, walking_eq
|
188 |
+
|
189 |
+
def format_energy_eq_electric_vehicle(energy: Quantity) -> Quantity:
|
190 |
+
energy = energy.to("kWh")
|
191 |
+
ev_eq = energy / EV_ENERGY_EQ
|
192 |
+
if ev_eq < q("1 km"):
|
193 |
+
ev_eq = ev_eq.to("meter")
|
194 |
+
return ev_eq
|
195 |
+
|
196 |
+
def format_gwp_eq_streaming(gwp: Quantity) -> Quantity:
|
197 |
+
gwp = gwp.to("kgCO2eq")
|
198 |
+
streaming_eq = gwp * STREAMING_GWP_EQ
|
199 |
+
if streaming_eq < q("1 h"):
|
200 |
+
streaming_eq = streaming_eq.to("min")
|
201 |
+
if streaming_eq < q("1 min"):
|
202 |
+
streaming_eq = streaming_eq.to("s")
|
203 |
+
return streaming_eq
|
204 |
+
|
205 |
+
def format_energy_eq_electricity_production(energy: Quantity) -> tuple[EnergyProduction, Quantity]:
|
206 |
+
electricity_eq = energy * ONE_PERCENT_WORLD_POPULATION * DAYS_IN_YEAR
|
207 |
+
electricity_eq = electricity_eq.to("TWh")
|
208 |
+
if electricity_eq > YEARLY_NUCLEAR_ENERGY_EQ:
|
209 |
+
return EnergyProduction.NUCLEAR, electricity_eq / YEARLY_NUCLEAR_ENERGY_EQ
|
210 |
+
electricity_eq = electricity_eq.to("GWh")
|
211 |
+
return EnergyProduction.WIND, electricity_eq / YEARLY_WIND_ENERGY_EQ
|
212 |
+
|
213 |
+
|
214 |
+
def format_energy_eq_electricity_consumption_ireland(energy: Quantity) -> Quantity:
|
215 |
+
electricity_eq = energy * ONE_PERCENT_WORLD_POPULATION * DAYS_IN_YEAR
|
216 |
+
electricity_eq = electricity_eq.to("TWh")
|
217 |
+
return electricity_eq / YEARLY_IRELAND_ELECTRICITY_CONSUMPTION
|
218 |
+
|
219 |
+
def format_gwp_eq_airplane_paris_nyc(gwp: Quantity) -> Quantity:
|
220 |
+
gwp_eq = gwp * ONE_PERCENT_WORLD_POPULATION * DAYS_IN_YEAR
|
221 |
+
gwp_eq = gwp_eq.to("kgCO2eq")
|
222 |
+
return gwp_eq / AIRPLANE_PARIS_NYC_GWP_EQ
|
223 |
+
|
224 |
+
#####################################################################################
|
225 |
+
### MODELS PARAMETERS
|
226 |
+
#####################################################################################
|
227 |
+
|
228 |
+
def model_active_params_fn(provider_name: str, model_name: str, n_param: float):
|
229 |
+
if model_name == 'CUSTOM':
|
230 |
+
return n_param
|
231 |
+
else:
|
232 |
+
model = models.find_model(provider=provider_name, model_name=model_name)
|
233 |
+
|
234 |
+
if model.architecture == 'moe':
|
235 |
+
try:
|
236 |
+
return model.architecture.parameters.active.max
|
237 |
+
except:
|
238 |
+
try:
|
239 |
+
return model.architecture.parameters.active
|
240 |
+
except:
|
241 |
+
return model.architecture.parameters
|
242 |
+
elif model.architecture == 'dense':
|
243 |
+
try: #dense with range
|
244 |
+
return model.architecture.parameters.max
|
245 |
+
except: #dense without range
|
246 |
+
return model.architecture.parameters
|
247 |
+
|
248 |
+
def model_total_params_fn(provider_name: str, model_name: str, n_param: float):
|
249 |
+
if model_name == 'CUSTOM':
|
250 |
+
return n_param
|
251 |
+
provider, model_name = model_name.split('/', 1)
|
252 |
+
model = models.find_model(provider=provider, model_name=model_name)
|
253 |
+
try: #moe
|
254 |
+
return model.architecture.parameters.total.max
|
255 |
+
except:
|
256 |
+
try: #dense with range
|
257 |
+
return model.architecture.parameters.max
|
258 |
+
except: #dense without range
|
259 |
+
try:
|
260 |
+
return model.architecture.parameters.total
|
261 |
+
except:
|
262 |
+
return model.architecture.parameters
|
utils.py
ADDED
@@ -0,0 +1,262 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from dataclasses import dataclass
|
2 |
+
from enum import Enum
|
3 |
+
|
4 |
+
import pandas as pd
|
5 |
+
from ecologits.model_repository import models
|
6 |
+
from ecologits.impacts.modeling import Impacts, Energy, GWP, ADPe, PE
|
7 |
+
#from ecologits.tracers.utils import llm_impacts
|
8 |
+
from pint import UnitRegistry, Quantity
|
9 |
+
|
10 |
+
#####################################################################################
|
11 |
+
### UNITS DEFINITION
|
12 |
+
#####################################################################################
|
13 |
+
|
14 |
+
u = UnitRegistry()
|
15 |
+
u.define('Wh = watt_hour')
|
16 |
+
u.define('kWh = kilowatt_hour')
|
17 |
+
u.define('MWh = megawatt_hour')
|
18 |
+
u.define('GWh = gigawatt_hour')
|
19 |
+
u.define('TWh = terawatt_hour')
|
20 |
+
u.define('gCO2eq = gram')
|
21 |
+
u.define('kgCO2eq = kilogram')
|
22 |
+
u.define('tCO2eq = metricton')
|
23 |
+
u.define('kgSbeq = kilogram')
|
24 |
+
u.define('kJ = kilojoule')
|
25 |
+
u.define('MJ = megajoule')
|
26 |
+
u.define('m = meter')
|
27 |
+
u.define('km = kilometer')
|
28 |
+
u.define('s = second')
|
29 |
+
u.define('min = minute')
|
30 |
+
u.define('h = hour')
|
31 |
+
q = u.Quantity
|
32 |
+
|
33 |
+
@dataclass
|
34 |
+
class QImpacts:
|
35 |
+
energy: Quantity
|
36 |
+
gwp: Quantity
|
37 |
+
adpe: Quantity
|
38 |
+
pe: Quantity
|
39 |
+
|
40 |
+
|
41 |
+
class PhysicalActivity(str, Enum):
|
42 |
+
RUNNING = "running"
|
43 |
+
WALKING = "walking"
|
44 |
+
|
45 |
+
|
46 |
+
class EnergyProduction(str, Enum):
|
47 |
+
NUCLEAR = "nuclear"
|
48 |
+
WIND = "wind"
|
49 |
+
|
50 |
+
|
51 |
+
COUNTRIES = [
|
52 |
+
("cook_islands", 38.81, 9_556),
|
53 |
+
("tonga", 51.15, 104_490),
|
54 |
+
("comoros", 100, 821_632),
|
55 |
+
("samoa", 100, 821_632),
|
56 |
+
]
|
57 |
+
|
58 |
+
#####################################################################################
|
59 |
+
### EQUIVALENT RAW DATA
|
60 |
+
#####################################################################################
|
61 |
+
|
62 |
+
# From https://www.runningtools.com/energyusage.htm
|
63 |
+
RUNNING_ENERGY_EQ = q("294 kJ / km") # running 1 km at 10 km/h with a weight of 70 kg
|
64 |
+
WALKING_ENERGY_EQ = q("196 kJ / km") # walking 1 km at 3 km/h with a weight of 70 kg
|
65 |
+
|
66 |
+
# From https://selectra.info/energie/actualites/insolite/consommation-vehicules-electriques-france-2040
|
67 |
+
# and https://www.tesla.com/fr_fr/support/power-consumption
|
68 |
+
EV_ENERGY_EQ = q("0.17 kWh / km")
|
69 |
+
|
70 |
+
# From https://impactco2.fr/outils/comparateur?value=1&comparisons=streamingvideo
|
71 |
+
STREAMING_GWP_EQ = q("15.6 h / kgCO2eq")
|
72 |
+
|
73 |
+
# From https://ourworldindata.org/population-growth
|
74 |
+
ONE_PERCENT_WORLD_POPULATION = 80_000_000
|
75 |
+
|
76 |
+
DAYS_IN_YEAR = 365
|
77 |
+
|
78 |
+
# For a 900 MW nuclear plant -> 500 000 MWh / month
|
79 |
+
# 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
|
80 |
+
YEARLY_NUCLEAR_ENERGY_EQ = q("6 TWh")
|
81 |
+
|
82 |
+
# For a 2MW wind turbine
|
83 |
+
# https://www.ecologie.gouv.fr/eolien-terrestre
|
84 |
+
YEARLY_WIND_ENERGY_EQ = q("4.2 GWh")
|
85 |
+
|
86 |
+
# Ireland yearly electricity consumption
|
87 |
+
# From https://en.wikipedia.org/wiki/List_of_countries_by_electricity_consumption
|
88 |
+
YEARLY_IRELAND_ELECTRICITY_CONSUMPTION = q("33 TWh")
|
89 |
+
IRELAND_POPULATION_MILLION = 5
|
90 |
+
|
91 |
+
# From https://impactco2.fr/outils/comparateur?value=1&comparisons=&equivalent=avion-pny
|
92 |
+
AIRPLANE_PARIS_NYC_GWP_EQ = q("177000 kgCO2eq")
|
93 |
+
|
94 |
+
def filter_models(provider, list_models):
|
95 |
+
|
96 |
+
model = 1
|
97 |
+
|
98 |
+
return model
|
99 |
+
|
100 |
+
#####################################################################################
|
101 |
+
### IMPACTS FORMATING
|
102 |
+
#####################################################################################
|
103 |
+
|
104 |
+
def format_energy(energy: Energy) -> Quantity:
|
105 |
+
val = q(energy.value, energy.unit)
|
106 |
+
if val < q("1 kWh"):
|
107 |
+
val = val.to("Wh")
|
108 |
+
return val
|
109 |
+
|
110 |
+
def format_gwp(gwp: GWP) -> Quantity:
|
111 |
+
val = q(gwp.value, gwp.unit)
|
112 |
+
if val < q("1 kgCO2eq"):
|
113 |
+
val = val.to("gCO2eq")
|
114 |
+
return val
|
115 |
+
|
116 |
+
def format_adpe(adpe: ADPe) -> Quantity:
|
117 |
+
return q(adpe.value, adpe.unit)
|
118 |
+
|
119 |
+
def format_pe(pe: PE) -> Quantity:
|
120 |
+
val = q(pe.value, pe.unit)
|
121 |
+
if val < q("1 MJ"):
|
122 |
+
val = val.to("kJ")
|
123 |
+
return val
|
124 |
+
|
125 |
+
def format_impacts(impacts: Impacts) -> QImpacts:
|
126 |
+
|
127 |
+
try:
|
128 |
+
impacts.energy.value = (impacts.energy.value.max + impacts.energy.value.min)/2
|
129 |
+
impacts.gwp.value = (impacts.gwp.value.max + impacts.gwp.value.min)/2
|
130 |
+
impacts.adpe.value = (impacts.adpe.value.max + impacts.adpe.value.min)/2
|
131 |
+
impacts.pe.value = (impacts.pe.value.max + impacts.pe.value.min)/2
|
132 |
+
return QImpacts(
|
133 |
+
energy=format_energy(impacts.energy),
|
134 |
+
gwp=format_gwp(impacts.gwp),
|
135 |
+
adpe=format_adpe(impacts.adpe),
|
136 |
+
pe=format_pe(impacts.pe)
|
137 |
+
), impacts.usage, impacts.embodied
|
138 |
+
except: #when no range
|
139 |
+
return QImpacts(
|
140 |
+
energy=format_energy(impacts.energy),
|
141 |
+
gwp=format_gwp(impacts.gwp),
|
142 |
+
adpe=format_adpe(impacts.adpe),
|
143 |
+
pe=format_pe(impacts.pe)
|
144 |
+
), impacts.usage, impacts.embodied
|
145 |
+
|
146 |
+
def split_impacts_u_e(impacts: Impacts) -> QImpacts:
|
147 |
+
return impacts.usage, impacts.embodied
|
148 |
+
|
149 |
+
def average_range_impacts(RangeValue):
|
150 |
+
return (RangeValue.max + RangeValue.min)/2
|
151 |
+
|
152 |
+
def format_impacts_expert(impacts: Impacts, display_range: bool) -> QImpacts:
|
153 |
+
|
154 |
+
if display_range:
|
155 |
+
return QImpacts(
|
156 |
+
energy=format_energy(impacts.energy),
|
157 |
+
gwp=format_gwp(impacts.gwp),
|
158 |
+
adpe=format_adpe(impacts.adpe),
|
159 |
+
pe=format_pe(impacts.pe)
|
160 |
+
), impacts.usage, impacts.embodied
|
161 |
+
|
162 |
+
else:
|
163 |
+
energy = {"value":(impacts.energy.value.max + impacts.energy.value.min)/2, "unit":impacts.energy.unit}
|
164 |
+
gwp = (impacts.gwp.value.max + impacts.gwp.value.min)/2
|
165 |
+
adpe = (impacts.adpe.value.max + impacts.adpe.value.min)/2
|
166 |
+
pe = (impacts.pe.value.max + impacts.pe.value.min)/2
|
167 |
+
return QImpacts(
|
168 |
+
energy=format_energy(energy),
|
169 |
+
gwp=format_gwp(gwp),
|
170 |
+
adpe=format_adpe(adpe),
|
171 |
+
pe=format_pe(pe)
|
172 |
+
), impacts.usage, impacts.embodied
|
173 |
+
|
174 |
+
#####################################################################################
|
175 |
+
### EQUIVALENT FORMATING
|
176 |
+
#####################################################################################
|
177 |
+
|
178 |
+
def format_energy_eq_physical_activity(energy: Quantity) -> tuple[PhysicalActivity, Quantity]:
|
179 |
+
energy = energy.to("kJ")
|
180 |
+
running_eq = energy / RUNNING_ENERGY_EQ
|
181 |
+
if running_eq > q("1 km"):
|
182 |
+
return PhysicalActivity.RUNNING, running_eq
|
183 |
+
|
184 |
+
walking_eq = energy / WALKING_ENERGY_EQ
|
185 |
+
if walking_eq < q("1 km"):
|
186 |
+
walking_eq = walking_eq.to("meter")
|
187 |
+
return PhysicalActivity.WALKING, walking_eq
|
188 |
+
|
189 |
+
def format_energy_eq_electric_vehicle(energy: Quantity) -> Quantity:
|
190 |
+
energy = energy.to("kWh")
|
191 |
+
ev_eq = energy / EV_ENERGY_EQ
|
192 |
+
if ev_eq < q("1 km"):
|
193 |
+
ev_eq = ev_eq.to("meter")
|
194 |
+
return ev_eq
|
195 |
+
|
196 |
+
def format_gwp_eq_streaming(gwp: Quantity) -> Quantity:
|
197 |
+
gwp = gwp.to("kgCO2eq")
|
198 |
+
streaming_eq = gwp * STREAMING_GWP_EQ
|
199 |
+
if streaming_eq < q("1 h"):
|
200 |
+
streaming_eq = streaming_eq.to("min")
|
201 |
+
if streaming_eq < q("1 min"):
|
202 |
+
streaming_eq = streaming_eq.to("s")
|
203 |
+
return streaming_eq
|
204 |
+
|
205 |
+
def format_energy_eq_electricity_production(energy: Quantity) -> tuple[EnergyProduction, Quantity]:
|
206 |
+
electricity_eq = energy * ONE_PERCENT_WORLD_POPULATION * DAYS_IN_YEAR
|
207 |
+
electricity_eq = electricity_eq.to("TWh")
|
208 |
+
if electricity_eq > YEARLY_NUCLEAR_ENERGY_EQ:
|
209 |
+
return EnergyProduction.NUCLEAR, electricity_eq / YEARLY_NUCLEAR_ENERGY_EQ
|
210 |
+
electricity_eq = electricity_eq.to("GWh")
|
211 |
+
return EnergyProduction.WIND, electricity_eq / YEARLY_WIND_ENERGY_EQ
|
212 |
+
|
213 |
+
|
214 |
+
def format_energy_eq_electricity_consumption_ireland(energy: Quantity) -> Quantity:
|
215 |
+
electricity_eq = energy * ONE_PERCENT_WORLD_POPULATION * DAYS_IN_YEAR
|
216 |
+
electricity_eq = electricity_eq.to("TWh")
|
217 |
+
return electricity_eq / YEARLY_IRELAND_ELECTRICITY_CONSUMPTION
|
218 |
+
|
219 |
+
def format_gwp_eq_airplane_paris_nyc(gwp: Quantity) -> Quantity:
|
220 |
+
gwp_eq = gwp * ONE_PERCENT_WORLD_POPULATION * DAYS_IN_YEAR
|
221 |
+
gwp_eq = gwp_eq.to("kgCO2eq")
|
222 |
+
return gwp_eq / AIRPLANE_PARIS_NYC_GWP_EQ
|
223 |
+
|
224 |
+
#####################################################################################
|
225 |
+
### MODELS PARAMETERS
|
226 |
+
#####################################################################################
|
227 |
+
|
228 |
+
def model_active_params_fn(provider_name: str, model_name: str, n_param: float):
|
229 |
+
if model_name == 'CUSTOM':
|
230 |
+
return n_param
|
231 |
+
else:
|
232 |
+
model = models.find_model(provider=provider_name, model_name=model_name)
|
233 |
+
|
234 |
+
if model.architecture == 'moe':
|
235 |
+
try:
|
236 |
+
return model.architecture.parameters.active.max
|
237 |
+
except:
|
238 |
+
try:
|
239 |
+
return model.architecture.parameters.active
|
240 |
+
except:
|
241 |
+
return model.architecture.parameters
|
242 |
+
elif model.architecture == 'dense':
|
243 |
+
try: #dense with range
|
244 |
+
return model.architecture.parameters.max
|
245 |
+
except: #dense without range
|
246 |
+
return model.architecture.parameters
|
247 |
+
|
248 |
+
def model_total_params_fn(provider_name: str, model_name: str, n_param: float):
|
249 |
+
if model_name == 'CUSTOM':
|
250 |
+
return n_param
|
251 |
+
provider, model_name = model_name.split('/', 1)
|
252 |
+
model = models.find_model(provider=provider, model_name=model_name)
|
253 |
+
try: #moe
|
254 |
+
return model.architecture.parameters.total.max
|
255 |
+
except:
|
256 |
+
try: #dense with range
|
257 |
+
return model.architecture.parameters.max
|
258 |
+
except: #dense without range
|
259 |
+
try:
|
260 |
+
return model.architecture.parameters.total
|
261 |
+
except:
|
262 |
+
return model.architecture.parameters
|