The comment credited bnb PR #1887 as "the ROCm 4-bit GEMV fix" for every
AMD GPU. #1887 decouples blocksize from warp size and fixes a hardcoded
warp size of 32 in kgemm_4bit_inference_naive, which is a CDNA problem by
construction. The RDNA-side work is #1979 (fused 4-bit SIMT GEMM) and
#2012 (RDNA3/4 workgroup resonance). All three first ship in 0.50.0, so
the >=0.50.0 floor is unchanged; only the justification was wrong.
bnb <= 0.49.2 NaNs at decode shape on every AMD GPU. The ROCm 4-bit GEMV
fix (bnb PR #1887) merged after 0.49.2 and its merge commit is an ancestor
of the 0.50.0 tag, so 0.50.0 is the first PyPI release carrying it.
The PyPI wheels ship the ROCm binaries for the platforms these markers
select: libbitsandbytes_rocm{64,70,71,714,72}.so on manylinux x86_64 and
libbitsandbytes_rocm{72,714}.dll on win_amd64. 0.49.1 already required
Python >=3.10, same as 0.50.0, so the Python floor is unchanged.
unsloth_cli/commands/start.py imports click at module scope, and
unsloth_cli/__init__.py imports that module, so every unsloth command needs
it. typer carried click through 0.19 and dropped it in 0.27, and the declared
floor is typer>=0.12.0, so a fresh resolve gets none. The wheel still works
today only because huggingface_hub requires click<9,>=8.4.2, which is luck
rather than a declaration.
Verified on a wheel built from a dependency list without that transitive
provider: every command, including `unsloth --help`, died with
ModuleNotFoundError for click. Same class as the structlog gap in #7493, so
the drift test covers both now.
Resolves 85 conflicted files, all of which trace to the branch's
pre-commit.ci commit 18673a5 rather than to any change this PR authored.
Why the code side takes 'pip':
At the merge base the pip branch's [tool.ruff] table had no line-length,
so ruff-format fell back to its 88 column default and the pre-commit.ci
run reformatted 682 files to 88 columns. Since then 3455b45 ("pip: track
main's packaging and tooling config") added line-length = 100 to pip,
matching main. The bot commit is therefore churn produced under a tooling
config the base branch has since corrected, and re-running the hook on the
merged tree reproduces pip's 100 column formatting, not the branch's.
It also carries no behaviour: all 682 files it touches are .py, and every
one of them is AST identical before and after, so dropping the reformat
drops formatting only. The resolved tree is byte identical to pip
everywhere except pyproject.toml.
pyproject.toml (no textual conflict, but two semantic points):
- torch>=2.4.0,<2.11.0 -> <2.12.0 was made independently on both sides,
by this PR in cd50f9e and on pip in b22b243, with the identical value.
The merged file keeps <2.12.0, so neither side is undone. This also
matches the exclusive _TORCH_CEILING="2.12.0" that #7256 introduces in
install.sh, which expands to torch>=2.4,<2.12.0.
- The huggingfacenotorch and amd extras are this PR's remaining novel
content; pip has neither. They are re-applied on top of pip's file.
The one deliberate rewrite is huggingfacenotorch's unsloth_zoo floor,
from >=2026.7.4 to >=2026.7.6: b22b243 raised every other unsloth_zoo
pin on pip to 2026.7.6, and main's own huggingfacenotorch already says
2026.7.6, so keeping 2026.7.4 would have reintroduced a stale floor that
the base branch had just retired. The amd extra is unchanged from main.
Line level preservation was checked in both directions: all 90477 lines
pip added since the merge base survive, and all 26 lines this branch added
survive except the single unsloth_zoo floor noted above.
* pip: declare the Studio dependencies the wheel's own modules import
The wheel packages studio/ and studio.backend*, so pip install unsloth puts
five commands on PATH -- train, export, chat, inference, studio -- and every one
of them imports studio.backend.*. None of those imports were declared, so all
five ended in a rich traceback at ModuleNotFoundError: No module named
'structlog' (#4701, #5260, #7147). --help rendered fine for all of them because
typer defers the import, which is why this went unnoticed.
Walking module-level, non-try-guarded imports from each entry point shows
structlog is the only hard requirement they share, once starlette's
annotation-only import in loggers/handlers.py moves under TYPE_CHECKING. So
structlog becomes a core dependency and the rest of the server stack (fastapi,
uvicorn, matplotlib, pandas, pymupdf, ...) becomes a [studio] extra mirroring
studio/backend/requirements/studio.txt, with a test that fails if the two drift.
pip install unsloth -> train / export work
pip install "unsloth[studio]" -> the server works
* Apply ruff-format quote normalisation
* Trim the comments added in this PR
The merge keeps this branch's own dependencies and extras, which are
deliberately reduced, but the rest of pyproject.toml should not diverge.
Missing here and present on main:
- unsloth_cli package-data, node_prebuilt_pins.json and the backend/assets
jinja/html globs, so the wheel was not shipping files the code loads
- ruff line-length and pytest pythonpath
test_pins_manifest_is_declared_in_package_data now passes on this branch.
The released torch>=2.4.0,<2.11.0 pin excludes the AMD 2.11.0+rocm wheel, so a
follow-up pip resolve downgrades torch to 2.10.0 and breaks the ROCm install
(#7275). Raise the ceiling to <2.12.0 so the ROCm 2.11 wheel is preserved, and
add an amd extra (pulls huggingfacenotorch, no torch pin) plus a torch-free
huggingfacenotorch extra so AMD users keep their ROCm torch.
[pre-commit.ci skip]
- Add missing cu124onlytorch240 extras (xformers==0.0.28.post1)
- Add sentence-transformers to huggingface and colab-new extras
- Add triton extras group (split out from main deps)
- Add windows extras group
- Drop xformers<0.0.27 cap in colab-no-deps; gate on linux/win + x86_64
- Add [tool.ruff] config (target py311, lint select/ignore, extend-exclude)
- Add [tool.pytest.ini_options] testpaths = ["tests/security"]
Only PyPI-compatible (version-pin) entries copied; URL-based intel/amd/rocm/
flashattentiontorch* extras from main are intentionally skipped.
* Route CPU-only Linux x86_64 to ggml-org/llama.cpp prebuilts
setup.sh hard-coded _HELPER_RELEASE_REPO=unslothai/llama.cpp for every
non-Darwin host. unslothai/llama.cpp only publishes Linux CUDA bundles
(app-*-linux-x64-cuda*.tar.gz), so a CPU-only Linux host walked ~30
releases looking for a non-existent app-*-linux-x64-cpu asset, exited
the prebuilt planner with "no compatible Linux prebuilt asset was
found", and fell through to a source build. Free CI runners
(ubuntu-latest with no GPU) hit this on every install, and anyone
running Studio on a Linux laptop without an NVIDIA GPU paid the
~3 minute cmake+make cost on first install.
ggml-org publishes llama-<tag>-bin-ubuntu-x64.tar.gz on every release
and install_llama_prebuilt.py already knows how to fetch it: when
called with --published-repo ggml-org/llama.cpp, the Linux x86_64 +
not has_usable_nvidia branch in direct_upstream_release_plan picks up
that asset directly. The fix is purely on the routing side.
Tighten the gate so a Linux host routes to ggml-org only when it is
x86_64 and has no GPU detection tool installed (nvidia-smi, rocminfo,
amd-smi, hipconfig, hipinfo). Everything else stays on the current
path:
- macOS: already on ggml-org, unchanged
- Windows: already on ggml-org via setup.ps1, unchanged
- Linux CUDA: nvidia-smi present -> unslothai/llama.cpp, unchanged
- Linux ROCm: rocminfo / amd-smi / hipconfig / hipinfo present
-> unslothai/llama.cpp -> source build with HIP,
unchanged
- Linux Intel / Vulkan / SYCL: no NVIDIA / AMD tools, hits the new
ggml-org route, gets upstream CPU asset (same as
today's source-build CPU output, ~3 min faster)
- Linux arm64 / s390x: not x86_64 -> unslothai/llama.cpp ->
source build, unchanged
* Tighten routing comment in studio/setup.sh
Cuts a new PyPI release that ships PR #5296: Studio chat history and
attachments work again with newer @assistant-ui/react, plus the pinned
assistant-ui surface and frontend package-lock.json so future installs
cannot drift back onto a broken bundle.
- Strip version constraints on Colab dep install
- Upgrade huggingface-hub>=1.0 if is_offline_mode is missing
- ensurepip fallback for uv venvs without pip
- Bump installer pins to 2026.3.14
- colab.py / setup.sh: relax == pins to >= when installing studio.txt
on Colab so huggingface-hub 0.36.2 does not clobber Colab's bundled
version (which breaks transformers is_offline_mode import)
- install_python_stack.py: when uv is unavailable and pip is missing
(uv-created venvs), bootstrap via ensurepip before attempting upgrade
- Bump version to 2026.3.14
studio.txt pins huggingface-hub==0.36.2 and datasets==4.3.0 which
overwrite Colab's pre-installed versions and break its bundled
transformers (is_offline_mode was removed in newer huggingface-hub).
Relax == to >= in both colab.py and setup.sh Colab paths so pip keeps
existing compatible versions instead of force-upgrading.
litellm has been quarantined on PyPI due to a supply chain attack
in version 1.82.8 (malicious credential-stealing .pth file).
No versions are currently installable, which blocks
`unsloth studio setup` at step 8/11 (data-designer deps).
Remove litellm from the single-env data-designer requirements
so setup completes. litellm can be re-added once PyPI lifts the
quarantine.
Ref: https://github.com/BerriAI/litellm/issues/24512