-
-
Notifications
You must be signed in to change notification settings - Fork 6.1k
Add Unsloth Docker images (base + Studio) for any NVIDIA GPU host, Ampere through Blackwell #5748
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 4 commits
c6d9216
a75aef0
58693c4
acbb16c
f7b3479
56d2701
23a5b43
fd55ed0
00cbc82
1cdc5f1
dde5170
4bfb4b8
7354642
8344fa0
391532c
e7cfcea
131f1d3
897e5e7
1769204
e728eed
c463d58
fa9609d
34fb65f
215ed9b
6d536d8
79e9363
a01fa21
29a6bde
5cb5eb7
6e45c27
291e2cf
914f91c
0d574d8
a9b8d68
f116f78
c91fa26
cceeeb1
2faf827
6b91708
9723d72
4d34845
10f0a03
f34a4cd
6448587
f1a63db
9e9877e
38d7b5e
e8ac40f
d431f3c
6fd1220
c62bb19
f4e378e
81b0d1e
3d56379
96edc89
b2fe9f4
25d95c0
c515aa0
e06b1fb
3e6d37c
cfeb772
9f9cd41
09c9c95
11430aa
487ea4f
9987323
9d39aee
6f6b638
8242b73
5b4eb34
eba071f
5c5b534
d01da4c
2cd58d5
5bb47cf
ea91c7a
dec240a
aba16af
448e225
d0d5f3c
338aff5
7e2e842
921ab18
d5df6c0
b897cf8
7606081
08f9b67
c0abb0a
053a4f3
52067fb
8f693c6
f45c455
8402dce
0ebbdbb
d476c77
7083a2d
2ee7f4b
2c31686
f152569
68f5394
8fc483e
08a1bf6
034fbc9
6cb2201
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,118 @@ | ||
| # Builds and publishes the Blackwell-compatible Unsloth Docker image. | ||
| # | ||
| # The build runs on a free GitHub-hosted Ubuntu runner with NO GPU attached. | ||
| # This is possible because: | ||
| # 1. cu128 PyTorch wheels are fat binaries -- they already ship sm_70 through | ||
| # sm_120 SASS, cross-compiled upstream by the PyTorch team. | ||
| # 2. The Dockerfile pins explicit wheel URLs (no --torch-backend=auto, no | ||
| # install.sh that introspects the host driver). | ||
| # 3. The build-time sanity check uses torch._C._cuda_getArchFlags(), which | ||
| # reads compiled wheel metadata and does NOT require a CUDA device. | ||
| # 4. UNSLOTH_COMPILE_DISABLE=1 prevents Unsloth from JIT-compiling a Triton | ||
| # kernel cache keyed to the (non-existent) build-host GPU. | ||
| # | ||
| # Required repository secrets: | ||
| # DOCKERHUB_USERNAME, DOCKERHUB_TOKEN | ||
| # | ||
| # Optional repository variable (gates the smoke-test job): | ||
| # HAS_GPU_RUNNER = 'true' if a self-hosted GPU runner is available | ||
|
|
||
| name: Publish Blackwell Docker image | ||
|
|
||
| on: | ||
| push: | ||
| branches: [main] | ||
| tags: ['v*'] | ||
| schedule: | ||
| - cron: '17 4 * * 1' # weekly Mon 04:17 UTC (off-the-hour on purpose) | ||
| workflow_dispatch: | ||
| inputs: | ||
| unsloth_ref: | ||
| description: 'unsloth git ref to bake in' | ||
| required: false | ||
| default: 'main' | ||
| unsloth_zoo_ref: | ||
| description: 'unsloth-zoo git ref to bake in' | ||
| required: false | ||
| default: 'main' | ||
|
|
||
| env: | ||
| REGISTRY: docker.io | ||
| IMAGE_NAME: unsloth/unsloth | ||
|
|
||
| jobs: | ||
| build: | ||
| runs-on: ubuntu-latest # no GPU, 16GB RAM, 4 vCPU | ||
| timeout-minutes: 60 | ||
| permissions: | ||
| contents: read | ||
| packages: write | ||
|
|
||
| steps: | ||
| - uses: actions/checkout@v4 | ||
|
|
||
| # Free up ~20GB on the runner so cu128 wheels + cudnn fit. | ||
| - name: Reclaim disk | ||
| run: | | ||
| sudo rm -rf /usr/share/dotnet /usr/local/lib/android /opt/ghc \ | ||
| /opt/hostedtoolcache/CodeQL "$AGENT_TOOLSDIRECTORY" | ||
| df -h / | ||
|
|
||
| - uses: docker/setup-qemu-action@v3 | ||
| - uses: docker/setup-buildx-action@v3 | ||
|
|
||
| - name: Log in to Docker Hub | ||
| uses: docker/login-action@v3 | ||
| with: | ||
| username: ${{ secrets.DOCKERHUB_USERNAME }} | ||
| password: ${{ secrets.DOCKERHUB_TOKEN }} | ||
|
|
||
| - name: Resolve tags | ||
| id: meta | ||
| uses: docker/metadata-action@v5 | ||
| with: | ||
| images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} | ||
| tags: | | ||
| type=raw,value=latest,enable={{is_default_branch}} | ||
| type=ref,event=tag | ||
| type=schedule,pattern=nightly | ||
| type=sha,prefix=sha-,format=short | ||
|
|
||
| - name: Build and push | ||
| uses: docker/build-push-action@v6 | ||
| with: | ||
| context: ./docker | ||
| file: ./docker/Dockerfile | ||
| platforms: linux/amd64 | ||
| push: true | ||
| tags: ${{ steps.meta.outputs.tags }} | ||
| labels: ${{ steps.meta.outputs.labels }} | ||
| cache-from: type=gha | ||
| cache-to: type=gha,mode=max | ||
| build-args: | | ||
| CUDA_VERSION=12.8.1 | ||
| UBUNTU_VERSION=24.04 | ||
| PYTHON_VERSION=3.12 | ||
| UNSLOTH_REF=${{ github.event.inputs.unsloth_ref || 'main' }} | ||
| UNSLOTH_ZOO_REF=${{ github.event.inputs.unsloth_zoo_ref || 'main' }} | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
For non- Useful? React with 👍 / 👎. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The workflow now pins Useful? React with 👍 / 👎. |
||
|
|
||
| - name: Image digest | ||
| run: echo "${{ steps.meta.outputs.tags }} -> ${{ steps.meta.outputs.digest }}" | ||
|
|
||
| # Optional: pull the freshly published image onto a self-hosted GPU runner | ||
| # and run smoke_test.py. Keeps "did the image actually work" decoupled from | ||
| # "was a GPU available at build time". Skipped automatically when no GPU | ||
| # runner is registered. | ||
| smoke-test: | ||
| needs: build | ||
| if: ${{ vars.HAS_GPU_RUNNER == 'true' }} | ||
| runs-on: [self-hosted, gpu] | ||
| timeout-minutes: 20 | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
| - name: Pull and smoke-test | ||
| run: | | ||
| docker pull ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest | ||
| docker run --rm --gpus all \ | ||
| ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest \ | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The Useful? React with 👍 / 👎. |
||
| python /workspace/smoke_test.py | ||
Check warningCode scanning / CodeQL Workflow does not contain permissions Medium
Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {contents: read}
|
||
|
github-advanced-security[bot] marked this conversation as resolved.
Fixed
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| ** | ||
| !Dockerfile | ||
| !entrypoint.sh | ||
| !smoke_test.py |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,213 @@ | ||
| # syntax=docker/dockerfile:1.7 | ||
| # ----------------------------------------------------------------------------- | ||
| # Unsloth + unsloth-zoo for Blackwell (sm_100 B200 + sm_120 RTX 50-series / 6000 Pro) | ||
| # | ||
| # Why this image works: | ||
| # * cu128 wheels are fat binaries: SASS for sm_80;86;89;90;100;120. | ||
| # * Unsloth's runtime kernels are Triton, which JIT-compiles per device at first run. | ||
| # * Anything that DOES need to be source-built (rare on this pin set) compiles | ||
| # against TORCH_CUDA_ARCH_LIST="10.0;12.0+PTX" -- the host GPU is irrelevant | ||
| # for compilation; nvcc emits whatever the arch list says. | ||
| # | ||
| # Build host requirements: | ||
| # * Docker with buildkit (default since 23.x) | ||
| # * nvidia-container-toolkit (only needed for `docker run --gpus all` at test time) | ||
| # * A GPU is NOT required at build time. | ||
| # ----------------------------------------------------------------------------- | ||
|
|
||
| ARG CUDA_VERSION=12.8.1 | ||
| ARG UBUNTU_VERSION=24.04 | ||
| ARG PYTHON_VERSION=3.12 | ||
|
|
||
| # ============================================================================= | ||
| # Stage 1: builder -- toolkit + dev headers, builds any source extensions | ||
| # ============================================================================= | ||
| FROM nvidia/cuda:${CUDA_VERSION}-cudnn-devel-ubuntu${UBUNTU_VERSION} AS builder | ||
|
|
||
| ARG PYTHON_VERSION | ||
| ENV DEBIAN_FRONTEND=noninteractive \ | ||
| PIP_NO_CACHE_DIR=1 \ | ||
| PIP_DISABLE_PIP_VERSION_CHECK=1 \ | ||
| PYTHONDONTWRITEBYTECODE=1 \ | ||
| PYTHONUNBUFFERED=1 \ | ||
| # Cross-compile for: Ampere, Ada, Hopper, B100/B200 (sm_100), RTX 50x / 6000 Pro (sm_120). | ||
| # +PTX on the highest arch lets future Blackwell SKUs run via JIT-PTX. | ||
| TORCH_CUDA_ARCH_LIST="8.0;8.6;8.9;9.0;10.0;12.0+PTX" \ | ||
| MAX_JOBS=4 \ | ||
| CUDA_HOME=/usr/local/cuda \ | ||
| # Build-host-independence guards. The build must NEVER introspect a GPU, | ||
| # because the build host may have a B200, RTX 6000, or no GPU at all | ||
| # (GitHub Actions ubuntu-latest). All three must yield byte-identical images. | ||
| # | ||
| # 1) Stop unsloth from JIT-compiling kernels at import time and writing a | ||
| # sm_NNN-specific blob into /opt/unsloth-venv/.../unsloth_compiled_cache/. | ||
| UNSLOTH_COMPILE_DISABLE=1 \ | ||
| UNSLOTH_COMPILE_OVERWRITE=0 \ | ||
| # 2) Stop unsloth-zoo / vllm from probing torch.cuda.is_available() during | ||
| # setup. There's no GPU here, and we don't want it to silently skip a wheel. | ||
| UNSLOTH_DISABLE_GPU_PROBE=1 \ | ||
| # 3) Force CUDA_VISIBLE_DEVICES empty so any stray torch.cuda call during | ||
| # `pip install` returns "no devices" rather than triggering host-specific | ||
| # code paths (we re-enable at runtime via `docker run --gpus all`). | ||
| CUDA_VISIBLE_DEVICES="" | ||
|
|
||
| RUN apt-get update && apt-get install -y --no-install-recommends \ | ||
| software-properties-common ca-certificates curl git build-essential \ | ||
| ninja-build cmake pkg-config \ | ||
| && add-apt-repository -y ppa:deadsnakes/ppa \ | ||
| && apt-get update && apt-get install -y --no-install-recommends \ | ||
| python${PYTHON_VERSION} python${PYTHON_VERSION}-venv python${PYTHON_VERSION}-dev \ | ||
| && ln -sf /usr/bin/python${PYTHON_VERSION} /usr/local/bin/python \ | ||
| && ln -sf /usr/bin/python${PYTHON_VERSION} /usr/local/bin/python3 \ | ||
| && curl -fsSL https://bootstrap.pypa.io/get-pip.py | python \ | ||
| && python -m pip install -U pip uv \ | ||
| && rm -rf /var/lib/apt/lists/* | ||
|
|
||
| # Build into an isolated prefix that we copy into the runtime stage. | ||
| ENV VENV=/opt/unsloth-venv | ||
| RUN python -m venv ${VENV} && ${VENV}/bin/pip install -U pip wheel setuptools | ||
|
|
||
| # Unified install: torch + triton + bitsandbytes + unsloth + unsloth_zoo | ||
| # resolve in a SINGLE uv pip pass. This is mandatory -- splitting it across | ||
| # multiple `pip install` calls causes bnb's transitive `cuda-toolkit` dep to | ||
| # silently upgrade torch to 2.12.0+cu130 in a later pass, breaking the cu128 | ||
| # xformers wheel that was pinned earlier. (Empirically discovered; the cu cascade | ||
| # happens AFTER xformers is already on disk, leaving a working-but-mismatched env.) | ||
| # | ||
| # uv-specific flags explained: | ||
| # --index-strategy unsafe-best-match | ||
| # The PyTorch index serves an old `requests==2.28.1` which conflicts with | ||
| # `datasets>=2.32.2`. uv's default is "first index wins per package" to | ||
| # prevent dependency confusion; we override here because both indexes | ||
| # (pytorch.org/whl/cu128 + pypi.org) are equally trusted. | ||
| # --extra-index-url https://download.pytorch.org/whl/cu128 | ||
| # Where torch's +cu128 wheels live, plus the xformers/cu128 URLs referenced | ||
| # by unsloth's `cu128onlytorch2100` extra. | ||
| # | ||
| # Why the extra is `cu128-ampere-torch2100` (not `cu128-torch2100-ampere`): | ||
| # See unsloth_src/pyproject.toml:835. The ordering is ampere-then-torch-ver. | ||
| # | ||
| # Why no `flash-attn` here: | ||
| # - FA3 is hard-refused on Blackwell (Dao-AILab/flash-attention#1810). | ||
| # - FA2 has no prebuilt wheel for cu128+torch2.10+cp312 -> would require | ||
| # a ~30min source build, fragile on the 16GB ubuntu-latest CI runner. | ||
| # - Unsloth gracefully falls back to xformers/SDPA on Blackwell anyway. | ||
| # - Users on Ampere/Ada/Hopper who want FA2 can `pip install flash-attn` | ||
| # on top of this image at deploy time. | ||
| ARG UNSLOTH_REF=main | ||
| ARG UNSLOTH_ZOO_REF=main | ||
| RUN ${VENV}/bin/pip install uv \ | ||
| && ${VENV}/bin/uv pip install \ | ||
| --python ${VENV}/bin/python \ | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The |
||
| --index-strategy unsafe-best-match \ | ||
| --extra-index-url https://download.pytorch.org/whl/cu128 \ | ||
| "torch==2.10.0" "torchvision==0.25.0" "torchaudio==2.11.0" \ | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There appears to be a version mismatch for There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The install set mixes Useful? React with 👍 / 👎. |
||
| "triton>=3.3.1" \ | ||
| "bitsandbytes>=0.49.2,!=0.46.0,!=0.48.0" \ | ||
| "unsloth_zoo @ git+https://github.com/unslothai/unsloth-zoo@${UNSLOTH_ZOO_REF}" \ | ||
| "unsloth[cu128-ampere-torch2100] @ git+https://github.com/unslothai/unsloth@${UNSLOTH_REF}" | ||
|
|
||
| # 5) Emit a lockfile so the next rebuild can be byte-identical even if PyPI | ||
| # has moved on. Bake it into the image at /opt/unsloth-venv/requirements.lock.txt | ||
| # so `docker run ... cat /opt/unsloth-venv/requirements.lock.txt > pins.txt` | ||
| # gives you the input to a fully-pinned rebuild. | ||
| RUN ${VENV}/bin/pip freeze --exclude-editable > ${VENV}/requirements.lock.txt \ | ||
| && head -50 ${VENV}/requirements.lock.txt | ||
|
|
||
| # 6) Strip pip cache & __pycache__ to shrink the layer copied to runtime. | ||
| RUN find ${VENV} -depth -type d -name __pycache__ -exec rm -rf {} + \ | ||
| && find ${VENV} -depth -type d -name tests -exec rm -rf {} + \ | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
This cleanup step removes every Useful? React with 👍 / 👎. |
||
| && rm -rf /root/.cache/pip /root/.cache/uv | ||
|
|
||
| # Build-time verification. | ||
| # | ||
| # (1) arch-list check uses the RAW C++ accessor (not torch.cuda.get_arch_list()). | ||
| # The Python wrapper checks torch.cuda.is_available() first and returns [] | ||
| # when no GPU is visible -- which is always the case here because | ||
| # CUDA_VISIBLE_DEVICES is empty by design. | ||
| # | ||
| # (2) We verify required packages via package metadata only -- we do NOT import | ||
| # unsloth or unsloth_zoo here. Their __init__ calls torch.cuda.get_device_ | ||
| # properties(0) which requires an actual CUDA device (UNSLOTH_ALLOW_CPU=1 | ||
| # only bypasses the first gate, not the deeper init). Import-time | ||
| # correctness is exercised at deploy time by smoke_test.py with --gpus all. | ||
| RUN ${VENV}/bin/python - <<'PY' | ||
| import torch | ||
| arches = torch._C._cuda_getArchFlags().split() | ||
| print("torch", torch.__version__, "cuda", torch.version.cuda) | ||
| print("arches:", arches) | ||
| assert torch.__version__.startswith("2.10.0"), f"torch silently moved: {torch.__version__}" | ||
| assert "+cu128" in torch.__version__, f"cu build silently changed: {torch.__version__}" | ||
| assert "sm_100" in arches, f"sm_100 (B200) missing: {arches}" | ||
| assert "sm_120" in arches, f"sm_120 (RTX 5090) missing: {arches}" | ||
| print("OK: torch 2.10.0+cu128 with sm_100 + sm_120 fat binary intact") | ||
|
|
||
| from importlib.metadata import version, PackageNotFoundError | ||
| REQUIRED = ("torch", "triton", "xformers", "bitsandbytes", "unsloth", | ||
| "unsloth_zoo", "transformers", "trl", "peft", "accelerate") | ||
| missing = [] | ||
| for pkg in REQUIRED: | ||
| try: | ||
| v = version(pkg.replace("_", "-")) | ||
| print(f" {pkg:14s} {v}") | ||
| except PackageNotFoundError: | ||
| missing.append(pkg) | ||
| if missing: | ||
| raise SystemExit(f"FAIL: missing wheels: {missing}") | ||
| print("OK: all required wheels present (xformers, bnb, unsloth metadata visible)") | ||
|
|
||
| # Lightweight imports: these init without touching CUDA, unlike unsloth. | ||
| import importlib | ||
| for pkg in ("xformers", "bitsandbytes", "triton"): | ||
| importlib.import_module(pkg) | ||
| print("OK: xformers + bitsandbytes + triton import cleanly on no-GPU host") | ||
| PY | ||
|
|
||
| # ============================================================================= | ||
| # Stage 2: runtime -- slim runtime image, no nvcc, no headers | ||
| # ============================================================================= | ||
| FROM nvidia/cuda:${CUDA_VERSION}-cudnn-runtime-ubuntu${UBUNTU_VERSION} AS runtime | ||
|
|
||
| ARG PYTHON_VERSION | ||
| ENV DEBIAN_FRONTEND=noninteractive \ | ||
| PIP_NO_CACHE_DIR=1 \ | ||
| PYTHONDONTWRITEBYTECODE=1 \ | ||
| PYTHONUNBUFFERED=1 \ | ||
| PATH=/opt/unsloth-venv/bin:${PATH} \ | ||
| HF_HOME=/workspace/.cache/huggingface \ | ||
| TRITON_CACHE_DIR=/workspace/.cache/triton \ | ||
|
Comment on lines
+504
to
+505
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Setting |
||
| # Keep the arch list visible at runtime in case the user source-builds anything | ||
| # extra inside the container (e.g. a custom CUDA op). | ||
| TORCH_CUDA_ARCH_LIST="8.0;8.6;8.9;9.0;10.0;12.0+PTX" | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The runtime image advertises support from Turing onward (see Useful? React with 👍 / 👎. |
||
|
|
||
| RUN apt-get update && apt-get install -y --no-install-recommends \ | ||
| software-properties-common ca-certificates curl git libgomp1 \ | ||
| && add-apt-repository -y ppa:deadsnakes/ppa \ | ||
| && apt-get update && apt-get install -y --no-install-recommends \ | ||
| python${PYTHON_VERSION} python${PYTHON_VERSION}-venv \ | ||
| && ln -sf /usr/bin/python${PYTHON_VERSION} /usr/local/bin/python \ | ||
| && ln -sf /usr/bin/python${PYTHON_VERSION} /usr/local/bin/python3 \ | ||
| && rm -rf /var/lib/apt/lists/* | ||
|
|
||
| COPY --from=builder /opt/unsloth-venv /opt/unsloth-venv | ||
|
|
||
| WORKDIR /workspace | ||
| RUN mkdir -p ${HF_HOME} ${TRITON_CACHE_DIR} | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
|
|
||
| COPY smoke_test.py /workspace/smoke_test.py | ||
| COPY entrypoint.sh /usr/local/bin/unsloth-entrypoint | ||
| RUN chmod +x /usr/local/bin/unsloth-entrypoint | ||
|
|
||
| # Entrypoint runs three fast pre-flight checks before user code: | ||
| # 1. nvidia-smi sees at least one GPU (catches missing --gpus all) | ||
| # 2. torch.cuda.is_available() is True (catches host driver too old) | ||
| # 3. compute capability >= sm_80 (catches pre-Ampere GPUs) | ||
| # Each check fails with an actionable error pointing to the fix. | ||
| # Bypass for offline tooling: docker run -e UNSLOTH_SKIP_GPU_CHECK=1 ... | ||
| ENTRYPOINT ["/usr/local/bin/unsloth-entrypoint"] | ||
|
|
||
| # Default command: interactive python REPL. | ||
| # Override examples: | ||
| # docker run --gpus all unsloth/unsloth:latest python /workspace/smoke_test.py | ||
| # docker run --gpus all -it unsloth/unsloth:latest bash | ||
| CMD ["python"] | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,46 @@ | ||
| #!/usr/bin/env bash | ||
| # Build the unsloth-blackwell image on this B200 host (or any Linux host with Docker). | ||
| # The build host's GPU is NOT used -- nvcc cross-compiles for sm_100 + sm_120. | ||
| # | ||
| # Usage: | ||
| # ./build.sh # builds unsloth-blackwell:latest pinned to unsloth main | ||
| # TAG=2026.05.1 ./build.sh # custom tag | ||
| # UNSLOTH_REF=v2026.5.6 UNSLOTH_ZOO_REF=v2026.5.4 ./build.sh # pin git refs | ||
| set -euo pipefail | ||
|
|
||
| cd "$(dirname "$0")" | ||
|
|
||
| IMAGE_NAME="${IMAGE_NAME:-unsloth-blackwell}" | ||
| TAG="${TAG:-latest}" | ||
| CUDA_VERSION="${CUDA_VERSION:-12.8.1}" | ||
| UBUNTU_VERSION="${UBUNTU_VERSION:-24.04}" | ||
| PYTHON_VERSION="${PYTHON_VERSION:-3.12}" | ||
| UNSLOTH_REF="${UNSLOTH_REF:-main}" | ||
| UNSLOTH_ZOO_REF="${UNSLOTH_ZOO_REF:-main}" | ||
|
|
||
| echo "Building ${IMAGE_NAME}:${TAG}" | ||
| echo " CUDA ${CUDA_VERSION} Ubuntu ${UBUNTU_VERSION} Python ${PYTHON_VERSION}" | ||
| echo " unsloth @${UNSLOTH_REF}" | ||
| echo " unsloth-zoo @${UNSLOTH_ZOO_REF}" | ||
| echo " arch list 8.0;8.6;8.9;9.0;10.0;12.0+PTX" | ||
| echo | ||
|
|
||
| DOCKER_BUILDKIT=1 docker build \ | ||
| --progress=plain \ | ||
| --build-arg CUDA_VERSION="${CUDA_VERSION}" \ | ||
| --build-arg UBUNTU_VERSION="${UBUNTU_VERSION}" \ | ||
| --build-arg PYTHON_VERSION="${PYTHON_VERSION}" \ | ||
| --build-arg UNSLOTH_REF="${UNSLOTH_REF}" \ | ||
| --build-arg UNSLOTH_ZOO_REF="${UNSLOTH_ZOO_REF}" \ | ||
| -t "${IMAGE_NAME}:${TAG}" \ | ||
| . | ||
|
|
||
| echo | ||
| echo "Built ${IMAGE_NAME}:${TAG}" | ||
| echo | ||
| echo "Smoke test on this host (B200, sm_100):" | ||
| echo " docker run --rm --gpus all ${IMAGE_NAME}:${TAG} python /workspace/smoke_test.py" | ||
| echo | ||
| echo "Smoke test on an RTX 5090 host (sm_120):" | ||
| echo " docker pull ${IMAGE_NAME}:${TAG} # or load .tar" | ||
| echo " docker run --rm --gpus all ${IMAGE_NAME}:${TAG} python /workspace/smoke_test.py" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
latestThis tag rule publishes
latestwhenever the run is on the default branch, butworkflow_dispatchalso allows overridingUNSLOTH_REF/UNSLOTH_ZOO_REFto arbitrary refs. A manual test run frommaincan therefore push a non-release image aslatest, which makes downstream users pull an unintended build. Gatelatestto trusted release flows (or only when both refs are the defaults) to avoid accidental retagging.Useful? React with 👍 / 👎.