From 0716270cbb02a179b16fa79448083d0acd683275 Mon Sep 17 00:00:00 2001 From: Malte Grosse Date: Mon, 4 Dec 2023 23:08:32 +0900 Subject: [PATCH 1/4] added training --- src/sandbox/res/sandbox-ci-repos.png | Bin 0 -> 20198 bytes src/sandbox/res/sandbox-ci-settings.png | Bin 0 -> 10727 bytes src/sandbox/training.md | 92 +++++++++++++++++++++++- 3 files changed, 91 insertions(+), 1 deletion(-) create mode 100644 src/sandbox/res/sandbox-ci-repos.png create mode 100644 src/sandbox/res/sandbox-ci-settings.png diff --git a/src/sandbox/res/sandbox-ci-repos.png b/src/sandbox/res/sandbox-ci-repos.png new file mode 100644 index 0000000000000000000000000000000000000000..4f4c54c65038398936dec63b67ce6f8c4b544f06 GIT binary patch literal 20198 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 Ok(LsZ6Ri?92>36p7sf3B literal 0 HcmV?d00001 diff --git a/src/sandbox/training.md b/src/sandbox/training.md index 4e0973b..8068f6c 100644 --- a/src/sandbox/training.md +++ b/src/sandbox/training.md @@ -1,4 +1,94 @@ # Training Environment -Currently under heavy development, coming soon....stayed tuned! +This documentation is for advanced users which are aware of following tools: git, python/R, cuda, pytorch/tensorflow and basic container knowledge. +## Overview +Available are two worker agents with +- 12 CPUs +- 40 GB memory +- 20 GB Nvidia GPU memory +- 100 GB Hdd Diskspace + +Only two pipelines can run in parallel to ensure having the promised hardware resources. If more jobs occur, they will be stored in a queue and released after the fifo principle. + + +## Development + +### Git +Create a new git repository and commit your latest code here: https://git.sandbox.iuk.hdm-stuttgart.de/ + +Repositories can be private or public - depends on your use case. + + +### CI +Connect your newly created repository here: https://ci.sandbox.iuk.hdm-stuttgart.de/ +1. After login, click on "+ Add repository" +![repos](./res/sandbox-ci-repos.png) +2. Enable the specific repository + +3. Go to the repositories [overview site](https://ci.sandbox.iuk.hdm-stuttgart.de/repos) and select your enabled repository +4. Go to settings (clicking the settings icon) +![repos](./res/sandbox-ci-settings.png) +5. Set a reasonable timeout in minutes (e.g. 360 minutes for 6hours) if some training crashes/hangs +6. Add additional settings like secrets or container registries, see the official [documentation](https://woodpecker-ci.org/docs/usage/project-settings) for additional settings + + +### Pipeline File +An example script can be found here: + + https://git.sandbox.iuk.hdm-stuttgart.de/grosse/test-ci + + +1. Create a new file in your repository `.woodpecker.yml` (of different regarding repository settings above) +2. The content can look like following: + +``` +steps: + "train": + image: nvcr.io/nvidia/tensorflow:23.10-tf2-py3 + commands: + - echo "starting python script" + - python run.py + "compress and upload": + image: alpine:3 + commands: + - apk --no-cache add zip curl + - zip mymodel.zip mymodel.keras + - curl -F fileUpload=@mymodel.zip https://share.storage.sandbox.iuk.hdm-stuttgart.de/upload +``` +See the official [documentation](https://woodpecker-ci.org/docs/usage/workflow-syntax) for the syntax. + +Generally, the pipeline is based on different steps, and in each step, another container environment can be chosen. In the example above, first an official tensorflow container with python 3 is used to run the training python script. In the second step, the model gets compressed and pushed on the temp sandbox storage. +3. Commit and push +4. See current state of the pipelines at the [overview site](https://ci.sandbox.iuk.hdm-stuttgart.de/repos) + +Hints: +- The first time an external container is pulled, depending on the size, container images can take quite a while as different organization (like dockerhub) limit the download speed. The Sandbox git also supports hosting container images... +- Choose a proper way to output some reasonable logs during your training, so it wont spam the logs too heavily + +### Exporting trained model +We provide a 3-months disposal internal storage. +You can either use the a simple curl command `curl -F fileUpload=@mymodel.zip https://share.storage.sandbox.iuk.hdm-stuttgart.de/upload` to upload a file or a simple python script + +``` +import requests +import os + +myurl = 'https://share.storage.sandbox.iuk.hdm-stuttgart.de/upload' + +print("uploading file") +files = { + 'fileUpload':('mymodel.keras', open('mymodel.keras', 'rb'),'application/octet-stream') +} + +response = requests.post(myurl, files=files) +print(response,response.text) + +``` + +which returns a json + +``` +{"PublicUrl":"https://storage.sandbox.iuk.hdm-stuttgart.de/upload/49676006-94e4-4da6-be3f-466u786768979/mymodel.keras","Size":97865925,"Expiration":"2024-03-30T00:00:00Z"} + +``` \ No newline at end of file From 3002313bf0b9527410fe7cdd060dd01d92cee39c Mon Sep 17 00:00:00 2001 From: Malte Grosse Date: Mon, 4 Dec 2023 23:12:20 +0900 Subject: [PATCH 2/4] fix --- src/sandbox/training.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sandbox/training.md b/src/sandbox/training.md index 8068f6c..f550240 100644 --- a/src/sandbox/training.md +++ b/src/sandbox/training.md @@ -86,7 +86,7 @@ print(response,response.text) ``` -which returns a json +which returns a json with the download url of your uploaded file. ``` {"PublicUrl":"https://storage.sandbox.iuk.hdm-stuttgart.de/upload/49676006-94e4-4da6-be3f-466u786768979/mymodel.keras","Size":97865925,"Expiration":"2024-03-30T00:00:00Z"} From 8cfc3679230a4f1c8b3ceeb5e643d534ea6bf1ad Mon Sep 17 00:00:00 2001 From: Malte Grosse Date: Fri, 3 May 2024 11:44:41 +0900 Subject: [PATCH 3/4] changed training --- src/sandbox/training.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sandbox/training.md b/src/sandbox/training.md index f550240..af7927e 100644 --- a/src/sandbox/training.md +++ b/src/sandbox/training.md @@ -4,12 +4,12 @@ This documentation is for advanced users which are aware of following tools: git ## Overview Available are two worker agents with -- 12 CPUs +- 12 physical CPUs - 40 GB memory - 20 GB Nvidia GPU memory - 100 GB Hdd Diskspace -Only two pipelines can run in parallel to ensure having the promised hardware resources. If more jobs occur, they will be stored in a queue and released after the fifo principle. +Only two pipelines can run in parallel to ensure having the promised hardware resources. If more jobs occur, they will be stored in a queue and released after the fifo principle. Storage is not persistent - every build/training job needs to saved somewhere external. ## Development @@ -58,7 +58,7 @@ steps: ``` See the official [documentation](https://woodpecker-ci.org/docs/usage/workflow-syntax) for the syntax. -Generally, the pipeline is based on different steps, and in each step, another container environment can be chosen. In the example above, first an official tensorflow container with python 3 is used to run the training python script. In the second step, the model gets compressed and pushed on the temp sandbox storage. +Generally, the pipeline is based on different steps, and in each step, another container environment can be chosen. In the example above, first an official tensorflow container with python 3 is used to run the training python script. In the second step, the model gets compressed and pushed on the temp. sandbox storage. 3. Commit and push 4. See current state of the pipelines at the [overview site](https://ci.sandbox.iuk.hdm-stuttgart.de/repos) From 49afe43ad7ee08c180ff2f2f2fb971202485d1c7 Mon Sep 17 00:00:00 2001 From: Malte Grosse Date: Tue, 14 May 2024 18:09:26 +0900 Subject: [PATCH 4/4] changed training --- src/sandbox/res/training.svg | 4 ++++ src/sandbox/training.md | 24 ++++++++++++++++++------ 2 files changed, 22 insertions(+), 6 deletions(-) create mode 100644 src/sandbox/res/training.svg diff --git a/src/sandbox/res/training.svg b/src/sandbox/res/training.svg new file mode 100644 index 0000000..9c70de9 --- /dev/null +++ b/src/sandbox/res/training.svg @@ -0,0 +1,4 @@ + + + +SandboxScientific UserAccess SandboxLogin to Gitcreate Repositoryclone repositorycreate model & set parametercreate woodpecker.ymlgit commit & pushci/cd add new repositoryWoodpecker start trainingafter training upload model to datapoolprovide linkDatapoolaccess modelShut Down ServerGIT \ No newline at end of file diff --git a/src/sandbox/training.md b/src/sandbox/training.md index af7927e..39f1692 100644 --- a/src/sandbox/training.md +++ b/src/sandbox/training.md @@ -1,7 +1,7 @@ # Training Environment This documentation is for advanced users which are aware of following tools: git, python/R, cuda, pytorch/tensorflow and basic container knowledge. - +![repos](./res/training.svg) ## Overview Available are two worker agents with - 12 physical CPUs @@ -39,7 +39,7 @@ An example script can be found here: https://git.sandbox.iuk.hdm-stuttgart.de/grosse/test-ci -1. Create a new file in your repository `.woodpecker.yml` (of different regarding repository settings above) +1. Create a new file in your repository `.woodpecker.yml` (or different regarding repository settings above) 2. The content can look like following: ``` @@ -62,9 +62,7 @@ Generally, the pipeline is based on different steps, and in each step, another c 3. Commit and push 4. See current state of the pipelines at the [overview site](https://ci.sandbox.iuk.hdm-stuttgart.de/repos) -Hints: -- The first time an external container is pulled, depending on the size, container images can take quite a while as different organization (like dockerhub) limit the download speed. The Sandbox git also supports hosting container images... -- Choose a proper way to output some reasonable logs during your training, so it wont spam the logs too heavily + ### Exporting trained model We provide a 3-months disposal internal storage. @@ -91,4 +89,18 @@ which returns a json with the download url of your uploaded file. ``` {"PublicUrl":"https://storage.sandbox.iuk.hdm-stuttgart.de/upload/49676006-94e4-4da6-be3f-466u786768979/mymodel.keras","Size":97865925,"Expiration":"2024-03-30T00:00:00Z"} -``` \ No newline at end of file +``` +## Troubleshooting: +- The first time an external container is pulled, depending on the size, container images can take quite a while as different organization (like dockerhub) limit the download speed. The Sandbox git also supports hosting container images... +- Choose a proper way to output some reasonable logs during your training, so it wont spam the logs too heavily +- training exists after 60 minutes: increase maximum duration in the ci repository settings + +## Useful Links +- [Sandbox GIT](https://git.sandbox.iuk.hdm-stuttgart.de/) +- [Sandbox CI](https://ci.sandbox.iuk.hdm-stuttgart.de) +- [Git](https://git-scm.com/docs/gittutorial) +- [Woodpecker Syntax](https://woodpecker-ci.org/docs/2.3/usage/workflow-syntax) +- [PyTorch](https://pytorch.org/docs/stable/index.html) +- [TensorFlow](https://www.tensorflow.org/versions/r2.15/api_docs/python/tf) +- [NVIDIA PyTorch Container](https://catalog.ngc.nvidia.com/orgs/nvidia/containers/pytorch) +- [NVIDIA Tensorflow Container](https://catalog.ngc.nvidia.com/orgs/nvidia/containers/tensorflow) \ No newline at end of file