diff --git a/install.ps1 b/install.ps1 index 86e4288e8e..3ef251715e 100644 --- a/install.ps1 +++ b/install.ps1 @@ -607,7 +607,7 @@ shell.Run cmd, 0, False # Migrated env: force-reinstall unsloth+unsloth-zoo to ensure clean state # in the new venv location, while preserving existing torch/CUDA Write-Host "==> Upgrading unsloth in migrated environment..." - uv pip install --python $VenvPython --reinstall-package unsloth --reinstall-package unsloth-zoo "unsloth>=2026.3.12" unsloth-zoo + uv pip install --python $VenvPython --reinstall-package unsloth --reinstall-package unsloth-zoo "unsloth>=2026.3.14" unsloth-zoo if ($StudioLocalInstall) { Write-Host "==> Overlaying local repo (editable)..." uv pip install --python $VenvPython -e $RepoRoot --no-deps @@ -622,7 +622,7 @@ shell.Run cmd, 0, False Write-Host "==> Installing unsloth (this may take a few minutes)..." if ($StudioLocalInstall) { - uv pip install --python $VenvPython --upgrade-package unsloth "unsloth>=2026.3.12" unsloth-zoo + uv pip install --python $VenvPython --upgrade-package unsloth "unsloth>=2026.3.14" unsloth-zoo Write-Host "==> Overlaying local repo (editable)..." uv pip install --python $VenvPython -e $RepoRoot --no-deps } else { @@ -632,7 +632,7 @@ shell.Run cmd, 0, False # Fallback: GPU detection failed to produce a URL -- let uv resolve torch Write-Host "==> Installing unsloth (this may take a few minutes)..." if ($StudioLocalInstall) { - uv pip install --python $VenvPython unsloth-zoo "unsloth>=2026.3.12" --torch-backend=auto + uv pip install --python $VenvPython unsloth-zoo "unsloth>=2026.3.14" --torch-backend=auto Write-Host "==> Overlaying local repo (editable)..." uv pip install --python $VenvPython -e $RepoRoot --no-deps } else { diff --git a/install.sh b/install.sh index ebb5b1f9ae..a0f6ef2ee5 100755 --- a/install.sh +++ b/install.sh @@ -767,7 +767,7 @@ if [ "$_MIGRATED" = true ]; then echo "==> Upgrading unsloth in migrated environment..." uv pip install --python "$_VENV_PY" \ --reinstall-package unsloth --reinstall-package unsloth-zoo \ - "unsloth>=2026.3.12" unsloth-zoo + "unsloth>=2026.3.14" unsloth-zoo if [ "$STUDIO_LOCAL_INSTALL" = true ]; then echo "==> Overlaying local repo (editable)..." uv pip install --python "$_VENV_PY" -e "$_REPO_ROOT" --no-deps @@ -781,7 +781,7 @@ elif [ -n "$TORCH_INDEX_URL" ]; then echo "==> Installing unsloth (this may take a few minutes)..." if [ "$STUDIO_LOCAL_INSTALL" = true ]; then uv pip install --python "$_VENV_PY" \ - --upgrade-package unsloth "unsloth>=2026.3.12" unsloth-zoo + --upgrade-package unsloth "unsloth>=2026.3.14" unsloth-zoo echo "==> Overlaying local repo (editable)..." uv pip install --python "$_VENV_PY" -e "$_REPO_ROOT" --no-deps else @@ -792,7 +792,7 @@ else # Fallback: GPU detection failed to produce a URL -- let uv resolve torch echo "==> Installing unsloth (this may take a few minutes)..." if [ "$STUDIO_LOCAL_INSTALL" = true ]; then - uv pip install --python "$_VENV_PY" unsloth-zoo "unsloth>=2026.3.12" --torch-backend=auto + uv pip install --python "$_VENV_PY" unsloth-zoo "unsloth>=2026.3.14" --torch-backend=auto echo "==> Overlaying local repo (editable)..." uv pip install --python "$_VENV_PY" -e "$_REPO_ROOT" --no-deps else diff --git a/studio/backend/colab.py b/studio/backend/colab.py index ad9a7e98b2..deddf28087 100644 --- a/studio/backend/colab.py +++ b/studio/backend/colab.py @@ -30,17 +30,45 @@ def _pip_install_backend_deps() -> None: Used on Colab when the Studio venv does not exist (install.sh was not run). Reads the requirements from studio.txt next to this file. + + Version constraints are stripped entirely so pip keeps whatever Colab + already has installed (e.g. huggingface-hub, datasets, transformers) + and only installs genuinely missing packages like structlog, fastapi. """ + import re import subprocess req_file = Path(__file__).parent / "requirements" / "studio.txt" if not req_file.exists(): return + + packages = [] + for line in req_file.read_text().splitlines(): + line = line.strip() + if not line or line.startswith("#"): + continue + # Strip all version constraints -- just keep the package name + pkg_name = re.split(r"[><=!~;\[]", line)[0].strip() + if pkg_name: + packages.append(pkg_name) + + if not packages: + return print("Installing Studio backend dependencies ...") subprocess.check_call( - [sys.executable, "-m", "pip", "install", "-q", "-r", str(req_file)], + [sys.executable, "-m", "pip", "install", "-q"] + packages, ) + # Colab ships huggingface-hub 0.36.x which removed is_offline_mode, + # breaking transformers. Upgrade to 1.0+ which restored it. + try: + from huggingface_hub import is_offline_mode # noqa: F401 + except ImportError: + print("Upgrading huggingface-hub (is_offline_mode missing) ...") + subprocess.check_call( + [sys.executable, "-m", "pip", "install", "-q", "huggingface-hub>=1.0"], + ) + def _bootstrap_studio_venv() -> None: """Expose the Studio venv's site-packages to the current interpreter. diff --git a/studio/install_python_stack.py b/studio/install_python_stack.py index 39fec2e6f5..2c64695241 100644 --- a/studio/install_python_stack.py +++ b/studio/install_python_stack.py @@ -373,11 +373,29 @@ def install_python_stack() -> int: ], ) else: - run( - "Upgrading pip", - [sys.executable, "-m", "pip", "install", "--upgrade", "pip"], + # pip may not exist yet (uv-created venvs omit it). Try ensurepip + # first, then upgrade. Only fall back to a direct upgrade when pip + # is already present. + _has_pip = ( + subprocess.run( + [sys.executable, "-m", "pip", "--version"], + stdout = subprocess.DEVNULL, + stderr = subprocess.DEVNULL, + ).returncode + == 0 ) + if not _has_pip: + run( + "Bootstrapping pip via ensurepip", + [sys.executable, "-m", "ensurepip", "--upgrade"], + ) + else: + run( + "Upgrading pip", + [sys.executable, "-m", "pip", "install", "--upgrade", "pip"], + ) + # 3. Core packages: unsloth-zoo + unsloth (or custom package name) if skip_base: print(_green(f"✅ {package_name} already installed — skipping base packages")) diff --git a/studio/setup.sh b/studio/setup.sh index dd758e49e8..f103dd95a4 100755 --- a/studio/setup.sh +++ b/studio/setup.sh @@ -295,9 +295,14 @@ VENV_T5_DIR="$STUDIO_HOME/.venv_t5" _COLAB_NO_VENV=false if [ ! -x "$VENV_DIR/bin/python" ]; then if [ "$IS_COLAB" = true ]; then - # On Colab there is no Studio venv -- install backend deps into system Python + # On Colab there is no Studio venv -- install backend deps into system Python. + # Strip all version constraints so pip keeps Colab's pre-installed + # packages (huggingface-hub, datasets, transformers) and only pulls + # in genuinely missing ones (structlog, fastapi, etc.). echo " Colab detected, installing Studio backend dependencies..." - pip install -q -r "$SCRIPT_DIR/backend/requirements/studio.txt" 2>/dev/null || true + sed 's/[><=!~;].*//' "$SCRIPT_DIR/backend/requirements/studio.txt" \ + | grep -v '^#' | grep -v '^$' \ + | pip install -q -r /dev/stdin 2>/dev/null || true _COLAB_NO_VENV=true else echo "❌ ERROR: Virtual environment not found at $VENV_DIR" diff --git a/unsloth/models/_utils.py b/unsloth/models/_utils.py index 1fffc62f81..da912dec76 100644 --- a/unsloth/models/_utils.py +++ b/unsloth/models/_utils.py @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "2026.3.13" +__version__ = "2026.3.14" __all__ = [ "SUPPORTS_BFLOAT16",