47 KiB
Inżynieria uczenia maszynowego
22 maja 2024
10. DVC
DVC - Data Version Control
- dvc.org
- "Version Control System for Machine Learning Projects" (System kontroli wersji dla projektów uczenia maszynowego)
- Open Source
- Umożliwia:
- wersjonowanie danych i modeli. "Git dla danych i modeli"
- budowanie potoków ("pipeline") definiujących jak budować/trenować/ewaluować modele. "Makefile dla uczenia maszynowego"
- śledzenie, porównywanie metryk i parametrów
- ściśle zintegowany z gitem
- działa niezależnie od używanego języka/bibliotek i systemu operacyjnego
- 5-minutowe wprowadzenie: https://www.youtube.com/watch?v=UbL7VUpv1Bs
Śledzenie plików za pomocą DVC
- dużymi plikami, takimi jak plikami z danymi wejściowymi czy plikami modeli, trudno zarządza się za pomocą gita, ze względu na problemy z:
- wydajnością
- przestrzenią w repozytorium
- ograniczenia ze strony serwisu (np. limit 100 MB na plik w Github)
- Git posiada rozszerzenie lfs(Large File Storage), które stanowi pewne rozwiązanie tego problemu.
- Same pliki przechowywane są na specjalnym zdalnym serwerze, w repozytorium przechowywane są jedynie odnośniki do tych plików i pewne metadane
- Github ma zintegrowany LFS z limitem 1GB dla kont bezpłatnych
- DVC proponuje podobne podejście co LFS, ale:
Instalacja i inicjalizacja
- https://dvc.org/doc/install
pip install dvc
pipx install dvc
conda install dvc
!pip3 install dvc
Collecting dvc Downloading dvc-3.50.2-py3-none-any.whl (451 kB) [2K [90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━[0m [32m451.6/451.6 KB[0m [31m4.8 MB/s[0m eta [36m0:00:00[0ma [36m0:00:01[0m [?25hRequirement already satisfied: psutil>=5.8 in ./venv/lib/python3.10/site-packages (from dvc) (5.9.8) Collecting rich>=12 Downloading rich-13.7.1-py3-none-any.whl (240 kB) [2K [90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━[0m [32m240.7/240.7 KB[0m [31m9.1 MB/s[0m eta [36m0:00:00[0m [?25hCollecting pathspec>=0.10.3 Using cached pathspec-0.12.1-py3-none-any.whl (31 kB) Collecting configobj>=5.0.6 Downloading configobj-5.0.8-py2.py3-none-any.whl (36 kB) Collecting pydot>=1.2.4 Downloading pydot-2.0.0-py3-none-any.whl (22 kB) Collecting platformdirs<4,>=3.1.1 Downloading platformdirs-3.11.0-py3-none-any.whl (17 kB) Collecting funcy>=1.14 Downloading funcy-2.0-py2.py3-none-any.whl (30 kB) Collecting attrs>=22.2.0 Using cached attrs-23.2.0-py3-none-any.whl (60 kB) Collecting shtab<2,>=1.3.4 Downloading shtab-1.7.1-py3-none-any.whl (14 kB) Collecting flatten-dict<1,>=0.4.1 Downloading flatten_dict-0.4.2-py2.py3-none-any.whl (9.7 kB) Collecting kombu Downloading kombu-5.3.7-py3-none-any.whl (200 kB) [2K [90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━[0m [32m200.2/200.2 KB[0m [31m7.6 MB/s[0m eta [36m0:00:00[0m [?25hCollecting hydra-core>=1.1 Downloading hydra_core-1.3.2-py3-none-any.whl (154 kB) [2K [90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━[0m [32m154.5/154.5 KB[0m [31m9.0 MB/s[0m eta [36m0:00:00[0m [?25hCollecting omegaconf Downloading omegaconf-2.3.0-py3-none-any.whl (79 kB) [2K [90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━[0m [32m79.5/79.5 KB[0m [31m7.0 MB/s[0m eta [36m0:00:00[0m [?25hCollecting voluptuous>=0.11.7 Downloading voluptuous-0.14.2-py3-none-any.whl (31 kB) Collecting dvc-objects Downloading dvc_objects-5.1.0-py3-none-any.whl (33 kB) Requirement already satisfied: colorama>=0.3.9 in ./venv/lib/python3.10/site-packages (from dvc) (0.4.6) Collecting dulwich Downloading dulwich-0.22.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (979 kB) [2K [90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━[0m [32m979.1/979.1 KB[0m [31m8.3 MB/s[0m eta [36m0:00:00[0ma [36m0:00:01[0m [?25hCollecting celery Downloading celery-5.4.0-py3-none-any.whl (425 kB) [2K [90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━[0m [32m426.0/426.0 KB[0m [31m8.4 MB/s[0m eta [36m0:00:00[0ma [36m0:00:01[0m [?25hCollecting pygtrie>=2.3.2 Downloading pygtrie-2.5.0-py3-none-any.whl (25 kB) Collecting zc.lockfile>=1.2.1 Downloading zc.lockfile-3.0.post1-py3-none-any.whl (9.8 kB) Collecting gto<2,>=1.6.0 Downloading gto-1.7.1-py3-none-any.whl (46 kB) [2K [90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━[0m [32m46.6/46.6 KB[0m [31m6.0 MB/s[0m eta [36m0:00:00[0m [?25hCollecting tabulate>=0.8.7 Downloading tabulate-0.9.0-py3-none-any.whl (35 kB) Collecting iterative-telemetry>=0.0.7 Downloading iterative_telemetry-0.0.8-py3-none-any.whl (10 kB) Requirement already satisfied: pyparsing>=2.4.7 in ./venv/lib/python3.10/site-packages (from dvc) (3.1.2) Collecting networkx>=2.5 Using cached networkx-3.3-py3-none-any.whl (1.7 MB) Collecting distro>=1.3 Downloading distro-1.9.0-py3-none-any.whl (20 kB) Requirement already satisfied: tqdm<5,>=4.63.1 in ./venv/lib/python3.10/site-packages (from dvc) (4.66.2) Collecting flufl.lock<8,>=5 Downloading flufl.lock-7.1.1-py3-none-any.whl (11 kB) Collecting scmrepo<4,>=3.3.2 Downloading scmrepo-3.3.5-py3-none-any.whl (73 kB) [2K [90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━[0m [32m73.6/73.6 KB[0m [31m5.8 MB/s[0m eta [36m0:00:00[0m [?25hCollecting dvc-http>=2.29.0 Downloading dvc_http-2.32.0-py3-none-any.whl (12 kB) Collecting grandalf<1,>=0.7 Downloading grandalf-0.8-py3-none-any.whl (41 kB) [2K [90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━[0m [32m41.8/41.8 KB[0m [31m3.2 MB/s[0m eta [36m0:00:00[0m [?25hRequirement already satisfied: packaging>=19 in ./venv/lib/python3.10/site-packages (from dvc) (24.0) Collecting dvc-task<1,>=0.3.0 Downloading dvc_task-0.4.0-py3-none-any.whl (21 kB) Collecting dvc-studio-client<1,>=0.20 Downloading dvc_studio_client-0.20.0-py3-none-any.whl (16 kB) Collecting dpath<3,>=2.1.0 Downloading dpath-2.1.6-py3-none-any.whl (17 kB) Collecting fsspec Downloading fsspec-2024.5.0-py3-none-any.whl (316 kB) [2K [90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━[0m [32m316.1/316.1 KB[0m [31m4.0 MB/s[0m eta [36m0:00:00[0ma [36m0:00:01[0m [?25hCollecting dvc-render<2,>=1.0.1 Downloading dvc_render-1.0.2-py3-none-any.whl (22 kB) Collecting dvc-data<3.16,>=3.15 Downloading dvc_data-3.15.1-py3-none-any.whl (71 kB) [2K [90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━[0m [32m71.6/71.6 KB[0m [31m7.5 MB/s[0m eta [36m0:00:00[0m [?25hCollecting ruamel.yaml>=0.17.11 Downloading ruamel.yaml-0.18.6-py3-none-any.whl (117 kB) [2K [90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━[0m [32m117.8/117.8 KB[0m [31m1.7 MB/s[0m eta [36m0:00:00[0ma [36m0:00:01[0m [?25hCollecting shortuuid>=0.5 Downloading shortuuid-1.0.13-py3-none-any.whl (10 kB) Requirement already satisfied: requests>=2.22 in ./venv/lib/python3.10/site-packages (from dvc) (2.31.0) Collecting tomlkit>=0.11.1 Downloading tomlkit-0.12.5-py3-none-any.whl (37 kB) Requirement already satisfied: six in ./venv/lib/python3.10/site-packages (from configobj>=5.0.6->dvc) (1.16.0) Collecting sqltrie<1,>=0.11.0 Downloading sqltrie-0.11.0-py3-none-any.whl (17 kB) Collecting diskcache>=5.2.1 Downloading diskcache-5.6.3-py3-none-any.whl (45 kB) [2K [90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━[0m [32m45.5/45.5 KB[0m [31m3.7 MB/s[0m eta [36m0:00:00[0m [?25hCollecting dictdiffer>=0.8.1 Downloading dictdiffer-0.9.0-py2.py3-none-any.whl (16 kB) Collecting aiohttp-retry>=2.5.0 Downloading aiohttp_retry-2.8.3-py3-none-any.whl (9.8 kB) Collecting click-didyoumean>=0.3.0 Downloading click_didyoumean-0.3.1-py3-none-any.whl (3.6 kB) Requirement already satisfied: click<9.0,>=8.1.2 in ./venv/lib/python3.10/site-packages (from celery->dvc) (8.1.7) Collecting click-plugins>=1.1.1 Downloading click_plugins-1.1.1-py2.py3-none-any.whl (7.5 kB) Collecting vine<6.0,>=5.1.0 Downloading vine-5.1.0-py3-none-any.whl (9.6 kB) Collecting click-repl>=0.2.0 Downloading click_repl-0.3.0-py3-none-any.whl (10 kB) Requirement already satisfied: tzdata>=2022.7 in ./venv/lib/python3.10/site-packages (from celery->dvc) (2024.1) Requirement already satisfied: python-dateutil>=2.8.2 in ./venv/lib/python3.10/site-packages (from celery->dvc) (2.9.0.post0) Collecting billiard<5.0,>=4.2.0 Downloading billiard-4.2.0-py3-none-any.whl (86 kB) [2K [90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━[0m [32m86.7/86.7 KB[0m [31m5.0 MB/s[0m eta [36m0:00:00[0m [?25hCollecting atpublic>=2.3 Downloading atpublic-4.1.0-py3-none-any.whl (5.0 kB) Collecting semver>=2.13.0 Downloading semver-3.0.2-py3-none-any.whl (17 kB) Collecting pydantic!=2.0.0,<3,>=1.9.0 Downloading pydantic-2.7.1-py3-none-any.whl (409 kB) [2K [90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━[0m [32m409.3/409.3 KB[0m [31m9.7 MB/s[0m eta [36m0:00:00[0m00:01[0m [?25hCollecting typer>=0.4.1 Downloading typer-0.12.3-py3-none-any.whl (47 kB) [2K [90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━[0m [32m47.2/47.2 KB[0m [31m6.9 MB/s[0m eta [36m0:00:00[0m [?25hRequirement already satisfied: entrypoints in ./venv/lib/python3.10/site-packages (from gto<2,>=1.6.0->dvc) (0.4) Collecting antlr4-python3-runtime==4.9.* Downloading antlr4-python3-runtime-4.9.3.tar.gz (117 kB) [2K [90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━[0m [32m117.0/117.0 KB[0m [31m9.4 MB/s[0m eta [36m0:00:00[0m [?25h Preparing metadata (setup.py) ... [?25ldone [?25hCollecting appdirs Downloading appdirs-1.4.4-py2.py3-none-any.whl (9.6 kB) Collecting filelock Downloading filelock-3.14.0-py3-none-any.whl (12 kB) Collecting amqp<6.0.0,>=5.1.1 Downloading amqp-5.2.0-py3-none-any.whl (50 kB) [2K [90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━[0m [32m50.9/50.9 KB[0m [31m7.9 MB/s[0m eta [36m0:00:00[0m [?25hRequirement already satisfied: PyYAML>=5.1.0 in ./venv/lib/python3.10/site-packages (from omegaconf->dvc) (6.0.1) Requirement already satisfied: certifi>=2017.4.17 in ./venv/lib/python3.10/site-packages (from requests>=2.22->dvc) (2024.2.2) Requirement already satisfied: charset-normalizer<4,>=2 in ./venv/lib/python3.10/site-packages (from requests>=2.22->dvc) (3.3.2) Requirement already satisfied: urllib3<3,>=1.21.1 in ./venv/lib/python3.10/site-packages (from requests>=2.22->dvc) (2.2.1) Requirement already satisfied: idna<4,>=2.5 in ./venv/lib/python3.10/site-packages (from requests>=2.22->dvc) (3.6) Collecting markdown-it-py>=2.2.0 Downloading markdown_it_py-3.0.0-py3-none-any.whl (87 kB) [2K [90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━[0m [32m87.5/87.5 KB[0m [31m5.5 MB/s[0m eta [36m0:00:00[0m [?25hRequirement already satisfied: pygments<3.0.0,>=2.13.0 in ./venv/lib/python3.10/site-packages (from rich>=12->dvc) (2.17.2) Collecting ruamel.yaml.clib>=0.2.7 Downloading ruamel.yaml.clib-0.2.8-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl (526 kB) [2K [90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━[0m [32m526.7/526.7 KB[0m [31m8.4 MB/s[0m eta [36m0:00:00[0ma [36m0:00:01[0m [?25hCollecting pygit2>=1.14.0 Downloading pygit2-1.15.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (5.1 MB) [2K [90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━[0m [32m5.1/5.1 MB[0m [31m7.4 MB/s[0m eta [36m0:00:00[0m00:01[0m00:01[0m [?25hCollecting asyncssh<3,>=2.13.1 Downloading asyncssh-2.14.2-py3-none-any.whl (352 kB) [2K [90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━[0m [32m352.5/352.5 KB[0m [31m1.2 MB/s[0m eta [36m0:00:00[0m00:01[0m00:01[0m [?25hRequirement already satisfied: gitpython>3 in ./venv/lib/python3.10/site-packages (from scmrepo<4,>=3.3.2->dvc) (3.1.43) Requirement already satisfied: setuptools in ./venv/lib/python3.10/site-packages (from zc.lockfile>=1.2.1->dvc) (59.6.0) Collecting aiohttp Downloading aiohttp-3.9.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.2 MB) [2K [90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━[0m [32m1.2/1.2 MB[0m [31m6.9 MB/s[0m eta [36m0:00:00[0m00:01[0m00:01[0mm [?25hRequirement already satisfied: typing-extensions>=3.6 in ./venv/lib/python3.10/site-packages (from asyncssh<3,>=2.13.1->scmrepo<4,>=3.3.2->dvc) (4.11.0) Collecting cryptography>=39.0 Downloading cryptography-42.0.7-cp39-abi3-manylinux_2_28_x86_64.whl (3.8 MB) [2K [90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━[0m [32m3.8/3.8 MB[0m [31m8.4 MB/s[0m eta [36m0:00:00[0ma [36m0:00:01[0mm [?25hRequirement already satisfied: prompt-toolkit>=3.0.36 in ./venv/lib/python3.10/site-packages (from click-repl>=0.2.0->celery->dvc) (3.0.43) Requirement already satisfied: gitdb<5,>=4.0.1 in ./venv/lib/python3.10/site-packages (from gitpython>3->scmrepo<4,>=3.3.2->dvc) (4.0.11) Collecting mdurl~=0.1 Downloading mdurl-0.1.2-py3-none-any.whl (10.0 kB) Collecting pydantic-core==2.18.2 Downloading pydantic_core-2.18.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (2.1 MB) [2K [90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━[0m [32m2.1/2.1 MB[0m [31m7.3 MB/s[0m eta [36m0:00:00[0ma [36m0:00:01[0m [?25hCollecting annotated-types>=0.4.0 Downloading annotated_types-0.7.0-py3-none-any.whl (13 kB) Collecting cffi>=1.16.0 Using cached cffi-1.16.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (443 kB) Collecting orjson Downloading orjson-3.10.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (142 kB) [2K [90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━[0m [32m142.5/142.5 KB[0m [31m5.6 MB/s[0m eta [36m0:00:00[0m [?25hCollecting shellingham>=1.3.0 Downloading shellingham-1.5.4-py2.py3-none-any.whl (9.8 kB) Collecting yarl<2.0,>=1.0 Using cached yarl-1.9.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (301 kB) Collecting aiosignal>=1.1.2 Using cached aiosignal-1.3.1-py3-none-any.whl (7.6 kB) Collecting frozenlist>=1.1.1 Using cached frozenlist-1.4.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl (239 kB) Collecting multidict<7.0,>=4.5 Using cached multidict-6.0.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (124 kB) Collecting async-timeout<5.0,>=4.0 Using cached async_timeout-4.0.3-py3-none-any.whl (5.7 kB) Collecting pycparser Downloading pycparser-2.22-py3-none-any.whl (117 kB) [2K [90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━[0m [32m117.6/117.6 KB[0m [31m6.6 MB/s[0m eta [36m0:00:00[0m [?25hRequirement already satisfied: smmap<6,>=3.0.1 in ./venv/lib/python3.10/site-packages (from gitdb<5,>=4.0.1->gitpython>3->scmrepo<4,>=3.3.2->dvc) (5.0.1) Requirement already satisfied: wcwidth in ./venv/lib/python3.10/site-packages (from prompt-toolkit>=3.0.36->click-repl>=0.2.0->celery->dvc) (0.2.13) Using legacy 'setup.py install' for antlr4-python3-runtime, since package 'wheel' is not installed. Installing collected packages: pygtrie, funcy, dictdiffer, appdirs, antlr4-python3-runtime, zc.lockfile, voluptuous, vine, tomlkit, tabulate, shtab, shortuuid, shellingham, semver, ruamel.yaml.clib, pydot, pydantic-core, pycparser, platformdirs, pathspec, orjson, omegaconf, networkx, multidict, mdurl, grandalf, fsspec, frozenlist, flatten-dict, filelock, dvc-render, dulwich, dpath, distro, diskcache, configobj, click-plugins, click-didyoumean, billiard, attrs, atpublic, async-timeout, annotated-types, yarl, sqltrie, ruamel.yaml, pydantic, markdown-it-py, iterative-telemetry, hydra-core, flufl.lock, dvc-studio-client, dvc-objects, click-repl, cffi, amqp, aiosignal, rich, pygit2, kombu, dvc-data, cryptography, aiohttp, typer, celery, asyncssh, aiohttp-retry, scmrepo, dvc-task, dvc-http, gto, dvc Running setup.py install for antlr4-python3-runtime ... [?25ldone [?25h Attempting uninstall: platformdirs Found existing installation: platformdirs 4.2.0 Uninstalling platformdirs-4.2.0: Successfully uninstalled platformdirs-4.2.0 Successfully installed aiohttp-3.9.5 aiohttp-retry-2.8.3 aiosignal-1.3.1 amqp-5.2.0 annotated-types-0.7.0 antlr4-python3-runtime-4.9.3 appdirs-1.4.4 async-timeout-4.0.3 asyncssh-2.14.2 atpublic-4.1.0 attrs-23.2.0 billiard-4.2.0 celery-5.4.0 cffi-1.16.0 click-didyoumean-0.3.1 click-plugins-1.1.1 click-repl-0.3.0 configobj-5.0.8 cryptography-42.0.7 dictdiffer-0.9.0 diskcache-5.6.3 distro-1.9.0 dpath-2.1.6 dulwich-0.22.1 dvc-3.50.2 dvc-data-3.15.1 dvc-http-2.32.0 dvc-objects-5.1.0 dvc-render-1.0.2 dvc-studio-client-0.20.0 dvc-task-0.4.0 filelock-3.14.0 flatten-dict-0.4.2 flufl.lock-7.1.1 frozenlist-1.4.1 fsspec-2024.5.0 funcy-2.0 grandalf-0.8 gto-1.7.1 hydra-core-1.3.2 iterative-telemetry-0.0.8 kombu-5.3.7 markdown-it-py-3.0.0 mdurl-0.1.2 multidict-6.0.5 networkx-3.3 omegaconf-2.3.0 orjson-3.10.3 pathspec-0.12.1 platformdirs-3.11.0 pycparser-2.22 pydantic-2.7.1 pydantic-core-2.18.2 pydot-2.0.0 pygit2-1.15.0 pygtrie-2.5.0 rich-13.7.1 ruamel.yaml-0.18.6 ruamel.yaml.clib-0.2.8 scmrepo-3.3.5 semver-3.0.2 shellingham-1.5.4 shortuuid-1.0.13 shtab-1.7.1 sqltrie-0.11.0 tabulate-0.9.0 tomlkit-0.12.5 typer-0.12.3 vine-5.1.0 voluptuous-0.14.2 yarl-1.9.4 zc.lockfile-3.0.post1
Stwórzmy katalog, w którym będziemy przechowywać nasz projekt:
!rm -r -f IUM_10/sample-ml-project-2023
!mkdir -p IUM_10/sample-ml-project-2023
#Jupyter notebook magic https://ipython.readthedocs.io/en/stable/interactive/magics.html#magic-cd
%cd "IUM_10/sample-ml-project-2023"
Inicjalizujemy puste repozytorium Git (możemy też pominąć ten krok i działać w istniejącym już repozytorium)
!git init
Teraz inicjalizujemy repozytorium DVC:
!dvc init
Zobaczmy jakie pliki dodał (również do repozytorium git) DVC. Ich opis znajdziemy tutaj: https://dvc.org/doc/user-guide/project-structure/internal-files
!git status
.dvc/config
- główny plik konfiguracyjny dvc.dvc/config.local
- nadpisuje wartości zconfig
, do lokalnych zmian nie commitowanych do repo.dvc/.gitignore
- pliki dvc, które nie mają znaleźć się w repo.dvcignore
- dvc pomija pliki zdefiniowane w tym pliku (np. aby poprawić wydajność)
Możemy teraz zacommitować zmiany w git:
!git commit -m "Initial commit"
Przygotujmy przykładowe dane, pobierając je z Kaggle:
!kaggle datasets download -d uciml/iris
!unzip -o iris.zip
!rm database.sqlite iris.zip
!mkdir -p data
!mv Iris.csv data/
Teraz dodamy plik(i) z danymi do DVC:
!dvc add data/Iris.csv
- DVC utworzył plik
data/Iris.csv.dvc
i dadał oryginalny plik do.gitignore
- W repozytorium będzie obecny tylko plik
*.dvc
, zawierający odnośnik do prawdziwego pliku
!git status -u
Dodajmy pliki data/Iris.csv.dvc data/.gitignore
do repozytorium git, zgodnie z sugestią DVC:
!git add data/Iris.csv.dvc data/.gitignore
!git commit -m "Dodano dane IRIS (DVC)"
Plik *.dvc
zawiera m.in. hash pliku. Więcej o plikach *.dvc
: link
# %load data/Iris.csv.dvc
Oryginalny plik Iris.csv
został przeniesiony do katalogu ./dvc/cache/{wartość hash pliku) i podlinkowany z powrotem do oryginalnej lokalizacji. Sposób tworzenia linków może być różny w zależności od systemu plików.
!ls -l .dvc/cache/71
!head -n 3 .dvc/cache/71/7820ef0af287ff346c5cabfb4c612c
!git remote add origin git@git.wmi.amu.edu.pl:tzietkiewicz/sample-ml-project.git
!git push --set-upstream origin main
dvc remote
- żeby wysłać właściwe pliki śledzone przez DVC do zdalnej lokalizacji (z której będą mogłby być pobrane np. przez system CI albo innych użytkowników) musimy mieć skonfigurowaną taką lokazliację
- służy do tego polecenie
dvc remote add
- użyjemy lokalnego "remote". Tutaj będzie to po prostu utworzony wcześniej katalog
/dvcstore
. Taki katalog istnieje też na naszym Jenkinsie, oczywiście należy go podmontować w Dockerze - w realnych zastosowaniach podalibyśmy tutaj ścieżkę do jakiegoś zasobu dostępnego przez inernet jak np. serwer SFTP, ścieżka do AWS S3 itp.
Obsługiwane typy zdalnych lokalizacji (remotes): https://dvc.org/doc/command-reference/remote/add#supported-storage-types
- Amazon S3
- S3-compatible storage
- Microsoft Azure Blob Storage
- Google Drive
- Google Cloud Storage
- Aliyun OSS
- SSH
- HDFS
- WebHDFS
- HTTP
- WebDAV
- local remote
Dodawanie remote typu local
!dvc remote add -d my_local_remote /dvcstore
!git status
!git add .dvc/config
!git commit -m "Added DVC remote"
dvc push
Kiedy mamy już skonfigurowany "remote" możemy wypchnąć do niego pliki korzystając z polecenia dvc push
:
!dvc push
!tree /dvcstore
dvc pull
Żeby pobrać dane z DVC (np. w innej lokalizacji, przez innego użytkownika), musimy:
- sklonować repozytorium git (żeby m.in. pobrać pliki
*.dvc
- wykonać
dvc pull
Dodawanie nowych plików i modyfikacja istniejących wygląda podobnie jak przy zwykłych plikach śledzonych przez git, tylko zamiast git
używamy polecenia dvc
a dodatkowo pamiętamy o zarządzaniu plikami *.dvc
za pomocą gita:
!head -n -1 data/Iris.csv | sponge data/Iris.csv
!git status
!dvc status
!dvc add data/Iris.csv
!git add data/Iris.csv.dvc
!git commit -m "Removed last line from Iris dataset"
!wc -l .dvc/cache/*/*
dvc checkout
- Polecenia
dvc checkout
używamy razem zgit checkout
, żeby zmienić branch, na którym pracujemy. - DVC podmieni wersje plików śledzonych przez siebie na pochodzące z innego brancha (o ile pliki te się różnią i różnią się pliki
*.dvc
w odpowiednich branchach - zmiana brancha przez git powoduje (ewentualną) zmianę plików
*.dvc
advc checkout
kopiuje/linkuje pliki z katalogu.dvc/cache
o wartościach hash odpowiadających tym z plików*.dvc
Wymiana danych między projektami
- za pomocą poleceń
dvc import
idvc update
możemy dodać i później aktualizować pliki śledzone przez DVC w innym repozytorium
!dvc import https://github.com/iterative/dataset-registry \
get-started/data.xml -o data/data.xml
!dvc status
ls -l data
# %load data/data.xml.dvc
md5: 9d5921765bfba6c2c7e4c780c66edaa0
frozen: true
deps:
- path: get-started/data.xml
repo:
url: https://github.com/iterative/dataset-registry
rev_lock: 08c38bbea04e4f9e2130615dd679309ed0e11a72
outs:
- md5: 22a1a2931c8370d3aeedd7183606fd7f
size: 14445097
path: data.xml
DVC pipelines
- wprowadzenie: https://youtu.be/71IGzyH95UY
- Getting started: https://dvc.org/doc/start/data-pipelines
- dvc pipelines pozwala nam zbudować (za pomocą polecenie
dvc run
) lub zdefiniować (edytując plikdvc.yaml
) graf zależności między krokami wykonywanymi w naszym projekcie (takimi jak "przygotowanie danych", "trenowanie", "ewaluacja") - tak zdefiniowany pipeline można potem uruchomić za pomocą polecenia
dvc reproduce
Zadania [10+10 pkt]
- Zainicjalizuj repozytorium DVC wewnątrz Twojego repozytorium z projektem [1pkt]
- Dodaj plik(i) z danymi w Twoim projekcie do DVC [1pkt]
- Skonfiguruj remote (dane do konfiguracji podane poniżej) [3pkt]
- Stwórz/zdefiniuj i dodaj do repozytorium plik
dvc.yaml
opisujący kroki wykonywane w Twoim projekcie. Wydziel przynajmniej 2 kroki (np. przygotowanie danych/trenowanie) powiązane ze sobą za pomocą zależności (skorzystaj z materiałów "Getting started", link powyżej) [10pkt (opcjonalne)] - Stwórz projekt na Jenkinsie (
s1233456-dvc
), w którym sklonujesz repozytorium, ściągniesz pliki dvc (za pomocądvc pull
) i uruchomisz pipeline (za pomocądvc reproduce
) [5pkt]
SSH remote
Jednym z remote obsługiwanych przez DVC jest SFTP/SSH.
W celu jego wykorzystania na serwerze tzietkiewicz.vm.wmi.amu.edu.pl utworzony został użytkownik ium-sftp
i skonfigurowany serwer SFTP.
Został też dla niego wygenerowany klucz ssh, który został dodany jako "Jenkins credential" (patrz opis konfiguracji na Jenkins poniżej)
Lokalnie
Będziemy potrzebować zależności (szczegóły)
conda install dvc-ssh
albo
pip install dvc[ssh] paramiko
conda install -c conda-forge dvc-ssh
Collecting package metadata (current_repodata.json): done Solving environment: \
## Poniższe są potrzebne, żeby polecania dvc remote działały:
!sudo apt install libssl3 libffi7
Dodajemy remote:
!dvc remote add -f -d ium_ssh_remote ssh://ium-sftp@tzietkiewicz.vm.wmi.amu.edu.pl
!dvc remote list
Zapisujemy hasło:
!dvc remote modify --local ium_ssh_remote password IUM@2021
Pushujemy do skonfigurowanego remote:
!dvc push
Jenkins
W Jenkins można użyć mechanizmu "Credentials", żeby w bezpieczny sposób przekazać hasło albo klucz prywatny.
Takie dane dla użytkownika ium-sftp zostały stworzone na Jenkinsie:
- typu ssh key: https://tzietkiewicz.vm.wmi.amu.edu.pl:8081/credentials/store/system/domain/_/credential/48ac7004-216e-4260-abba-1fe5db753e18/
- typu "secret text" - zawierający hasło użytkownika ium-shftp: https://tzietkiewicz.vm.wmi.amu.edu.pl:8081/credentials/store/system/domain/_/credential/ium-sftp-password/
Opis używania "Credentials" w Jenkinsfile: https://www.jenkins.io/doc/book/pipeline/jenkinsfile/#for-other-credential-types
Klucza ssh można użyć tak:
withCredentials(
[sshUserPrivateKey(credentialsId: '48ac7004-216e-4260-abba-1fe5db753e18', keyFileVariable: 'IUM_SFTP_KEY', passphraseVariable: '', usernameVariable: '')]) {
sh 'dvc remote add -d ium_ssh_remote ssh://ium-sftp@tzietkiewicz.vm.wmi.amu.edu.pl/ium-sftp'
sh 'dvc remote modify --local ium_ssh_remote keyfile $IUM_SFTP_KEY'
sh 'dvc pull'}
Secret text tak:
withCredentials([string(credentialsId: 'ium-sftp-password', variable: 'IUM_SFTP_PASS')]) {
sh 'dvc remote add -d ium_ssh_remote ssh://ium-sftp@tzietkiewicz.vm.wmi.amu.edu.pl/ium-sftp'
sh 'dvc remote modify --local ium_ssh_remote password $IUM_SFTP_PASS'
sh 'dvc pull'
}
Przykład konfiguracji: