Compare commits
3 commits
main
...
feature/do
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b9e6016095 | ||
|
|
2cfb83dc71 | ||
|
|
44454091c0 |
4 changed files with 236 additions and 212 deletions
|
|
@ -416,169 +416,155 @@ def install_python_stack() -> int:
|
||||||
base_total -= 1 # triton step is skipped on macOS
|
base_total -= 1 # triton step is skipped on macOS
|
||||||
_TOTAL = (base_total - 1) if skip_base else base_total
|
_TOTAL = (base_total - 1) if skip_base else base_total
|
||||||
|
|
||||||
# 1. Try to use uv for faster installs (must happen before pip upgrade
|
# # 1. Try to use uv for faster installs (must happen before pip upgrade
|
||||||
# because uv venvs don't include pip by default)
|
# # because uv venvs don't include pip by default)
|
||||||
USE_UV = _bootstrap_uv()
|
# USE_UV = _bootstrap_uv()
|
||||||
|
|
||||||
# 2. Ensure pip is available (uv venvs created by install.sh don't include pip)
|
# # 2. Ensure pip is available (uv venvs created by install.sh don't include pip)
|
||||||
_progress("pip bootstrap")
|
# _progress("pip bootstrap")
|
||||||
if USE_UV:
|
# if USE_UV:
|
||||||
run(
|
# run(
|
||||||
"Bootstrapping pip via uv",
|
# "Bootstrapping pip via uv",
|
||||||
[
|
# [
|
||||||
"uv",
|
# "uv",
|
||||||
"pip",
|
# "pip",
|
||||||
"install",
|
# "install",
|
||||||
"--python",
|
# "--python",
|
||||||
sys.executable,
|
# sys.executable,
|
||||||
"pip",
|
# "pip",
|
||||||
],
|
# ],
|
||||||
)
|
# )
|
||||||
else:
|
# else:
|
||||||
# pip may not exist yet (uv-created venvs omit it). Try ensurepip
|
# # pip may not exist yet (uv-created venvs omit it). Try ensurepip
|
||||||
# first, then upgrade. Only fall back to a direct upgrade when pip
|
# # first, then upgrade. Only fall back to a direct upgrade when pip
|
||||||
# is already present.
|
# # is already present.
|
||||||
_has_pip = (
|
# _has_pip = (
|
||||||
subprocess.run(
|
# subprocess.run(
|
||||||
[sys.executable, "-m", "pip", "--version"],
|
# [sys.executable, "-m", "pip", "--version"],
|
||||||
stdout = subprocess.DEVNULL,
|
# stdout = subprocess.DEVNULL,
|
||||||
stderr = subprocess.DEVNULL,
|
# stderr = subprocess.DEVNULL,
|
||||||
).returncode
|
# ).returncode
|
||||||
== 0
|
# == 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"],
|
||||||
|
# )
|
||||||
|
|
||||||
if not _has_pip:
|
# # 3. Core packages: unsloth-zoo + unsloth (or custom package name)
|
||||||
run(
|
# if skip_base:
|
||||||
"Bootstrapping pip via ensurepip",
|
# print(_green(f"✅ {package_name} already installed — skipping base packages"))
|
||||||
[sys.executable, "-m", "ensurepip", "--upgrade"],
|
# elif NO_TORCH:
|
||||||
)
|
# # No-torch update path: install unsloth + unsloth-zoo with --no-deps
|
||||||
else:
|
# # (current PyPI metadata still declares torch as a hard dep), then
|
||||||
run(
|
# # runtime deps with --no-deps (avoids transitive torch).
|
||||||
"Upgrading pip",
|
# _progress("base packages (no torch)")
|
||||||
[sys.executable, "-m", "pip", "install", "--upgrade", "pip"],
|
# pip_install(
|
||||||
)
|
# f"Updating {package_name} + unsloth-zoo (no-torch mode)",
|
||||||
|
# "--no-cache-dir",
|
||||||
|
# "--no-deps",
|
||||||
|
# "--upgrade-package",
|
||||||
|
# package_name,
|
||||||
|
# "--upgrade-package",
|
||||||
|
# "unsloth-zoo",
|
||||||
|
# package_name,
|
||||||
|
# "unsloth-zoo",
|
||||||
|
# )
|
||||||
|
# pip_install(
|
||||||
|
# "Installing no-torch runtime deps",
|
||||||
|
# "--no-cache-dir",
|
||||||
|
# "--no-deps",
|
||||||
|
# req = REQ_ROOT / "no-torch-runtime.txt",
|
||||||
|
# )
|
||||||
|
# if local_repo:
|
||||||
|
# pip_install(
|
||||||
|
# "Overlaying local repo (editable)",
|
||||||
|
# "--no-cache-dir",
|
||||||
|
# "--no-deps",
|
||||||
|
# "-e",
|
||||||
|
# local_repo,
|
||||||
|
# constrain = False,
|
||||||
|
# )
|
||||||
|
# elif local_repo:
|
||||||
|
# _progress("base packages")
|
||||||
|
# pip_install(
|
||||||
|
# "Updating base packages",
|
||||||
|
# "--no-cache-dir",
|
||||||
|
# "--upgrade-package",
|
||||||
|
# "unsloth",
|
||||||
|
# "--upgrade-package",
|
||||||
|
# "unsloth-zoo",
|
||||||
|
# req = REQ_ROOT / "base.txt",
|
||||||
|
# )
|
||||||
|
# pip_install(
|
||||||
|
# "Overlaying local repo (editable)",
|
||||||
|
# "--no-cache-dir",
|
||||||
|
# "--no-deps",
|
||||||
|
# "-e",
|
||||||
|
# local_repo,
|
||||||
|
# constrain = False,
|
||||||
|
# )
|
||||||
|
# elif package_name != "unsloth":
|
||||||
|
# _progress("base packages")
|
||||||
|
# pip_install(
|
||||||
|
# f"Installing {package_name}",
|
||||||
|
# "--no-cache-dir",
|
||||||
|
# package_name,
|
||||||
|
# )
|
||||||
|
# else:
|
||||||
|
# _progress("base packages")
|
||||||
|
# pip_install(
|
||||||
|
# "Updating base packages",
|
||||||
|
# "--no-cache-dir",
|
||||||
|
# "--upgrade-package",
|
||||||
|
# "unsloth",
|
||||||
|
# "--upgrade-package",
|
||||||
|
# "unsloth-zoo",
|
||||||
|
# req = REQ_ROOT / "base.txt",
|
||||||
|
# )
|
||||||
|
|
||||||
# 3. Core packages: unsloth-zoo + unsloth (or custom package name)
|
# pip_install(
|
||||||
if skip_base:
|
# "Installing additional unsloth dependencies",
|
||||||
pass
|
# "--no-cache-dir",
|
||||||
elif NO_TORCH:
|
# req = REQ_ROOT / "extras.txt",
|
||||||
# No-torch update path: install unsloth + unsloth-zoo with --no-deps
|
# )
|
||||||
# (current PyPI metadata still declares torch as a hard dep), then
|
|
||||||
# runtime deps with --no-deps (avoids transitive torch).
|
|
||||||
_progress("base packages (no torch)")
|
|
||||||
pip_install(
|
|
||||||
f"Updating {package_name} + unsloth-zoo (no-torch mode)",
|
|
||||||
"--no-cache-dir",
|
|
||||||
"--no-deps",
|
|
||||||
"--upgrade-package",
|
|
||||||
package_name,
|
|
||||||
"--upgrade-package",
|
|
||||||
"unsloth-zoo",
|
|
||||||
package_name,
|
|
||||||
"unsloth-zoo",
|
|
||||||
)
|
|
||||||
pip_install(
|
|
||||||
"Installing no-torch runtime deps",
|
|
||||||
"--no-cache-dir",
|
|
||||||
"--no-deps",
|
|
||||||
req = REQ_ROOT / "no-torch-runtime.txt",
|
|
||||||
)
|
|
||||||
if local_repo:
|
|
||||||
pip_install(
|
|
||||||
"Overlaying local repo (editable)",
|
|
||||||
"--no-cache-dir",
|
|
||||||
"--no-deps",
|
|
||||||
"-e",
|
|
||||||
local_repo,
|
|
||||||
constrain = False,
|
|
||||||
)
|
|
||||||
elif local_repo:
|
|
||||||
# Local dev install: update deps from base.txt, then overlay the
|
|
||||||
# local checkout as an editable install (--no-deps so torch is
|
|
||||||
# never re-resolved).
|
|
||||||
_progress("base packages")
|
|
||||||
pip_install(
|
|
||||||
"Updating base packages",
|
|
||||||
"--no-cache-dir",
|
|
||||||
"--upgrade-package",
|
|
||||||
"unsloth",
|
|
||||||
"--upgrade-package",
|
|
||||||
"unsloth-zoo",
|
|
||||||
req = REQ_ROOT / "base.txt",
|
|
||||||
)
|
|
||||||
pip_install(
|
|
||||||
"Overlaying local repo (editable)",
|
|
||||||
"--no-cache-dir",
|
|
||||||
"--no-deps",
|
|
||||||
"-e",
|
|
||||||
local_repo,
|
|
||||||
constrain = False,
|
|
||||||
)
|
|
||||||
elif package_name != "unsloth":
|
|
||||||
# Custom package name (e.g. roland-sloth for testing) — install directly
|
|
||||||
_progress("base packages")
|
|
||||||
pip_install(
|
|
||||||
f"Installing {package_name}",
|
|
||||||
"--no-cache-dir",
|
|
||||||
package_name,
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
# Update path: upgrade only unsloth + unsloth-zoo while preserving
|
|
||||||
# existing torch/CUDA installations. Torch is pre-installed by
|
|
||||||
# install.sh / setup.ps1; --upgrade-package targets only base pkgs.
|
|
||||||
_progress("base packages")
|
|
||||||
pip_install(
|
|
||||||
"Updating base packages",
|
|
||||||
"--no-cache-dir",
|
|
||||||
"--upgrade-package",
|
|
||||||
"unsloth",
|
|
||||||
"--upgrade-package",
|
|
||||||
"unsloth-zoo",
|
|
||||||
req = REQ_ROOT / "base.txt",
|
|
||||||
)
|
|
||||||
|
|
||||||
# 3. Extra dependencies
|
# # 3b. Extra dependencies (no-deps) -- audio model support etc.
|
||||||
_progress("unsloth extras")
|
# _progress("extra codecs")
|
||||||
pip_install(
|
# pip_install(
|
||||||
"Installing additional unsloth dependencies",
|
# "Installing extras (no-deps)",
|
||||||
"--no-cache-dir",
|
# "--no-deps",
|
||||||
req = REQ_ROOT / "extras.txt",
|
# "--no-cache-dir",
|
||||||
)
|
# req = REQ_ROOT / "extras-no-deps.txt",
|
||||||
|
# )
|
||||||
|
|
||||||
# 3b. Extra dependencies (no-deps) -- audio model support etc.
|
# # 4. Overrides (torchao, transformers) -- force-reinstall
|
||||||
_progress("extra codecs")
|
# _progress("dependency overrides")
|
||||||
pip_install(
|
# pip_install(
|
||||||
"Installing extras (no-deps)",
|
# "Installing dependency overrides",
|
||||||
"--no-deps",
|
# "--force-reinstall",
|
||||||
"--no-cache-dir",
|
# "--no-cache-dir",
|
||||||
req = REQ_ROOT / "extras-no-deps.txt",
|
# req = REQ_ROOT / "overrides.txt",
|
||||||
)
|
# )
|
||||||
|
|
||||||
# 4. Overrides (torchao, transformers) -- force-reinstall
|
# # 5. Triton kernels (no-deps, from source)
|
||||||
# Skip entirely when torch is unavailable (e.g. Intel Mac GGUF-only mode)
|
# # Skip on Windows (no support) and macOS (no support).
|
||||||
# because overrides.txt contains torchao which requires torch.
|
# if not IS_WINDOWS and not IS_MACOS:
|
||||||
if NO_TORCH:
|
# _progress("triton kernels")
|
||||||
_progress("dependency overrides (skipped, no torch)")
|
# pip_install(
|
||||||
else:
|
# "Installing triton kernels",
|
||||||
_progress("dependency overrides")
|
# "--no-deps",
|
||||||
pip_install(
|
# "--no-cache-dir",
|
||||||
"Installing dependency overrides",
|
# req = REQ_ROOT / "triton-kernels.txt",
|
||||||
"--force-reinstall",
|
# constrain = False,
|
||||||
"--no-cache-dir",
|
# )
|
||||||
req = REQ_ROOT / "overrides.txt",
|
|
||||||
)
|
|
||||||
|
|
||||||
# 5. Triton kernels (no-deps, from source)
|
|
||||||
# Skip on Windows (no support) and macOS (no support).
|
|
||||||
if not IS_WINDOWS and not IS_MACOS:
|
|
||||||
_progress("triton kernels")
|
|
||||||
pip_install(
|
|
||||||
"Installing triton kernels",
|
|
||||||
"--no-deps",
|
|
||||||
"--no-cache-dir",
|
|
||||||
req = REQ_ROOT / "triton-kernels.txt",
|
|
||||||
constrain = False,
|
|
||||||
)
|
|
||||||
|
|
||||||
# # 6. Patch: override llama_cpp.py with fix from unsloth-zoo feature/llama-cpp-windows-support branch
|
# # 6. Patch: override llama_cpp.py with fix from unsloth-zoo feature/llama-cpp-windows-support branch
|
||||||
# patch_package_file(
|
# patch_package_file(
|
||||||
|
|
|
||||||
|
|
@ -352,7 +352,7 @@ if [ -d "$SCRIPT_DIR/backend/core/data_recipe/oxc-validator" ] && command -v npm
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# ── Python venv + deps ──
|
# ── Python venv + deps ──
|
||||||
STUDIO_HOME="$HOME/.unsloth/studio"
|
STUDIO_HOME="${UNSLOTH_STUDIO_HOME:-$HOME/.unsloth/studio}"
|
||||||
VENV_DIR="$STUDIO_HOME/unsloth_studio"
|
VENV_DIR="$STUDIO_HOME/unsloth_studio"
|
||||||
VENV_T5_DIR="$STUDIO_HOME/.venv_t5"
|
VENV_T5_DIR="$STUDIO_HOME/.venv_t5"
|
||||||
|
|
||||||
|
|
@ -362,7 +362,12 @@ VENV_T5_DIR="$STUDIO_HOME/.venv_t5"
|
||||||
# Note: do NOT delete $STUDIO_HOME/.venv here — install.sh handles migration
|
# Note: do NOT delete $STUDIO_HOME/.venv here — install.sh handles migration
|
||||||
|
|
||||||
_COLAB_NO_VENV=false
|
_COLAB_NO_VENV=false
|
||||||
if [ ! -x "$VENV_DIR/bin/python" ]; then
|
_DOCKER_NO_VENV=false
|
||||||
|
if [ -n "$UNSLOTH_DOCKER" ]; then
|
||||||
|
# Docker: packages already in /opt/conda — skip venv entirely.
|
||||||
|
# Only pre-install .venv_t5 for transformers 5.x switching (handled below).
|
||||||
|
_DOCKER_NO_VENV=true
|
||||||
|
elif [ ! -x "$VENV_DIR/bin/python" ]; then
|
||||||
if [ "$IS_COLAB" = true ]; 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
|
# Strip all version constraints so pip keeps Colab's pre-installed
|
||||||
|
|
@ -427,6 +432,38 @@ if [ "$_COLAB_NO_VENV" = true ]; then
|
||||||
substep "continuing to llama.cpp install for GGUF inference support"
|
substep "continuing to llama.cpp install for GGUF inference support"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# In Docker, packages are pre-installed in /opt/conda — only install missing
|
||||||
|
# studio/data-designer deps and pre-install .venv_t5 for transformers 5.x.
|
||||||
|
if [ "$_DOCKER_NO_VENV" = true ]; then
|
||||||
|
echo " Docker detected — skipping venv activation."
|
||||||
|
|
||||||
|
# Install branch's unsloth/unsloth_cli/studio into /opt/conda
|
||||||
|
# (overwrites PyPI version with Docker-aware code)
|
||||||
|
echo " Installing local unsloth from branch..."
|
||||||
|
pip install --force-reinstall --no-deps "$REPO_ROOT"
|
||||||
|
|
||||||
|
# Install only missing deps (studio, data-designer, plugin, metadata patch).
|
||||||
|
# Heavy packages (torch, unsloth, vllm, etc.) are already in /opt/conda.
|
||||||
|
# install_python_stack.py has steps 1-5 commented out for this branch.
|
||||||
|
python "$SCRIPT_DIR/install_python_stack.py"
|
||||||
|
|
||||||
|
# Pre-install transformers 5.x into .venv_t5
|
||||||
|
echo ""
|
||||||
|
echo " Pre-installing transformers 5.x for newer model support..."
|
||||||
|
mkdir -p "$VENV_T5_DIR"
|
||||||
|
pip install --target "$VENV_T5_DIR" --no-deps "transformers==5.3.0" 2>/dev/null
|
||||||
|
pip install --target "$VENV_T5_DIR" --no-deps "huggingface_hub==1.7.1" 2>/dev/null
|
||||||
|
pip install --target "$VENV_T5_DIR" --no-deps "hf_xet==1.4.2" 2>/dev/null
|
||||||
|
pip install --target "$VENV_T5_DIR" "tiktoken" 2>/dev/null
|
||||||
|
echo "✅ Transformers 5.x pre-installed to $VENV_T5_DIR/"
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "╔══════════════════════════════════════╗"
|
||||||
|
echo "║ Docker Studio Setup Complete! ║"
|
||||||
|
echo "╚══════════════════════════════════════╝"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
# ── Check if Python deps need updating ──
|
# ── Check if Python deps need updating ──
|
||||||
# Compare installed package version against PyPI latest.
|
# Compare installed package version against PyPI latest.
|
||||||
# Skip all Python dependency work if versions match (fast update path).
|
# Skip all Python dependency work if versions match (fast update path).
|
||||||
|
|
|
||||||
|
|
@ -1548,7 +1548,6 @@ class FastModel(FastBaseModel):
|
||||||
|
|
||||||
if _clippable_linear_cls is not None:
|
if _clippable_linear_cls is not None:
|
||||||
from peft.tuners.lora.model import LoraModel as _LoraModel
|
from peft.tuners.lora.model import LoraModel as _LoraModel
|
||||||
|
|
||||||
_original_car = _LoraModel._create_and_replace
|
_original_car = _LoraModel._create_and_replace
|
||||||
|
|
||||||
def _patched_car(
|
def _patched_car(
|
||||||
|
|
|
||||||
|
|
@ -84,56 +84,58 @@ def studio_default(
|
||||||
if ctx.invoked_subcommand is not None:
|
if ctx.invoked_subcommand is not None:
|
||||||
return
|
return
|
||||||
|
|
||||||
# Always use the studio venv if it exists and we're not already in it
|
# In Docker, packages live in /opt/conda — skip venv re-exec entirely.
|
||||||
studio_venv_dir = STUDIO_HOME / "unsloth_studio"
|
if not os.environ.get("UNSLOTH_DOCKER"):
|
||||||
in_studio_venv = sys.prefix.startswith(str(studio_venv_dir))
|
# Always use the studio venv if it exists and we're not already in it
|
||||||
|
studio_venv_dir = STUDIO_HOME / "unsloth_studio"
|
||||||
|
in_studio_venv = sys.prefix.startswith(str(studio_venv_dir))
|
||||||
|
|
||||||
if not in_studio_venv:
|
if not in_studio_venv:
|
||||||
studio_python = _studio_venv_python()
|
studio_python = _studio_venv_python()
|
||||||
run_py = _find_run_py()
|
run_py = _find_run_py()
|
||||||
if studio_python and run_py:
|
if studio_python and run_py:
|
||||||
if not silent:
|
if not silent:
|
||||||
typer.echo("Launching Unsloth Studio... Please wait...")
|
typer.echo("Launching Unsloth Studio... Please wait...")
|
||||||
args = [
|
args = [
|
||||||
str(studio_python),
|
str(studio_python),
|
||||||
str(run_py),
|
str(run_py),
|
||||||
"--host",
|
"--host",
|
||||||
host,
|
host,
|
||||||
"--port",
|
"--port",
|
||||||
str(port),
|
str(port),
|
||||||
]
|
]
|
||||||
if frontend:
|
if frontend:
|
||||||
args.extend(["--frontend", str(frontend)])
|
args.extend(["--frontend", str(frontend)])
|
||||||
if silent:
|
if silent:
|
||||||
args.append("--silent")
|
args.append("--silent")
|
||||||
# On Windows, os.execvp() spawns a child but the parent lingers,
|
# On Windows, os.execvp() spawns a child but the parent lingers,
|
||||||
# so Ctrl+C only kills the parent leaving the child orphaned.
|
# so Ctrl+C only kills the parent leaving the child orphaned.
|
||||||
# Use subprocess.run() on Windows so the parent waits for the child.
|
# Use subprocess.run() on Windows so the parent waits for the child.
|
||||||
if sys.platform == "win32":
|
if sys.platform == "win32":
|
||||||
import subprocess as _sp
|
import subprocess as _sp
|
||||||
|
|
||||||
proc = _sp.Popen(args)
|
proc = _sp.Popen(args)
|
||||||
try:
|
try:
|
||||||
rc = proc.wait()
|
rc = proc.wait()
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
# Child has its own signal handler — let it finish
|
# Child has its own signal handler — let it finish
|
||||||
rc = proc.wait()
|
rc = proc.wait()
|
||||||
if rc != 0:
|
if rc != 0:
|
||||||
typer.echo(
|
typer.echo(
|
||||||
f"\nError: Studio server exited unexpectedly (code {rc}).",
|
f"\nError: Studio server exited unexpectedly (code {rc}).",
|
||||||
err = True,
|
err = True,
|
||||||
)
|
)
|
||||||
typer.echo(
|
typer.echo(
|
||||||
"Check the error above. If a package is missing, "
|
"Check the error above. If a package is missing, "
|
||||||
"re-run: unsloth studio setup",
|
"re-run: unsloth studio setup",
|
||||||
err = True,
|
err = True,
|
||||||
)
|
)
|
||||||
raise typer.Exit(rc)
|
raise typer.Exit(rc)
|
||||||
|
else:
|
||||||
|
os.execvp(str(studio_python), args)
|
||||||
else:
|
else:
|
||||||
os.execvp(str(studio_python), args)
|
typer.echo("Studio not set up. Run install.sh first.")
|
||||||
else:
|
raise typer.Exit(1)
|
||||||
typer.echo("Studio not set up. Run install.sh first.")
|
|
||||||
raise typer.Exit(1)
|
|
||||||
|
|
||||||
from studio.backend.run import run_server
|
from studio.backend.run import run_server
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue