studio: improve Colab notebook, redesign ready popup, and clean up install output (#4339)

* Removing .precommit config

* edited colab comments

* studio: update Unsloth_Studio_Colab.ipynb

* studio: update Unsloth_Studio_Colab.ipynb

* studio: add Colab T4 GPU metadata to force T4 instance

* style: update colab popup to black/white theme with gem icon and play button

* feat: center landscape image in colab notebook

* style: shrink popup to fit content, truncate URL display

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* feat: center landscape image in colab notebook

* feat: use GitHub raw URL for studio landscape image in notebook

* chore: update colab notebook

* feat: add studio landscape colab display image and update notebook

* feat: update notebook with studio landscape image

* style: remove colors, add progress bar, add VERBOSE flag to install output

* docs: add comments explaining VERBOSE flag and progress bar

* chore: update colab notebook

* fix: define VERBOSE, _STEP, _TOTAL at module level to fix NameError

---------

Co-authored-by: LeoBorcherding <LeoBorcherding@users.noreply.github.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
This commit is contained in:
Leo Borcherding 2026-03-16 23:39:25 -05:00 committed by GitHub
commit df98569f12
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 61 additions and 17 deletions

View file

@ -22,6 +22,19 @@ from pathlib import Path
IS_WINDOWS = sys.platform == "win32"
# ── Verbosity control ──────────────────────────────────────────────────────────
# By default the installer shows a minimal progress bar (one line, in-place).
# Set UNSLOTH_VERBOSE=1 in the environment to restore full per-step output:
# Linux/Mac: UNSLOTH_VERBOSE=1 ./studio/setup.sh
# Windows: $env:UNSLOTH_VERBOSE="1" ; .\studio\setup.ps1
VERBOSE: bool = os.environ.get("UNSLOTH_VERBOSE", "0") == "1"
# Progress bar state — updated by _progress() as each install step runs.
# _TOTAL counts: pip-upgrade + 7 shared steps + triton (non-Windows) + local-plugin + finalize
# Update _TOTAL here if you add or remove install steps in install_python_stack().
_STEP: int = 0
_TOTAL: int = 0 # set at runtime in install_python_stack() based on platform
# ── Paths ──────────────────────────────────────────────────────────────
SCRIPT_DIR = Path(__file__).resolve().parent
REQ_ROOT = SCRIPT_DIR / "backend" / "requirements"
@ -59,7 +72,9 @@ def _enable_colors() -> bool:
return True # Unix terminals support ANSI by default
_HAS_COLOR = _enable_colors()
# Colors disabled — Colab and most CI runners render ANSI fine, but plain output
# is cleaner in the notebook cell. Re-enable by setting _HAS_COLOR = _enable_colors()
_HAS_COLOR = False
def _green(msg: str) -> str:
@ -74,11 +89,30 @@ def _red(msg: str) -> str:
return f"\033[91m{msg}\033[0m" if _HAS_COLOR else msg
def _progress(label: str) -> None:
"""Print an in-place progress bar for the current install step.
Uses only stdlib (sys.stdout) no extra packages required.
In VERBOSE mode this is a no-op; per-step labels are printed by run() instead.
"""
global _STEP
_STEP += 1
if VERBOSE:
return # verbose mode: run() already printed the label
width = 20
filled = int(width * _STEP / _TOTAL)
bar = "=" * filled + "-" * (width - filled)
end = "\n" if _STEP >= _TOTAL else "" # newline only on the final step
sys.stdout.write(f"\r[{bar}] {_STEP:2}/{_TOTAL} {label:<40}{end}")
sys.stdout.flush()
def run(
label: str, cmd: list[str], *, quiet: bool = True
) -> subprocess.CompletedProcess[bytes]:
"""Run a command; on failure print output and exit."""
print(_cyan(f" {label}..."))
if VERBOSE:
print(f" {label}...")
result = subprocess.run(
cmd,
stdout = subprocess.PIPE if quiet else None,
@ -196,7 +230,8 @@ def pip_install(
try:
if USE_UV:
uv_cmd = _build_uv_cmd(args) + constraint_args + req_args
print(_cyan(f" {label}..."))
if VERBOSE:
print(f" {label}...")
result = subprocess.run(
uv_cmd,
stdout = subprocess.PIPE,
@ -250,17 +285,19 @@ def patch_package_file(package_name: str, relative_path: str, url: str) -> None:
def install_python_stack() -> int:
global USE_UV
global USE_UV, _STEP, _TOTAL
_STEP = 0
_TOTAL = 10 if IS_WINDOWS else 11
# 1. Upgrade pip (needed even with uv as fallback and for bootstrapping)
_progress("pip upgrade")
run("Upgrading pip", [sys.executable, "-m", "pip", "install", "--upgrade", "pip"])
# Try to use uv for faster installs
USE_UV = _bootstrap_uv()
installer = "uv" if USE_UV else "pip"
print(_cyan(f"── Installing Python stack (via {installer}) ──"))
# 2. Core packages: unsloth-zoo + unsloth
_progress("base packages")
pip_install(
"Installing base packages",
"--no-cache-dir",
@ -268,6 +305,7 @@ def install_python_stack() -> int:
)
# 3. Extra dependencies
_progress("unsloth extras")
pip_install(
"Installing additional unsloth dependencies",
"--no-cache-dir",
@ -275,6 +313,7 @@ def install_python_stack() -> int:
)
# 3b. Extra dependencies (no-deps) — audio model support etc.
_progress("extra codecs")
pip_install(
"Installing extras (no-deps)",
"--no-deps",
@ -283,6 +322,7 @@ def install_python_stack() -> int:
)
# 4. Overrides (torchao, transformers) — force-reinstall
_progress("dependency overrides")
pip_install(
"Installing dependency overrides",
"--force-reinstall",
@ -292,6 +332,7 @@ def install_python_stack() -> int:
# 5. Triton kernels (no-deps, from source)
if not IS_WINDOWS:
_progress("triton kernels")
pip_install(
"Installing triton kernels",
"--no-deps",
@ -322,6 +363,7 @@ def install_python_stack() -> int:
# )
# 8. Studio dependencies
_progress("studio deps")
pip_install(
"Installing studio dependencies",
"--no-cache-dir",
@ -329,6 +371,7 @@ def install_python_stack() -> int:
)
# 9. Data-designer dependencies
_progress("data designer deps")
pip_install(
"Installing data-designer base dependencies",
"--no-cache-dir",
@ -336,6 +379,7 @@ def install_python_stack() -> int:
)
# 10. Data-designer packages (no-deps to avoid conflicts)
_progress("data designer")
pip_install(
"Installing data-designer",
"--no-cache-dir",
@ -351,6 +395,7 @@ def install_python_stack() -> int:
),
)
return 1
_progress("local plugin")
pip_install(
"Installing local data-designer unstructured plugin",
"--no-cache-dir",
@ -360,6 +405,7 @@ def install_python_stack() -> int:
)
# 12. Patch metadata for single-env compatibility
_progress("finalizing")
run(
"Patching single-env metadata",
[sys.executable, str(SINGLE_ENV / "patch_metadata.py")],