Unsloth Docker images (Turing through Blackwell)

Prebuilt Docker images for Unsloth: training, Unsloth Studio, JupyterLab and llama.cpp GGUF tooling, on any current NVIDIA GPU.

Build date 2026-09-04 (second build that day). These tarballs replace the earlier 2026-09-04 build that previously occupied this repository.

All images and outputs in this repository are licensed under the GNU AGPLv3. Copyright 2026-Present the Unsloth team. Source: https://github.com/unslothai/unsloth Website: https://unsloth.ai

The two images

Tarball Loads as Size sha256
unsloth-blackwell-studio.tar.gz unsloth-blackwell:studio-r27 10,526,693,105 B (22,225,218,048 B uncompressed) 148f43fcee18874f2c4c13b191d360f02459d7172e0ac0e0af6dd4668ddc1bc5
unsloth-blackwell-base.tar.gz unsloth-blackwell:base-r27 7,900,812,275 B (15,933,907,456 B uncompressed) 667bbb80a45971fcf2c2ecb87e1275124b0f756ac06a9b8cbea96cca04d9bc07

Studio is the default: Unsloth Studio on :8000, JupyterLab on :8888, sshd optional. Base is training and CLI only, no web UI, and is smaller.

Build provenance

Built from unslothai/unsloth#5748, branch docker-blackwell-build, at branch head 2aeffde94. The exact refs baked into these images:

Build arg Value
UNSLOTH_REF 49dac87ab89a037a83e29776ae9c80296daf4314
UNSLOTH_ZOO_REF 4a1f75db0c3f0593edf16c360308380be253415e
LLAMA_PREBUILT_TAG b10796-mix-659e406 (llama.cpp source commit 66067abbfe2414bd21cd182bd1006d23435aca53)
UNSLOTH_NOTEBOOKS_REF cc4742b4d55fd210d4fb55a6aecb3a7a03101b8a

Every one of those four is checkable inside the image: the two Python refs from direct_url.json in the unsloth and unsloth_zoo dist-info directories, the llama.cpp tag from /opt/unsloth/llama.cpp/UNSLOTH_PREBUILT_INFO.json, and the notebooks ref from /opt/unsloth-notebooks/.unsloth_template_commit. All four were read back from both built images and match this table.

Two things changed since the previous (5d5380f95) build:

  • Six review rounds landed on docker/unsloth_pip_shim.py (+232 lines), docker/unsloth_sync_notebooks.sh, docker/unsloth_nb_compat.py and docker/unsloth_studio_update.sh. All of those ship inside the image.
  • UNSLOTH_REF moved to upstream main at 49dac87ab, so this is the first published image carrying the Studio API auth guard. It is visible at runtime: GET /api/health is public and returns 200, while /api/system, /api/system/hardware, /api/system/gpu-visibility and /api/train/hardware all return 401 without a session.

LLAMA_PREBUILT_TAG also advanced from b10715-mix-86bd2d3 to b10796-mix-659e406. See the llama.cpp section below, which is measured against this build rather than carried over from the previous one.

What is in the image

Component Version
Base image nvidia/cuda:12.8.1-base-ubuntu24.04 (builder stage uses -cudnn-devel-)
Ubuntu 24.04
CUDA toolkit 12.8 (CUDA_VERSION=12.8.1)
Python 3.12
PyTorch 2.11.0+cu128
Triton 3.6.0
xformers 0.0.35
bitsandbytes 0.50.2
unsloth / unsloth-zoo 2026.9.2 / 2026.9.1
transformers / trl / peft / accelerate 5.16.1 / 0.24.0 / 0.20.0 / 1.14.0
vLLM 0.26.0
datasets 4.3.0
JupyterLab 4.6.0
llama.cpp prebuilt b10796-mix-659e406 (portable CUDA 12 bundle)

transformers layout

More than one transformers version ships, on purpose. Nothing needs to be done about this in normal use, but it is worth knowing which environment you are in:

Environment transformers
/opt/unsloth-venv (the default venv, base and Studio images) 5.16.1
/opt/unsloth-venv/tf-sidecars/t_5_5_0 5.5.0
/opt/unsloth-venv/tf-sidecars/t_5_10_2 5.10.2
/opt/unsloth-studio/unsloth_studio (Studio backend, Studio image only) 5.5.0
/opt/unsloth-studio/.venv_t5_510 / _t5_530 / _t5_550 (Studio managed) 5.10.2 / 5.3.0 / 5.5.0

