Skip to content
Merged
Show file tree
Hide file tree
Changes from 46 commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
b5c1ceb
refactor: consolidate dual venvs into single ~/.unsloth/studio/unslot…
rolandtannous Mar 21, 2026
2cdafd0
refactor: separate install.sh (first-time) from setup.sh (smart updat…
rolandtannous Mar 21, 2026
f02d029
fix: install.sh calls setup.sh directly, keep both setup and update C…
rolandtannous Mar 21, 2026
0f151af
fix: use importlib.resources.files() directly without _path attribute
rolandtannous Mar 21, 2026
f3aa7c1
fix: bootstrap uv before pip upgrade to handle uv venvs without pip
rolandtannous Mar 21, 2026
0214283
fix: frontend 404 when launched via CLI, add global symlink to ~/.loc…
rolandtannous Mar 21, 2026
4e0be8f
feat: add --local flag to install.sh and unsloth studio update for br…
rolandtannous Mar 22, 2026
9e123fc
fix: resolve repo root from script location for --local installs
rolandtannous Mar 22, 2026
4c9c00a
feat: add --package flag to install.sh for testing with custom packag…
rolandtannous Mar 22, 2026
eee17f4
feat: add --package flag to unsloth studio update
rolandtannous Mar 22, 2026
996aba5
fix: always nuke venv in install.sh for clean installs
rolandtannous Mar 22, 2026
ec4e190
revert: remove Windows changes, will handle in separate PR
rolandtannous Mar 22, 2026
ff9a4de
fix: error when --package is passed without an argument
rolandtannous Mar 22, 2026
7afde2e
revert: restore Windows scripts to current main
rolandtannous Mar 22, 2026
4d4e55f
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Mar 22, 2026
4c551d1
Merge branch 'main' into feature/consolidate-envs
rolandtannous Mar 23, 2026
076e5e8
fix: always explicitly set STUDIO_LOCAL_INSTALL and STUDIO_PACKAGE_NA…
rolandtannous Mar 23, 2026
8b0d330
fix: pass explicit STUDIO_LOCAL_REPO env var for --local installs
rolandtannous Mar 23, 2026
97890e9
fix: align banner box for Setup vs Update labels
rolandtannous Mar 23, 2026
7049315
deprecate: hide 'unsloth studio setup' command, point users to update…
rolandtannous Mar 23, 2026
9f05ffe
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Mar 23, 2026
6f122d5
fix: check stdout not stdin for auto-launch detection (curl pipe fix)
rolandtannous Mar 23, 2026
9323188
fix: update install URL to unsloth.ai/install.sh
rolandtannous Mar 24, 2026
d835f98
fix: update install.sh usage comments to unsloth.ai/install.sh
rolandtannous Mar 24, 2026
e1134ee
fix: use --upgrade-package for base deps to preserve existing torch/C…
rolandtannous Mar 24, 2026
aa72130
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Mar 24, 2026
e273228
Merge branch 'main' into feature/consolidate-envs
rolandtannous Mar 24, 2026
7b16036
fix: --local install now also installs unsloth-zoo via base.txt befor…
rolandtannous Mar 24, 2026
165cefe
fix: don't skip base packages for --local installs (editable needs un…
rolandtannous Mar 24, 2026
636a4bd
refactor: move --local full dep install to install.sh, keep SKIP_STUD…
rolandtannous Mar 24, 2026
301291d
feat: add migration support for old .venv and CWD-based installs in s…
rolandtannous Mar 24, 2026
0288709
Revert "feat: add migration support for old .venv and CWD-based insta…
rolandtannous Mar 24, 2026
199fbec
feat: migrate old .venv layout in install.sh instead of always nuking
rolandtannous Mar 24, 2026
d1ede19
feat: validate old .venv with torch CUDA test before migration, recov…
rolandtannous Mar 24, 2026
b10fa37
fix: try CUDA then fall back to CPU for migration validation
rolandtannous Mar 24, 2026
af1be61
fix: upgrade unsloth/unsloth-zoo with --reinstall-package on migratio…
rolandtannous Mar 24, 2026
ab2909f
Merge branch 'main' into feature/consolidate-envs
rolandtannous Mar 24, 2026
86730e4
Merge branch 'main' into feature/consolidate-envs
danielhanchen Mar 25, 2026
418f51f
remove: delete unused unsloth ui command (use unsloth studio instead)
rolandtannous Mar 25, 2026
49600ef
Fix Windows venv path mismatch between install.ps1, setup.ps1, and st…
danielhanchen Mar 25, 2026
b38344d
setup.ps1: unconditionally error if venv missing, matching setup.sh
danielhanchen Mar 25, 2026
94b8cac
Merge branch 'main' into feature/consolidate-envs
danielhanchen Mar 25, 2026
50b6f22
Fix --torch-backend=auto CPU solver dead-end on Linux, macOS, and Win…
danielhanchen Mar 25, 2026
060535b
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Mar 25, 2026
4a2c6ee
Use --reinstall-package for migrated envs on both Linux and Windows
danielhanchen Mar 25, 2026
def7442
Merge branch 'main' into feature/consolidate-envs
danielhanchen Mar 25, 2026
0af3da5
Merge branch 'main' into feature/consolidate-envs
danielhanchen Mar 25, 2026
3a0abf3
Address review findings: portability, parity, and stale comments
danielhanchen Mar 25, 2026
5d711ed
Add --index-url to migrated env path to prevent CPU torch resolution
danielhanchen Mar 25, 2026
e35f3fb
Revert --index-url on migrated env path
danielhanchen Mar 25, 2026
529246e
Merge branch 'main' into feature/consolidate-envs
danielhanchen Mar 25, 2026
3709657
Fix unsloth studio update --local not installing local checkout
danielhanchen Mar 25, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 70 additions & 18 deletions install.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@
function Install-UnslothStudio {
$ErrorActionPreference = "Stop"

$VenvName = "unsloth_studio"
$PythonVersion = "3.13"
$StudioHome = Join-Path $env:USERPROFILE ".unsloth\studio"
$VenvDir = Join-Path $StudioHome "unsloth_studio"

Write-Host ""
Write-Host "========================================="
Expand Down Expand Up @@ -449,20 +450,59 @@ shell.Run cmd, 0, False
return
}

# ── Create venv (skip if it already exists and has a valid interpreter) ──
# ── Create venv (migrate old layout if possible, otherwise fresh) ──
# Pass the resolved executable path to uv so it does not re-resolve
# a version string back to a conda interpreter.
$VenvPython = Join-Path $VenvName "Scripts\python.exe"
if (-not (Test-Path $StudioHome)) {
New-Item -ItemType Directory -Path $StudioHome -Force | Out-Null
}

$VenvPython = Join-Path $VenvDir "Scripts\python.exe"
$_Migrated = $false

if (Test-Path $VenvPython) {
# New layout already exists -- nuke for fresh install
Write-Host "==> Removing existing environment for fresh install..."
Remove-Item -Recurse -Force $VenvDir
} elseif (Test-Path (Join-Path $StudioHome ".venv\Scripts\python.exe")) {
# Old layout (~/.unsloth/studio/.venv) exists -- validate before migrating
$OldVenv = Join-Path $StudioHome ".venv"
$OldPy = Join-Path $OldVenv "Scripts\python.exe"
Write-Host "==> Found legacy Studio environment, validating..."
$prevEAP2 = $ErrorActionPreference
$ErrorActionPreference = "Continue"
try {
& $OldPy -c "import torch; A = torch.ones((2,2)); B = A + A" 2>$null | Out-Null
$torchOk = ($LASTEXITCODE -eq 0)
} catch { $torchOk = $false }
$ErrorActionPreference = $prevEAP2
if ($torchOk) {
Write-Host " Legacy environment is healthy -- migrating..."
Move-Item -Path $OldVenv -Destination $VenvDir -Force
Write-Host " Moved .venv -> unsloth_studio"
$_Migrated = $true
} else {
Write-Host " Legacy environment failed validation -- creating fresh environment"
Remove-Item -Recurse -Force $OldVenv -ErrorAction SilentlyContinue
}
} elseif (Test-Path (Join-Path $env:USERPROFILE "unsloth_studio\Scripts\python.exe")) {
# CWD-relative venv from old install.ps1 -- migrate to absolute path
$CwdVenv = Join-Path $env:USERPROFILE "unsloth_studio"
Write-Host "==> Found CWD-relative Studio environment, migrating to $VenvDir..."
Move-Item -Path $CwdVenv -Destination $VenvDir -Force
Write-Host " Moved ~/unsloth_studio -> ~/.unsloth/studio/unsloth_studio"
$_Migrated = $true
}

if (-not (Test-Path $VenvPython)) {
if (Test-Path $VenvName) { Remove-Item -Recurse -Force $VenvName }
Write-Host "==> Creating Python $($DetectedPython.Version) virtual environment (${VenvName})..."
uv venv $VenvName --python "$($DetectedPython.Path)"
Write-Host "==> Creating Python $($DetectedPython.Version) virtual environment ($VenvDir)..."
uv venv $VenvDir --python "$($DetectedPython.Path)"
if ($LASTEXITCODE -ne 0) {
Write-Host "[ERROR] Failed to create virtual environment (exit code $LASTEXITCODE)" -ForegroundColor Red
return
}
} else {
Write-Host "==> Virtual environment ${VenvName} already exists, skipping creation."
Write-Host "==> Using migrated environment at $VenvDir"
}

# ── Detect GPU (robust: PATH + hardcoded fallback paths, mirrors setup.ps1) ──
Expand Down Expand Up @@ -536,15 +576,26 @@ shell.Run cmd, 0, False
# CUDA wheels. Missing dependencies (transformers, trl, peft, etc.)
# are still pulled in because they are new, not upgrades.
#
Write-Host "==> Installing PyTorch ($TorchIndexUrl)..."
uv pip install --python $VenvPython torch torchvision torchaudio --index-url $TorchIndexUrl
if ($LASTEXITCODE -ne 0) {
Write-Host "[ERROR] Failed to install PyTorch (exit code $LASTEXITCODE)" -ForegroundColor Red
return
}
if ($_Migrated) {
# 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.11"
} elseif ($TorchIndexUrl) {
Write-Host "==> Installing PyTorch ($TorchIndexUrl)..."
uv pip install --python $VenvPython torch torchvision torchaudio --index-url $TorchIndexUrl
if ($LASTEXITCODE -ne 0) {
Write-Host "[ERROR] Failed to install PyTorch (exit code $LASTEXITCODE)" -ForegroundColor Red
return
}

Write-Host "==> Installing unsloth (this may take a few minutes)..."
uv pip install --python $VenvPython --upgrade-package unsloth "unsloth>=2026.3.11"
Write-Host "==> Installing unsloth (this may take a few minutes)..."
uv pip install --python $VenvPython --upgrade-package unsloth "unsloth>=2026.3.11"
} else {
# Fallback: GPU detection failed to produce a URL -- let uv resolve torch
Write-Host "==> Installing unsloth (this may take a few minutes)..."
uv pip install --python $VenvPython "unsloth>=2026.3.11" --torch-backend=auto
}
if ($LASTEXITCODE -ne 0) {
Write-Host "[ERROR] Failed to install unsloth (exit code $LASTEXITCODE)" -ForegroundColor Red
return
Expand All @@ -554,14 +605,16 @@ shell.Run cmd, 0, False
# setup.ps1 will handle installing Git, CMake, Visual Studio Build Tools,
# CUDA Toolkit, Node.js, and other dependencies automatically via winget.
Write-Host "==> Running unsloth studio setup..."
$UnslothExe = Join-Path $VenvName "Scripts\unsloth.exe"
$UnslothExe = Join-Path $VenvDir "Scripts\unsloth.exe"
if (-not (Test-Path $UnslothExe)) {
Write-Host "[ERROR] unsloth CLI was not installed correctly." -ForegroundColor Red
Write-Host " Expected: $UnslothExe" -ForegroundColor Yellow
Write-Host " This usually means an older unsloth version was installed that does not include the Studio CLI." -ForegroundColor Yellow
Write-Host " Try re-running the installer or see: https://github.com/unslothai/unsloth?tab=readme-ov-file#-quickstart" -ForegroundColor Yellow
return
}
# Tell setup.ps1 to skip base package installation (install.ps1 already did it)
$env:SKIP_STUDIO_BASE = "1"
& $UnslothExe studio setup
if ($LASTEXITCODE -ne 0) {
Write-Host "[ERROR] unsloth studio setup failed (exit code $LASTEXITCODE)" -ForegroundColor Red
Expand All @@ -582,12 +635,11 @@ shell.Run cmd, 0, False
if ($IsInteractive) {
Write-Host "==> Launching Unsloth Studio..."
Write-Host ""
$UnslothExe = Join-Path $VenvName "Scripts\unsloth.exe"
& $UnslothExe studio -H 0.0.0.0 -p 8888
} else {
Write-Host " To launch, run:"
Write-Host ""
Write-Host " .\${VenvName}\Scripts\activate"
Write-Host " & `"$VenvDir\Scripts\Activate.ps1`""
Write-Host " unsloth studio -H 0.0.0.0 -p 8888"
Write-Host ""
}
Expand Down
Loading
Loading