utrain 0.0.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- utrain-0.0.4/.gitignore +7 -0
- utrain-0.0.4/.gitlab-ci.yml +195 -0
- utrain-0.0.4/.pre-commit-config.yaml +48 -0
- utrain-0.0.4/CHANGELOG.md +17 -0
- utrain-0.0.4/LICENSE +21 -0
- utrain-0.0.4/Makefile +26 -0
- utrain-0.0.4/PKG-INFO +15 -0
- utrain-0.0.4/README.md +14 -0
- utrain-0.0.4/changes/.empty +0 -0
- utrain-0.0.4/changes/1.bugfix.md +1 -0
- utrain-0.0.4/containers/shakespeare-char/Containerfile +6 -0
- utrain-0.0.4/containers/shakespeare-char/shakespeare_char.py +600 -0
- utrain-0.0.4/docs/changelog.md +17 -0
- utrain-0.0.4/docs/index.md +50 -0
- utrain-0.0.4/docs/installation.md +13 -0
- utrain-0.0.4/docs/quickstart.md +72 -0
- utrain-0.0.4/pyproject.toml +143 -0
- utrain-0.0.4/scripts/check-imports +39 -0
- utrain-0.0.4/scripts/release.sh +40 -0
- utrain-0.0.4/src/utrain/__init__.py +0 -0
- utrain-0.0.4/src/utrain/cli/__init__.py +0 -0
- utrain-0.0.4/src/utrain/cli/attempts.py +116 -0
- utrain-0.0.4/src/utrain/cli/compute.py +172 -0
- utrain-0.0.4/src/utrain/cli/db.py +178 -0
- utrain-0.0.4/src/utrain/cli/debug.py +38 -0
- utrain-0.0.4/src/utrain/cli/exceptions.py +2 -0
- utrain-0.0.4/src/utrain/cli/images.py +121 -0
- utrain-0.0.4/src/utrain/cli/main.py +382 -0
- utrain-0.0.4/src/utrain/cli/orchestrator.py +363 -0
- utrain-0.0.4/src/utrain/cli/output.py +37 -0
- utrain-0.0.4/src/utrain/cli/phases.py +228 -0
- utrain-0.0.4/src/utrain/cli/reconcile.py +144 -0
- utrain-0.0.4/src/utrain/cli/runs.py +705 -0
- utrain-0.0.4/src/utrain/cli/store.py +22 -0
- utrain-0.0.4/src/utrain/config.py +47 -0
- utrain-0.0.4/src/utrain/container/__init__.py +3 -0
- utrain-0.0.4/src/utrain/container/podman.py +74 -0
- utrain-0.0.4/src/utrain/container/run_data.py +107 -0
- utrain-0.0.4/src/utrain/container/schema.py +53 -0
- utrain-0.0.4/src/utrain/container/wandb_shim/wandb/__init__.py +14 -0
- utrain-0.0.4/tests/__init__.py +0 -0
- utrain-0.0.4/tests/conftest.py +125 -0
- utrain-0.0.4/tests/containers/fake/Containerfile +6 -0
- utrain-0.0.4/tests/containers/fake/fake.py +290 -0
- utrain-0.0.4/tests/containers/fake-gpu/Containerfile +5 -0
- utrain-0.0.4/tests/containers/fake-gpu/fake_gpu.py +48 -0
- utrain-0.0.4/tests/cram/attempt-show.t +37 -0
- utrain-0.0.4/tests/cram/compute.t +9 -0
- utrain-0.0.4/tests/cram/data-store.t +37 -0
- utrain-0.0.4/tests/cram/fixtures/compute-empty.json +9 -0
- utrain-0.0.4/tests/cram/fixtures/compute.json +19 -0
- utrain-0.0.4/tests/cram/gpu.t +11 -0
- utrain-0.0.4/tests/cram/id-prefix.t +15 -0
- utrain-0.0.4/tests/cram/image.t +28 -0
- utrain-0.0.4/tests/cram/phase-show.t +19 -0
- utrain-0.0.4/tests/cram/run-config-protocol.t +29 -0
- utrain-0.0.4/tests/cram/run-config.t +19 -0
- utrain-0.0.4/tests/cram/run-create.t +9 -0
- utrain-0.0.4/tests/cram/run-delete.t +33 -0
- utrain-0.0.4/tests/cram/run-lifecycle.t +40 -0
- utrain-0.0.4/tests/cram/run-restart.t +24 -0
- utrain-0.0.4/tests/cram/run-stop.t +16 -0
- utrain-0.0.4/tests/cram/setup.sh +16 -0
- utrain-0.0.4/tests/cram/wandb-compat.t +26 -0
- utrain-0.0.4/tests/test_cram.py +90 -0
- utrain-0.0.4/uv.lock +2214 -0
- utrain-0.0.4/zensical.toml +124 -0
utrain-0.0.4/.gitignore
ADDED
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
# CI pipeline.
|
|
2
|
+
#
|
|
3
|
+
# check stage: run the pre-commit hooks (`make check`) and the pytest suite on
|
|
4
|
+
# every push to main.
|
|
5
|
+
# release stage: on tag pipelines, build every container preset under
|
|
6
|
+
# containers/<name>/ and push it to this project's GitLab
|
|
7
|
+
# container registry. The pre-commit hooks also run on tags (the
|
|
8
|
+
# check stage runs first), so a release only publishes if they pass.
|
|
9
|
+
# Once the images are built, publish-pypi builds the wheel/sdist
|
|
10
|
+
# with `uv build` and uploads them to PyPI.
|
|
11
|
+
# deploy stage: build the docs with zensical and publish them to GitLab Pages,
|
|
12
|
+
# one version per release tag plus a rolling "dev" for main. mike
|
|
13
|
+
# owns the `pages` branch -- it keeps every version there, and
|
|
14
|
+
# the job only unpacks that branch into public/. Nothing should
|
|
15
|
+
# commit to it by hand.
|
|
16
|
+
#
|
|
17
|
+
# Users pull a published preset with:
|
|
18
|
+
# utrain image add docker://$CI_REGISTRY_IMAGE/<name>:latest
|
|
19
|
+
#
|
|
20
|
+
# Prerequisites:
|
|
21
|
+
# - Container Registry enabled (Settings -> General -> Visibility).
|
|
22
|
+
# - Pages enabled (Settings -> General -> Visibility).
|
|
23
|
+
# - MIKE_ACCESS_TOKEN: a project access token with the write_repository scope,
|
|
24
|
+
# masked and protected, so the pages job can push to the `pages` branch.
|
|
25
|
+
# - PYPI_API_TOKEN: a PyPI API token (scoped to the utrain project once it
|
|
26
|
+
# exists on PyPI, or account-wide for the first publish), masked and
|
|
27
|
+
# protected, so publish-pypi can upload releases. gitlab.inria.fr is
|
|
28
|
+
# self-hosted, so PyPI trusted publishing (OIDC) isn't available -- it
|
|
29
|
+
# only supports gitlab.com.
|
|
30
|
+
# - runner has privileged = true
|
|
31
|
+
|
|
32
|
+
stages: [check, release, deploy]
|
|
33
|
+
|
|
34
|
+
pre-commit:
|
|
35
|
+
stage: check
|
|
36
|
+
image: ghcr.io/astral-sh/uv:python3.11-bookworm
|
|
37
|
+
tags:
|
|
38
|
+
- self-linux
|
|
39
|
+
variables:
|
|
40
|
+
PRE_COMMIT_HOME: "$CI_PROJECT_DIR/.cache/pre-commit"
|
|
41
|
+
UV_CACHE_DIR: "$CI_PROJECT_DIR/.cache/uv"
|
|
42
|
+
cache:
|
|
43
|
+
key: pre-commit
|
|
44
|
+
paths:
|
|
45
|
+
- .cache/pre-commit
|
|
46
|
+
- .cache/uv
|
|
47
|
+
rules:
|
|
48
|
+
- if: '$CI_COMMIT_TAG'
|
|
49
|
+
- if: '$CI_COMMIT_BRANCH == "main"'
|
|
50
|
+
script:
|
|
51
|
+
- uv run --frozen pre-commit run --all-files --show-diff-on-failure
|
|
52
|
+
|
|
53
|
+
test:
|
|
54
|
+
stage: check
|
|
55
|
+
image: quay.io/podman/stable
|
|
56
|
+
tags:
|
|
57
|
+
- self-linux
|
|
58
|
+
rules:
|
|
59
|
+
- if: '$CI_COMMIT_TAG'
|
|
60
|
+
- if: '$CI_COMMIT_BRANCH == "main"'
|
|
61
|
+
variables:
|
|
62
|
+
# vfs because the job's container storage is itself inside a container,
|
|
63
|
+
# where overlay needs a host mount it does not have. It is space-hungry --
|
|
64
|
+
# if this job starts failing on disk, give the runner a bigger volume.
|
|
65
|
+
STORAGE_DRIVER: vfs
|
|
66
|
+
UV_CACHE_DIR: "$CI_PROJECT_DIR/.cache/uv"
|
|
67
|
+
cache:
|
|
68
|
+
key: test
|
|
69
|
+
paths:
|
|
70
|
+
- .cache/uv
|
|
71
|
+
script:
|
|
72
|
+
- curl -LsSf https://astral.sh/uv/install.sh | sh
|
|
73
|
+
- export PATH="$HOME/.local/bin:$PATH"
|
|
74
|
+
- podman run --rm docker.io/library/busybox:latest true
|
|
75
|
+
# -rs prints every skip reason, so a suite that goes quiet in CI says why in
|
|
76
|
+
# the job log rather than just shrinking.
|
|
77
|
+
- uv run --frozen pytest -rs
|
|
78
|
+
|
|
79
|
+
build-images:
|
|
80
|
+
stage: release
|
|
81
|
+
image:
|
|
82
|
+
# The :debug tag ships /busybox/sh so the shell loop below can run.
|
|
83
|
+
name: gcr.io/kaniko-project/executor:debug
|
|
84
|
+
entrypoint: [""]
|
|
85
|
+
tags:
|
|
86
|
+
- self-linux
|
|
87
|
+
rules:
|
|
88
|
+
- if: '$CI_COMMIT_TAG'
|
|
89
|
+
script:
|
|
90
|
+
- mkdir -p /kaniko/.docker
|
|
91
|
+
- |
|
|
92
|
+
cat > /kaniko/.docker/config.json <<EOF
|
|
93
|
+
{"auths":{"$CI_REGISTRY":{"username":"$CI_REGISTRY_USER","password":"$CI_REGISTRY_PASSWORD"}}}
|
|
94
|
+
EOF
|
|
95
|
+
- |
|
|
96
|
+
for dir in containers/*/; do
|
|
97
|
+
name=$(basename "$dir")
|
|
98
|
+
[ -f "containers/$name/Containerfile" ] || continue
|
|
99
|
+
echo "Building and pushing $name"
|
|
100
|
+
/kaniko/executor \
|
|
101
|
+
--context "$CI_PROJECT_DIR" \
|
|
102
|
+
--dockerfile "containers/$name/Containerfile" \
|
|
103
|
+
--destination "$CI_REGISTRY_IMAGE/$name:$CI_COMMIT_TAG" \
|
|
104
|
+
--destination "$CI_REGISTRY_IMAGE/$name:latest"
|
|
105
|
+
done
|
|
106
|
+
|
|
107
|
+
publish-pypi:
|
|
108
|
+
stage: release
|
|
109
|
+
image: ghcr.io/astral-sh/uv:python3.11-bookworm
|
|
110
|
+
tags:
|
|
111
|
+
- self-linux
|
|
112
|
+
needs:
|
|
113
|
+
- job: build-images
|
|
114
|
+
rules:
|
|
115
|
+
- if: '$CI_COMMIT_TAG'
|
|
116
|
+
before_script:
|
|
117
|
+
- |
|
|
118
|
+
if [ -z "$PYPI_API_TOKEN" ]; then
|
|
119
|
+
echo "PYPI_API_TOKEN is unset -- add it as a masked, protected CI/CD variable" >&2
|
|
120
|
+
exit 1
|
|
121
|
+
fi
|
|
122
|
+
script:
|
|
123
|
+
- uv build
|
|
124
|
+
- uv publish --token "$PYPI_API_TOKEN"
|
|
125
|
+
|
|
126
|
+
pages:
|
|
127
|
+
stage: deploy
|
|
128
|
+
image: ghcr.io/astral-sh/uv:python3.11-bookworm
|
|
129
|
+
tags:
|
|
130
|
+
- self-linux
|
|
131
|
+
needs:
|
|
132
|
+
- job: pre-commit
|
|
133
|
+
artifacts: false
|
|
134
|
+
- job: test
|
|
135
|
+
artifacts: false
|
|
136
|
+
rules:
|
|
137
|
+
- if: '$CI_COMMIT_TAG'
|
|
138
|
+
- if: '$CI_COMMIT_BRANCH == "main"'
|
|
139
|
+
# A tag is pushed right after the release commit, so the tag pipeline and the
|
|
140
|
+
# main pipeline overlap. Both push $MIKE_BRANCH; serialize them or the second
|
|
141
|
+
# one dies on a non-fast-forward.
|
|
142
|
+
resource_group: pages
|
|
143
|
+
variables:
|
|
144
|
+
UV_CACHE_DIR: "$CI_PROJECT_DIR/.cache/uv"
|
|
145
|
+
# mike appends to the published site by resetting the local branch to
|
|
146
|
+
# origin/$MIKE_BRANCH, comparing the two through their merge-base. A shallow
|
|
147
|
+
# clone has no merge-base to find.
|
|
148
|
+
GIT_DEPTH: "0"
|
|
149
|
+
# Where mike keeps the built site. mike itself takes this from
|
|
150
|
+
# `remote_branch` in zensical.toml; it is repeated here only for the two git
|
|
151
|
+
# commands below, so the two have to be changed together.
|
|
152
|
+
MIKE_BRANCH: pages
|
|
153
|
+
cache:
|
|
154
|
+
key:
|
|
155
|
+
files:
|
|
156
|
+
- uv.lock
|
|
157
|
+
paths:
|
|
158
|
+
- .cache/uv
|
|
159
|
+
before_script:
|
|
160
|
+
# The token has to be masked *and* protected: main and the release tags are
|
|
161
|
+
# protected refs, and an unprotected variable is simply absent here, which
|
|
162
|
+
# would otherwise surface as an opaque auth failure at push time.
|
|
163
|
+
- |
|
|
164
|
+
if [ -z "$MIKE_ACCESS_TOKEN" ]; then
|
|
165
|
+
echo "MIKE_ACCESS_TOKEN is unset -- add it as a masked, protected CI/CD variable" >&2
|
|
166
|
+
exit 1
|
|
167
|
+
fi
|
|
168
|
+
- uv sync --frozen
|
|
169
|
+
- git remote set-url origin "https://oauth2:${MIKE_ACCESS_TOKEN}@${CI_SERVER_HOST}/${CI_PROJECT_PATH}.git"
|
|
170
|
+
- git config user.name "GitLab CI"
|
|
171
|
+
- git config user.email "gitlab-ci@$CI_SERVER_HOST"
|
|
172
|
+
script:
|
|
173
|
+
# --alias-type=copy because mike defaults to publishing an alias as a
|
|
174
|
+
# symlink to the version it points at, and GitLab Pages serves the artifact
|
|
175
|
+
# archive without resolving symlinks: "latest" would 404 while "1.2.3"
|
|
176
|
+
# works. set-default has no such option -- it always writes a real redirect.
|
|
177
|
+
- |
|
|
178
|
+
if [ -n "$CI_COMMIT_TAG" ]; then
|
|
179
|
+
uv run mike deploy --push --update-aliases --alias-type=copy "$CI_COMMIT_TAG" latest
|
|
180
|
+
uv run mike set-default --push latest
|
|
181
|
+
else
|
|
182
|
+
uv run mike deploy --push --update-aliases --alias-type=copy dev
|
|
183
|
+
# mike only creates the "/" redirect once "set-default" has been
|
|
184
|
+
# run at least once. Bootstrap it to "dev" so the site is reachable
|
|
185
|
+
# at "/" before the first release tag exists; once a tag has set
|
|
186
|
+
# the default to "latest", leave it alone on later dev pushes.
|
|
187
|
+
if ! git cat-file -e "$MIKE_BRANCH:index.html" 2>/dev/null; then
|
|
188
|
+
uv run mike set-default --push dev
|
|
189
|
+
fi
|
|
190
|
+
fi
|
|
191
|
+
- rm -rf public && mkdir public
|
|
192
|
+
- git archive "$MIKE_BRANCH" | tar -x -C public
|
|
193
|
+
artifacts:
|
|
194
|
+
paths:
|
|
195
|
+
- public
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
repos:
|
|
2
|
+
- repo: https://github.com/pre-commit/pre-commit-hooks
|
|
3
|
+
rev: v6.0.0
|
|
4
|
+
hooks:
|
|
5
|
+
- id: trailing-whitespace
|
|
6
|
+
exclude: \.t$
|
|
7
|
+
- id: end-of-file-fixer
|
|
8
|
+
- id: check-yaml
|
|
9
|
+
- id: check-toml
|
|
10
|
+
- id: check-merge-conflict
|
|
11
|
+
- id: check-added-large-files
|
|
12
|
+
args: [--maxkb=1000]
|
|
13
|
+
- id: debug-statements
|
|
14
|
+
- repo: https://github.com/codespell-project/codespell
|
|
15
|
+
rev: v2.4.2
|
|
16
|
+
hooks:
|
|
17
|
+
- id: codespell
|
|
18
|
+
name: Spell check source files
|
|
19
|
+
exclude: frontend/package-lock.json
|
|
20
|
+
- repo: https://github.com/astral-sh/ruff-pre-commit
|
|
21
|
+
rev: v0.15.14
|
|
22
|
+
hooks:
|
|
23
|
+
- id: ruff
|
|
24
|
+
args: [--fix]
|
|
25
|
+
- id: ruff-format
|
|
26
|
+
- repo: local
|
|
27
|
+
hooks:
|
|
28
|
+
- id: check-from-imports
|
|
29
|
+
name: Ban from-imports for everything except relative imports
|
|
30
|
+
entry: scripts/check-imports
|
|
31
|
+
language: system
|
|
32
|
+
types: [python]
|
|
33
|
+
- id: pyright
|
|
34
|
+
name: Type checking for python
|
|
35
|
+
entry: uv run --frozen pyright
|
|
36
|
+
language: system
|
|
37
|
+
types: [python]
|
|
38
|
+
pass_filenames: false
|
|
39
|
+
- id: licensecheck
|
|
40
|
+
name: License compatibility
|
|
41
|
+
entry: uv run --frozen licensecheck
|
|
42
|
+
language: system
|
|
43
|
+
pass_filenames: false
|
|
44
|
+
- id: uv-audit
|
|
45
|
+
name: Vulnerability scan (uv audit)
|
|
46
|
+
entry: uv audit
|
|
47
|
+
language: system
|
|
48
|
+
pass_filenames: false
|
utrain-0.0.4/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 INRIA
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
utrain-0.0.4/Makefile
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
.PHONY: all presets frontend check cram FORCE
|
|
2
|
+
|
|
3
|
+
all: presets
|
|
4
|
+
|
|
5
|
+
frontend:
|
|
6
|
+
cd frontend && npm install && npm run build
|
|
7
|
+
|
|
8
|
+
presets: containers/shakespeare-char
|
|
9
|
+
|
|
10
|
+
containers/%: FORCE
|
|
11
|
+
podman build -t utrain-$*:utrain -f containers/$*/Containerfile .
|
|
12
|
+
|
|
13
|
+
cram:
|
|
14
|
+
uv run pytest tests/test_cram.py
|
|
15
|
+
|
|
16
|
+
check:
|
|
17
|
+
uv run pre-commit run --all-files
|
|
18
|
+
|
|
19
|
+
cov:
|
|
20
|
+
@rm -rf .coverage .coverage.*
|
|
21
|
+
PYTHONUNBUFFERED=1 COVERAGE_PROCESS_START=$(shell pwd)/pyproject.toml COVERAGE_FILE=$(shell pwd)/.coverage uv run pytest
|
|
22
|
+
|
|
23
|
+
cov-report:
|
|
24
|
+
COVERAGE_FILE=$(shell pwd)/.coverage uv run coverage combine --rcfile $(shell pwd)/pyproject.toml -a -q || true
|
|
25
|
+
COVERAGE_FILE=$(shell pwd)/.coverage uv run coverage html -d cov --rcfile $(shell pwd)/pyproject.toml
|
|
26
|
+
COVERAGE_FILE=$(shell pwd)/.coverage uv run coverage report
|
utrain-0.0.4/PKG-INFO
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: utrain
|
|
3
|
+
Version: 0.0.4
|
|
4
|
+
Summary: Local web UI for end-to-end LLM training
|
|
5
|
+
License: MIT
|
|
6
|
+
License-File: LICENSE
|
|
7
|
+
Requires-Python: >=3.11
|
|
8
|
+
Requires-Dist: anyio>=4.0
|
|
9
|
+
Requires-Dist: fastapi>=0.115
|
|
10
|
+
Requires-Dist: naw>=0.0.4
|
|
11
|
+
Requires-Dist: pydantic-settings>=2.0
|
|
12
|
+
Requires-Dist: pydantic>=2.0
|
|
13
|
+
Requires-Dist: pyyaml>=6.0
|
|
14
|
+
Requires-Dist: sqlalchemy>=2.0
|
|
15
|
+
Requires-Dist: uvicorn[standard]>=0.32
|
utrain-0.0.4/README.md
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# utrain
|
|
2
|
+
|
|
3
|
+
UTrain is a python package that can be run on Linux hosts to manage local SLM training runs:
|
|
4
|
+
- download and install training containers
|
|
5
|
+
- configure your training run
|
|
6
|
+
- monitor the status of your training run
|
|
7
|
+
- check benchmark results
|
|
8
|
+
- manually interact with your model for simple testing
|
|
9
|
+
|
|
10
|
+
If you want to learn how to use utrain, head to our [Documentation](https://mlacage.gitlabpages.inria.fr/utrain).
|
|
11
|
+
|
|
12
|
+
## License
|
|
13
|
+
|
|
14
|
+
MIT — see [LICENSE](https://gitlab.inria.fr/mlacage/utrain/-/raw/main/LICENSE?ref_type=heads)
|
|
File without changes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
build and publish release packages on pypi
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
FROM docker.io/python:3.11-slim
|
|
2
|
+
WORKDIR /app
|
|
3
|
+
RUN pip install --no-cache-dir torch --index-url https://download.pytorch.org/whl/cu121
|
|
4
|
+
RUN pip install --no-cache-dir pyyaml wandb
|
|
5
|
+
COPY containers/shakespeare-char/shakespeare_char.py /app/shakespeare_char.py
|
|
6
|
+
ENTRYPOINT ["python", "/app/shakespeare_char.py"]
|