GPU coverage

The cu128 wheels carry native SASS for sm_75, sm_80, sm_86, sm_90, sm_100 and sm_120, confirmed by torch.cuda.get_arch_list() inside the image. SASS is forward compatible within a major version, so every non-Jetson GPU on NVIDIA's current list runs precompiled code, Turing through Blackwell. Source builds use TORCH_CUDA_ARCH_LIST="7.5;8.0;8.6;8.9;9.0;10.0;12.0+PTX". The llama.cpp bundle covers sm_70 through sm_120.

Verified on this build: NVIDIA B200, sm_100, driver-visible as CUDA 12.8.

Load and run

# Studio (default): Studio on :8000, JupyterLab on :8888
curl -L -O https://huggingface.co/danielhanchen/unsloth-blackwell-docker/resolve/main/unsloth-blackwell-studio.tar.gz
sha256sum unsloth-blackwell-studio.tar.gz   # expect 148f43fcee18874f2c4c13b191d360f02459d7172e0ac0e0af6dd4668ddc1bc5
docker load -i unsloth-blackwell-studio.tar.gz

docker run --rm --gpus all --ipc=host --ulimit memlock=-1 \
    -p 127.0.0.1:8000:8000 -p 127.0.0.1:8888:8888 \
    -v "$HOME/.cache/huggingface:/workspace/.cache/huggingface" \
    unsloth-blackwell:studio-r27

The first-boot admin password is printed in the logs and saved to /opt/unsloth-studio/auth/.bootstrap_password. Studio shuts itself down an hour after boot until you change that password.

Publish the ports on 127.0.0.1 as shown unless you intend the machine to serve the internet. The raw port is otherwise reachable by anyone who can route to the host, and server-side tools are enabled by default. To reach Studio from your own machine, forward the port over SSH rather than opening it:

ssh -L 8000:localhost:8000 <user>@<host>
# Base image: training and CLI only
docker load -i unsloth-blackwell-base.tar.gz
docker run --rm --gpus all --ipc=host --ulimit memlock=-1 \
    unsloth-blackwell:base-r27 python3 -c "import torch, unsloth; print(torch.cuda.get_device_name(0))"

Verified on this build

Checks were run against the built images on a B200, and both tarballs were downloaded back from this repository and compared byte-for-byte against what was uploaded.

Check Result
Round-trip sha256 of both tarballs, downloaded vs uploaded match
Shipped unsloth_sync_notebooks.sh / unsloth_pip_shim.py / unsloth_nb_compat.py sha256 vs the source tree at 2aeffde94 identical in BOTH images (no stale build-cache layer)
The second unsloth_nb_compat.py under site-packages, which shadows the /opt/unsloth-nb/ copy on import identical to the same source file, and confirmed to be the one Python actually imports
All four build refs read back from inside both containers match the provenance table
Studio: boot, GET /api/health HTTP 200, {"status":"healthy", ...}
Studio: auth guard /api/system, /api/system/hardware, /api/system/gpu-visibility, /api/train/hardware all 401 without a session
Studio: hardware detection Hardware detected: CUDA -- NVIDIA B200, 4 devices
Studio: JupyterLab login with JUPYTER_PASSWORD, then authenticated GET /api/status and /api/contents login 302, both return 200 with live JSON; the same calls without the cookie return 403
Base/Studio: unsloth --version and unsloth --help 2026.9.2, command list renders
Base/Studio: torch.cuda.get_arch_list() sm_75 sm_80 sm_86 sm_90 sm_100 sm_120
pip shim, 18 cases, run against the shipped shim in both images all 18 behaved as intended (see below)
Notebook sync, cold start 561 notebooks, state file 133,287 B / 1241 records / mode 644, marker stamped
Notebook sync, restart on a persisted /workspace with a forced refresh 680 updated, 0 kept (your edits), 561 kept (only header/footer changed upstream), 0 removed upstream
Notebook sync, --user 1000:1000 boot over a root-created directory refreshes: 1241 updated, 0 kept (your edits); see the caveat about the sync marker below

