* fix(install.ps1): detect AMD/no-NVIDIA GPU early and guard unsloth.exe existence When a user has an AMD GPU (no nvidia-smi), uv's --torch-backend=auto resolves to CPU torch, which constrains the solver to unsloth==2024.8. That ancient release has no unsloth.exe CLI entry point, so the subsequent & \ studio setup call throws a confusing PowerShell 'module could not be loaded' CommandNotFoundException instead of a clear error. Two fixes: - Detect nvidia-smi early; if no NVIDIA GPU is found, print a clear error explaining AMD/Intel GPUs are unsupported and exit before wasting time installing the wrong package version. - Guard Test-Path \ before invoking it, so any future case where the CLI entry point is missing produces a readable error instead of a cryptic PowerShell exception. Fixes: unsloth_studio\Scripts\unsloth.exe CommandNotFoundException on AMD GPU systems (Windows). * fix(install.ps1): correct GPU support message - AMD is Linux-only via ROCm * Slim down to just the unsloth.exe existence guard Remove the early NVIDIA GPU detection gate -- Studio supports Windows and Mac without a GPU (finetuning is simply disabled). The GPU gate was blocking legitimate non-NVIDIA users from installing. Keep only the Test-Path guard on unsloth.exe before invoking it. This turns the confusing PowerShell CommandNotFoundException into a clear error message pointing at the likely cause (older unsloth version resolved by the package solver that does not include the Studio CLI). * Fix quickstart link in unsloth.exe guard message --------- Co-authored-by: LeoBorcherding <LeoBorcherding@users.noreply.github.com> Co-authored-by: Daniel Han <danielhanchen@gmail.com>
137 lines
6.1 KiB
PowerShell
137 lines
6.1 KiB
PowerShell
# Unsloth Studio Installer for Windows PowerShell
|
|
# Usage: irm https://raw.githubusercontent.com/unslothai/unsloth/main/install.ps1 | iex
|
|
# Local: Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass; .\install.ps1
|
|
|
|
function Install-UnslothStudio {
|
|
$ErrorActionPreference = "Stop"
|
|
|
|
$VenvName = "unsloth_studio"
|
|
$PythonVersion = "3.13"
|
|
|
|
Write-Host ""
|
|
Write-Host "========================================="
|
|
Write-Host " Unsloth Studio Installer (Windows)"
|
|
Write-Host "========================================="
|
|
Write-Host ""
|
|
|
|
# ── Helper: refresh PATH from registry (preserving current session entries) ──
|
|
function Refresh-SessionPath {
|
|
$machine = [System.Environment]::GetEnvironmentVariable("Path", "Machine")
|
|
$user = [System.Environment]::GetEnvironmentVariable("Path", "User")
|
|
$env:Path = "$machine;$user;$env:Path"
|
|
}
|
|
|
|
# ── Check winget ──
|
|
if (-not (Get-Command winget -ErrorAction SilentlyContinue)) {
|
|
Write-Host "Error: winget is not available." -ForegroundColor Red
|
|
Write-Host " Install it from https://aka.ms/getwinget" -ForegroundColor Yellow
|
|
Write-Host " or install Python $PythonVersion and uv manually, then re-run." -ForegroundColor Yellow
|
|
return
|
|
}
|
|
|
|
# ── Install Python if no compatible version (3.11-3.13) found ──
|
|
$DetectedPythonVersion = ""
|
|
if (Get-Command python -ErrorAction SilentlyContinue) {
|
|
$pyVer = python --version 2>&1
|
|
if ($pyVer -match "Python (3\.1[1-3])\.\d+") {
|
|
Write-Host "==> Python already installed: $pyVer"
|
|
$DetectedPythonVersion = $Matches[1]
|
|
}
|
|
}
|
|
if (-not $DetectedPythonVersion) {
|
|
Write-Host "==> Installing Python ${PythonVersion}..."
|
|
winget install -e --id Python.Python.3.13 --accept-package-agreements --accept-source-agreements
|
|
Refresh-SessionPath
|
|
if ($LASTEXITCODE -ne 0) {
|
|
# winget returns non-zero for "already installed" -- only fail if python is truly missing
|
|
if (-not (Get-Command python -ErrorAction SilentlyContinue)) {
|
|
Write-Host "[ERROR] Python installation failed (exit code $LASTEXITCODE)" -ForegroundColor Red
|
|
return
|
|
}
|
|
}
|
|
$DetectedPythonVersion = $PythonVersion
|
|
}
|
|
|
|
# ── Install uv if not present ──
|
|
if (-not (Get-Command uv -ErrorAction SilentlyContinue)) {
|
|
Write-Host "==> Installing uv package manager..."
|
|
winget install --id=astral-sh.uv -e --accept-package-agreements --accept-source-agreements
|
|
Refresh-SessionPath
|
|
# Fallback: if winget didn't put uv on PATH, try the PowerShell installer
|
|
if (-not (Get-Command uv -ErrorAction SilentlyContinue)) {
|
|
Write-Host " Trying alternative uv installer..."
|
|
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
|
|
Refresh-SessionPath
|
|
}
|
|
}
|
|
|
|
if (-not (Get-Command uv -ErrorAction SilentlyContinue)) {
|
|
Write-Host "Error: uv could not be installed." -ForegroundColor Red
|
|
Write-Host " Install it from https://docs.astral.sh/uv/" -ForegroundColor Yellow
|
|
return
|
|
}
|
|
|
|
# ── Create venv (skip if it already exists and has a valid interpreter) ──
|
|
$VenvPython = Join-Path $VenvName "Scripts\python.exe"
|
|
if (-not (Test-Path $VenvPython)) {
|
|
if (Test-Path $VenvName) { Remove-Item -Recurse -Force $VenvName }
|
|
Write-Host "==> Creating Python ${DetectedPythonVersion} virtual environment (${VenvName})..."
|
|
uv venv $VenvName --python $DetectedPythonVersion
|
|
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."
|
|
}
|
|
|
|
# ── Install unsloth directly into the venv (no activation needed) ──
|
|
Write-Host "==> Installing unsloth (this may take a few minutes)..."
|
|
uv pip install --python $VenvPython unsloth --torch-backend=auto
|
|
if ($LASTEXITCODE -ne 0) {
|
|
Write-Host "[ERROR] Failed to install unsloth (exit code $LASTEXITCODE)" -ForegroundColor Red
|
|
return
|
|
}
|
|
|
|
# ── Run studio setup ──
|
|
# 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"
|
|
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
|
|
}
|
|
& $UnslothExe studio setup
|
|
if ($LASTEXITCODE -ne 0) {
|
|
Write-Host "[ERROR] unsloth studio setup failed (exit code $LASTEXITCODE)" -ForegroundColor Red
|
|
return
|
|
}
|
|
|
|
Write-Host ""
|
|
Write-Host "========================================="
|
|
Write-Host " Unsloth Studio installed!"
|
|
Write-Host "========================================="
|
|
Write-Host ""
|
|
|
|
# Launch studio automatically in interactive terminals;
|
|
# in non-interactive environments (CI, Docker) just print instructions.
|
|
$IsInteractive = [Environment]::UserInteractive -and (-not [Console]::IsInputRedirected)
|
|
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 " unsloth studio -H 0.0.0.0 -p 8888"
|
|
Write-Host ""
|
|
}
|
|
}
|
|
|
|
Install-UnslothStudio
|