Instructions to use danielhanchen/unsloth-blackwell-docker with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Local Apps Settings
- Unsloth Desktop
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.pyanddocker/unsloth_studio_update.sh. All of those ship inside the image. UNSLOTH_REFmoved to upstreammainat49dac87ab, so this is the first published image carrying the Studio API auth guard. It is visible at runtime:GET /api/healthis public and returns 200, while/api/system,/api/system/hardware,/api/system/gpu-visibilityand/api/train/hardwareall 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-clirejects-no-cnv(error: invalid argument: -no-cnv, exit 1). One-shot completion lives inllama-completion, which accepts the flag.llama-cli --helpoffers-st, --single-turninstead.llama-completionon a model with a custom chat template and no--jinjastill 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--jinjathe same command exits 0. If your shell allows core dumps this writes a very large core file into the working directory;ulimit -c 0avoids that.- The binaries live in
/opt/unsloth/llama.cpp/build/bin/and are not onPATH.llama-server --versionreportsversion: 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 containerand a list of the usual causes. Pass-e UNSLOTH_ALLOW_CPU=1to continue on CPU, which covers Jupyter, GGUF tooling and llama.cpp Studio chat but not training or loading Unsloth models.UNSLOTH_SKIP_GPU_CHECK=1bypasses the check entirely. --ipc=hostmatters. The default 64 MB/dev/shmcrashes DataLoader workers.- The notebook refresh is a detached background child: the foreground
unsloth-sync-notebookspopulates from the baked template, forks the GitHub refresh with its output sent to/dev/null, and returns. A short-liveddocker run --rm ... unsloth-sync-notebookstherefore 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_stateand.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 withPermission deniedon.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 atdff3e8171(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 at2aeffde94and predate that commit, so the caveat still applies to them. Workaround until the next publish: run every boot as the same user, orchownthe 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 defaultumask 022it is0644and a later--userboot can read it. A boot with a restrictive umask (0077) produces a0600state file and strands a subsequent non-root boot, which then refuses loudly rather than corrupting it. - In these images
/opt/unsloth-studio/llama.cppis 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-statusreturnssupported: falsewith null tags. Rununsloth-llama-updateinside the container instead. That script resolves its install directory fromUNSLOTH_LLAMA_CPP_PATH, so it works on the real directory and is unaffected. - The Studio image exposes
22,8000and8888; the base image exposes8888. Do not publish any of them on0.0.0.0on a host with a public IP.