The 18 pip-shim cases: --root / filtered but --root /tmp/dest bypassed; uppercase GIT+FILE: and HTTPS:// direct references detected; --group and --requirements-from-script refused with exit 1; --upgrade-group not refused; pip download --group forwarded untouched; PIP_REQUIREMENT and PIP_EDITABLE folded in and filtered, and cleared from the child environment while PATH survives; clustered -qr expanded and filtered; uv pip sync refused with exit 1; PIP_TARGET outside the venv bypassed but PIP_TARGET inside it still filtered; UV_PYTHON bypassed for uv but ignored for pip; and uv pip --directory resolving a relative -r from uv's working directory rather than the caller's.

llama.cpp behaviour in this build

The prebuilt bundle moved from b10715-mix-86bd2d3 to b10796-mix-659e406, so the following were re-measured against this image rather than assumed from the previous one. All three behave the same as in b10715:

  • llama-cli rejects -no-cnv (error: invalid argument: -no-cnv, exit 1). One-shot completion lives in llama-completion, which accepts the flag. llama-cli --help offers -st, --single-turn instead.
  • llama-completion on a model with a custom chat template and no --jinja still aborts: terminate called after throwing an instance of 'std::runtime_error', what(): this custom template is not supported, try using --jinja, exit 134 (SIGABRT). With --jinja the same command exits 0. If your shell allows core dumps this writes a very large core file into the working directory; ulimit -c 0 avoids that.
  • The binaries live in /opt/unsloth/llama.cpp/build/bin/ and are not on PATH. llama-server --version reports version: 0.3.0-dev (build 10796, commit 66067abbf).

Known caveats

  • The base image requires a GPU. Without one the entrypoint refuses to start with ERROR: No GPU visible inside the container and a list of the usual causes. Pass -e UNSLOTH_ALLOW_CPU=1 to continue on CPU, which covers Jupyter, GGUF tooling and llama.cpp Studio chat but not training or loading Unsloth models. UNSLOTH_SKIP_GPU_CHECK=1 bypasses the check entirely.
  • --ipc=host matters. The default 64 MB /dev/shm crashes DataLoader workers.
  • The notebook refresh is a detached background child: the foreground unsloth-sync-notebooks populates from the baked template, forks the GitHub refresh with its output sent to /dev/null, and returns. A short-lived docker run --rm ... unsloth-sync-notebooks therefore exits before the refresh does any work. In a normal container this is fine because the container keeps running.
  • If a root boot creates <notebooks dir>/.unsloth_sync_state and .unsloth_sync_commit (root-owned, 0644) and a later boot runs as --user <uid>, the refresh itself succeeds and rewrites the state, but writing the commit marker fails with Permission denied on .unsloth_sync_commit, so the marker never advances and every later non-root boot re-syncs all notebooks from scratch. No notebook or user edit is lost by this; it is wasted work, not data loss. This is not new in this build: the line concerned is byte-identical to the previously published image. Fixed in PR #5748 at dff3e8171 (the marker is now renamed into place like the state file, verified against this exact image with the fixed script mounted over the shipped one); these tarballs were built at 2aeffde94 and predate that commit, so the caveat still applies to them. Workaround until the next publish: run every boot as the same user, or chown the two dot-files in the notebooks directory to that user once.
  • The sync state file takes its mode from the booting process's umask, not from an explicit chmod. At the default umask 022 it is 0644 and a later --user boot can read it. A boot with a restrictive umask (0077) produces a 0600 state file and strands a subsequent non-root boot, which then refuses loudly rather than corrupting it.
  • In these images /opt/unsloth-studio/llama.cpp is a symlink to the prebuilt bundle at /opt/unsloth/llama.cpp. Studio treats a symlinked component directory as externally managed, so it never offers an in-app llama.cpp update: GET /api/llama/update-status returns supported: false with null tags. Run unsloth-llama-update inside the container instead. That script resolves its install directory from UNSLOTH_LLAMA_CPP_PATH, so it works on the real directory and is unaffected.
  • The Studio image exposes 22, 8000 and 8888; the base image exposes 8888. Do not publish any of them on 0.0.0.0 on a host with a public IP.
Downloads last month

-

Downloads are not tracked for this model. How to track
Inference Providers NEW
This model isn't deployed by any Inference Provider. 🙋 Ask for provider support