Trim verbose PR comments to be succinct
Shorten the multi-line rationale comments added by this PR across the remaining changed files to 1-2 lines each, preserving intent (gotchas, workarounds, why-notes). Comment-only changes; no code, strings, or behavior altered. Verified: PowerShell AST parser, bash -n, and python ast.parse all pass; diffs confirmed comment-only. Files: install.ps1, scripts/uninstall.ps1, scripts/uninstall.sh, studio/setup.sh, unsloth/models/_utils.py, unsloth/kernels/flex_attention.py Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
db0df15f52
commit
0946d5d37f
6 changed files with 113 additions and 214 deletions
149
install.ps1
149
install.ps1
|
|
@ -9,8 +9,7 @@
|
|||
# (DataDir nests inside; user PATH not modified persistently).
|
||||
# Default ($USERPROFILE\.unsloth\studio) is preserved when no env var is set.
|
||||
# UNSLOTH_INSTALL_REF = branch/tag/sha to fetch repo-versioned install assets
|
||||
# from (provision_llama_cuda.sh, the .ico); defaults to 'main'. Lets the
|
||||
# WSL-fallback GPU path be tested on a branch before it merges.
|
||||
# from (provision_llama_cuda.sh, the .ico); defaults to 'main'.
|
||||
|
||||
function Install-UnslothStudio {
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
|
@ -45,10 +44,9 @@ function Install-UnslothStudio {
|
|||
}
|
||||
}
|
||||
|
||||
# Git ref (branch/tag/sha) used to fetch repo-versioned install assets from
|
||||
# raw.githubusercontent.com: provision_llama_cuda.sh and the .ico. Defaults to
|
||||
# 'main' so existing users are byte-for-byte unaffected; set UNSLOTH_INSTALL_REF
|
||||
# to a branch to exercise the WSL-fallback path end-to-end before a PR merges.
|
||||
# Git ref for fetching repo-versioned install assets (provision_llama_cuda.sh,
|
||||
# the .ico) from raw.githubusercontent.com. Defaults to 'main' (unchanged for
|
||||
# existing users); set UNSLOTH_INSTALL_REF to a branch to test pre-merge.
|
||||
function Get-UnslothInstallRef {
|
||||
if ($env:UNSLOTH_INSTALL_REF -and $env:UNSLOTH_INSTALL_REF.Trim()) { return $env:UNSLOTH_INSTALL_REF.Trim() }
|
||||
return 'main'
|
||||
|
|
@ -1470,20 +1468,16 @@ shell.Run cmd, 0, False
|
|||
$TorchIndexUrl = Get-TorchIndexUrl
|
||||
|
||||
# ===== Windows-on-ARM + NVIDIA GPU -> automatic WSL2 fallback (N1X "RTX Spark" / DGX Spark-class) =====
|
||||
# Native Windows-ARM64 has no CUDA PyTorch wheel and no Triton wheel for win_arm64, so the GPU
|
||||
# stack can't run natively today. When an NVIDIA GPU is present on ARM64 AND native CUDA PyTorch is
|
||||
# NOT installable for this platform, set up the supported path: enable/install WSL2, run the Linux
|
||||
# installer there (full GPU), and create a Windows `unsloth` shim that forwards into WSL.
|
||||
# STRICTLY gated -> normal x86_64 Windows (NVIDIA or AMD) and ARM64-without-NVIDIA are byte-for-byte
|
||||
# unaffected and continue the native install below. FUTURE-PROOF: if NVIDIA ships a win_arm64 CUDA
|
||||
# torch wheel, the probe below passes and the native install is kept automatically.
|
||||
# win_arm64 has no CUDA PyTorch/Triton wheel, so the GPU stack can't run natively. On ARM64 with an
|
||||
# NVIDIA GPU and no installable native CUDA torch, route GPU setup through WSL2: enable/install WSL2,
|
||||
# run the Linux installer there (full GPU), and add a Windows `unsloth` shim that forwards into WSL.
|
||||
# Strictly gated: x86_64 and ARM64-without-NVIDIA are unaffected. Future-proof: if a win_arm64 CUDA
|
||||
# torch wheel ships, the probe below passes and native install is kept automatically.
|
||||
# Opt out with UNSLOTH_NO_WSL_FALLBACK=1; choose the distro with UNSLOTH_WSL_DISTRO.
|
||||
try { $_winArm64 = ([System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture.ToString() -ieq 'Arm64') } catch { $_winArm64 = $false }
|
||||
# Robust against x64-EMULATED PowerShell on Windows-on-ARM: under emulation .NET's
|
||||
# OSArchitecture and $env:PROCESSOR_ARCHITECTURE both report X64/AMD64, which would
|
||||
# mis-skip the WSL fallback. Win32_Processor.Architecture (12 = ARM64) and the
|
||||
# machine-level PROCESSOR_ARCHITECTURE read the true OS arch even under emulation.
|
||||
# Additive: can only turn $_winArm64 ON for genuine ARM64 hosts; x86_64 is unaffected.
|
||||
# Under x64-emulated PowerShell on ARM, .NET OSArchitecture and $env:PROCESSOR_ARCHITECTURE report
|
||||
# X64/AMD64; Win32_Processor.Architecture (12=ARM64) and machine-level PROCESSOR_ARCHITECTURE read
|
||||
# the true arch. Additive: only turns $_winArm64 ON for genuine ARM64 hosts.
|
||||
if (-not $_winArm64) {
|
||||
try { if ((@(Get-CimInstance Win32_Processor -ErrorAction Stop))[0].Architecture -eq 12) { $_winArm64 = $true } } catch {}
|
||||
}
|
||||
|
|
@ -1495,11 +1489,9 @@ shell.Run cmd, 0, False
|
|||
}
|
||||
$_nativeCudaTorchOk = $false
|
||||
if ($_winArm64 -and $HasNvidiaSmi -and (-not $SkipTorch)) {
|
||||
# Future-proof check: can a CUDA-capable torch wheel be resolved natively for this platform/index?
|
||||
# MUST use the SAME spec as the real native install below ("torch>=2.4,<2.11.0"). A bare `torch`
|
||||
# probe is too loose -- the cu130 index can carry an out-of-range version (e.g. torch<2.4 or a
|
||||
# nightly >2.11) whose win_arm64 wheel makes the dry-run pass, giving a FALSE POSITIVE that skips
|
||||
# the WSL fallback and then fails the real install at the pinned range.
|
||||
# Can a native CUDA torch wheel be resolved for this platform/index? Must use the SAME spec
|
||||
# as the real install ("torch>=2.4,<2.11.0"): a bare `torch` probe can match an out-of-range
|
||||
# wheel on the index, a false positive that skips WSL then fails the real pinned install.
|
||||
$prevEapProbe = $ErrorActionPreference; $ErrorActionPreference = "Continue"
|
||||
try {
|
||||
& uv pip install --python $VenvPython --dry-run "torch>=2.4,<2.11.0" --index-url $TorchIndexUrl *> $null
|
||||
|
|
@ -1541,23 +1533,17 @@ shell.Run cmd, 0, False
|
|||
try { & wsl.exe --install -d $distro --no-launch } catch {}
|
||||
}
|
||||
substep "installing Unsloth Studio inside WSL '$distro' with full GPU (this downloads PyTorch)..." "Cyan"
|
||||
# When UNSLOTH_INSTALL_REF is a branch/tag/sha (not "main"), fetch THAT ref's
|
||||
# install.sh (which honors UNSLOTH_INSTALL_REF) and export the ref, so install.sh
|
||||
# installs unsloth from that ref -> the WSL studio venv carries this ref's
|
||||
# studio/setup.sh + unsloth Python patches (e.g. the WSL CPU-build skip). Otherwise
|
||||
# install.sh would pull released PyPI unsloth and the branch's setup.sh would never
|
||||
# run pre-merge. Default (ref = main) is byte-identical to before: plain
|
||||
# `curl https://unsloth.ai/install.sh | sh`. The ref is a bare git ref (no spaces),
|
||||
# so it passes cleanly PowerShell -> wsl.exe -> bash -lc.
|
||||
# For a non-main ref, fetch + export THAT ref so the WSL venv gets the branch's
|
||||
# setup.sh + unsloth patches (otherwise install.sh pulls released PyPI unsloth and the
|
||||
# branch never runs pre-merge). main is byte-identical to plain unsloth.ai/install.sh.
|
||||
$_instRef = Get-UnslothInstallRef
|
||||
if ($_instRef -eq 'main') {
|
||||
$wslInstall = 'export DEBIAN_FRONTEND=noninteractive; apt-get update -y >/dev/null 2>&1; apt-get install -y build-essential cmake git curl pciutils >/dev/null 2>&1; curl -fsSL https://unsloth.ai/install.sh | sh'
|
||||
} else {
|
||||
$wslInstall = 'export DEBIAN_FRONTEND=noninteractive; export UNSLOTH_INSTALL_REF=' + $_instRef + '; apt-get update -y >/dev/null 2>&1; apt-get install -y build-essential cmake git curl pciutils >/dev/null 2>&1; curl -fsSL https://raw.githubusercontent.com/unslothai/unsloth/' + $_instRef + '/install.sh | sh'
|
||||
}
|
||||
# install.sh writes diagnostics to stderr and may exit non-zero on the optional llama.cpp
|
||||
# prebuilt step (no aarch64 prebuilt exists) -- that must NOT abort us under -ErrorAction Stop,
|
||||
# since torch + unsloth + Studio still install. Lower EAP around the call (same idiom as above).
|
||||
# install.sh may exit non-zero on the optional llama.cpp prebuilt step (no aarch64 prebuilt)
|
||||
# though torch + unsloth + Studio still install, so lower EAP so it doesn't abort under Stop.
|
||||
$prevEapWsl = $ErrorActionPreference
|
||||
$ErrorActionPreference = "Continue"
|
||||
try {
|
||||
|
|
@ -1567,8 +1553,7 @@ shell.Run cmd, 0, False
|
|||
$ErrorActionPreference = $prevEapWsl
|
||||
}
|
||||
Write-Host ""
|
||||
# The optional llama.cpp prebuilt step exits non-zero on aarch64 (no prebuilt) even when
|
||||
# torch + unsloth + Studio installed fine -- so verify torch.cuda directly instead of trusting $wslRc.
|
||||
# $wslRc can be non-zero from the llama.cpp prebuilt step even on success, so verify torch.cuda directly.
|
||||
$torchOk = $false
|
||||
$prevEapChk = $ErrorActionPreference
|
||||
$ErrorActionPreference = "Continue"
|
||||
|
|
@ -1576,14 +1561,10 @@ shell.Run cmd, 0, False
|
|||
& wsl.exe -d $distro --cd /root -u root -- /root/.unsloth/studio/unsloth_studio/bin/python -c "import torch,sys; sys.exit(0 if torch.cuda.is_available() else 3)" *> $null
|
||||
$torchOk = ($LASTEXITCODE -eq 0)
|
||||
} catch {} finally { $ErrorActionPreference = $prevEapChk }
|
||||
# Self-heal Studio's web-server deps. install.sh installs them in a late step
|
||||
# (install_python_stack.py "studio deps", step 8). If that step is cut short --
|
||||
# an interrupted download, or a transient resolver hiccup -- torch + unsloth still
|
||||
# land, but the server stack (fastapi/uvicorn/structlog/starlette) is missing and
|
||||
# `unsloth studio` dies at launch with ModuleNotFoundError. If the stack can't
|
||||
# import, install it WITHOUT disturbing the working ML stack: we deliberately do
|
||||
# NOT pin huggingface-hub / transformers / datasets here, so the GPU torch path
|
||||
# we just verified stays intact (those pins live in studio.txt for a fresh env).
|
||||
# Self-heal Studio's web-server deps: if install.sh's late "studio deps" step was cut short,
|
||||
# torch + unsloth land but fastapi/uvicorn/structlog/starlette are missing and `unsloth studio`
|
||||
# dies with ModuleNotFoundError. Reinstall those without pinning huggingface-hub/transformers/
|
||||
# datasets, so the verified GPU torch stack stays intact.
|
||||
if ($torchOk) {
|
||||
$_studioPy = "/root/.unsloth/studio/unsloth_studio/bin/python"
|
||||
$_serverOk = $false
|
||||
|
|
@ -1594,14 +1575,10 @@ shell.Run cmd, 0, False
|
|||
} catch {} finally { $ErrorActionPreference = $prevEapS }
|
||||
if (-not $_serverOk) {
|
||||
substep "Studio web-server deps incomplete (install.sh step cut short) -- installing them now..." "Cyan"
|
||||
# Mirrors studio/backend/requirements/studio.txt MINUS the huggingface-hub
|
||||
# pin (protected above). Prefer uv (matches install.sh); fall back to pip.
|
||||
# Bare package names only -- NO version specifiers / embedded quotes.
|
||||
# The whole repair string is passed PowerShell -> wsl.exe -> bash -lc, and
|
||||
# PowerShell's native-arg quoting mangles embedded double-quotes, so a
|
||||
# "structlog>=24.1.0" loses its quotes and bash parses `>=` as a redirection,
|
||||
# failing the whole install. uv resolves the latest of each (which satisfies
|
||||
# the studio.txt minimums anyway), so bare names are sufficient and safe.
|
||||
# Mirrors studio.txt minus the huggingface-hub pin (protected above); uv preferred,
|
||||
# pip fallback. Bare names only -- a version spec's quotes get mangled through
|
||||
# PowerShell -> wsl.exe -> bash -lc and `>=` becomes a redirection. uv resolves the
|
||||
# latest of each, which satisfies the studio.txt minimums anyway.
|
||||
$_deps = 'typer fastapi uvicorn matplotlib pandas nest_asyncio pyjwt easydict addict structlog diceware ddgs cryptography httpx fastmcp'
|
||||
$_repair = 'PY=/root/.unsloth/studio/unsloth_studio/bin/python; UV="$(command -v uv 2>/dev/null || echo /root/.local/bin/uv)"; if [ -x "$UV" ] || command -v uv >/dev/null 2>&1; then "$UV" pip install --python "$PY" ' + $_deps + '; else "$PY" -m pip install ' + $_deps + '; fi'
|
||||
$prevEapR = $ErrorActionPreference; $ErrorActionPreference = "Continue"
|
||||
|
|
@ -1614,10 +1591,8 @@ shell.Run cmd, 0, False
|
|||
if ($_serverOk) { substep "Studio web-server deps installed." "Green" }
|
||||
else { substep "(could not auto-install Studio server deps; 'unsloth studio' may fail to start)" "Yellow" }
|
||||
}
|
||||
# GGUF export robustness: the venv is uv-managed and ships no `pip`, but
|
||||
# unsloth-zoo's exporter calls check_pip() and only finds `uv pip` when uv is
|
||||
# on PATH (true for the login-shell launcher, not for every code path).
|
||||
# Seeding pip into the venv makes `save_pretrained_gguf` work regardless.
|
||||
# The uv-managed venv ships no `pip`, but unsloth-zoo's exporter calls check_pip() and only
|
||||
# finds `uv pip` when uv is on PATH. Seed pip so `save_pretrained_gguf` works regardless.
|
||||
$prevEapP = $ErrorActionPreference; $ErrorActionPreference = "Continue"
|
||||
try {
|
||||
& wsl.exe -d $distro --cd /root -u root -- $_studioPy -m pip --version *> $null
|
||||
|
|
@ -1628,9 +1603,8 @@ shell.Run cmd, 0, False
|
|||
}
|
||||
if ($torchOk) {
|
||||
step "done" "Unsloth Studio installed in WSL '$distro' -- GPU ready (torch.cuda available)." "Green"
|
||||
# Native Windows `unsloth` shim: forward every `unsloth ...` into the WSL GPU env so the user
|
||||
# never has to touch WSL. `unsloth studio` runs inside WSL and streams output + URL back here;
|
||||
# WSL2 forwards 127.0.0.1, so http://localhost:8888 works in the Windows browser.
|
||||
# Native Windows `unsloth` shim forwards every `unsloth ...` into the WSL GPU env so the user
|
||||
# never touches WSL. WSL2 forwards 127.0.0.1, so http://localhost:8888 opens in the Windows browser.
|
||||
try {
|
||||
$shimDir = Join-Path $env:LOCALAPPDATA "Unsloth\bin"
|
||||
New-Item -ItemType Directory -Force -Path $shimDir *> $null
|
||||
|
|
@ -1665,10 +1639,8 @@ shell.Run cmd, 0, False
|
|||
)
|
||||
Set-Content -LiteralPath $launcher -Value $L -Encoding UTF8
|
||||
$icon = Join-Path $appDir "unsloth.ico"
|
||||
# Prefer the icon bundled in the local clone (instant + reliable); fall back to a
|
||||
# best-effort GitHub download only when no bundle is present. Then validate the ICO
|
||||
# header (00 00 01 00) before attaching it: a partial/empty/HTML-404 download must
|
||||
# never leave the shortcut pointing at a non-icon (which renders blank).
|
||||
# Prefer the bundled icon; fall back to a GitHub download. Validate the ICO header
|
||||
# (00 00 01 00) before attaching, so a partial/HTML-404 download never makes a blank icon.
|
||||
$bundledIcon = $null
|
||||
if ($PSScriptRoot -and $PSScriptRoot.Trim()) { $bundledIcon = Join-Path $PSScriptRoot "studio\frontend\public\unsloth.ico" }
|
||||
if ($bundledIcon -and (Test-Path -LiteralPath $bundledIcon)) {
|
||||
|
|
@ -1698,47 +1670,36 @@ shell.Run cmd, 0, False
|
|||
$sc.Save()
|
||||
}
|
||||
step "shortcuts" "created Desktop + Start Menu shortcuts (launch WSL Studio + open browser)" "Green"
|
||||
# Make the brand-new .lnk icons render immediately instead of blank. Explorer caches
|
||||
# per-.lnk icons, so a freshly-created shortcut often shows blank until the shell is told
|
||||
# to re-read it. ie4uinit -show alone is unreliable; also broadcast SHChangeNotify so
|
||||
# Explorer refreshes the icons without needing a restart or re-login.
|
||||
# Force the new .lnk icons to render now instead of blank: Explorer caches per-.lnk
|
||||
# icons. ie4uinit -show alone is unreliable, so also broadcast SHChangeNotify below.
|
||||
try { & "$env:SystemRoot\System32\ie4uinit.exe" -show 2>$null } catch {}
|
||||
try {
|
||||
if (-not ("UnslothShell.Notify" -as [type])) {
|
||||
Add-Type -Namespace UnslothShell -Name Notify -MemberDefinition '[System.Runtime.InteropServices.DllImport("shell32.dll", CharSet = System.Runtime.InteropServices.CharSet.Unicode)] public static extern void SHChangeNotify(int eventId, uint flags, string item1, System.IntPtr item2);'
|
||||
}
|
||||
# Per-.lnk SHCNE_UPDATEITEM (0x00002000) + SHCNF_PATHW (0x0005): force Explorer to
|
||||
# re-read each shortcut's icon NOW, clearing any stale "blank" entry cached for that
|
||||
# exact path (the global notify alone often does not refresh an existing .lnk).
|
||||
# Per-.lnk SHCNE_UPDATEITEM (0x00002000), SHCNF_PATHW (0x0005): force Explorer to
|
||||
# re-read each shortcut's icon now (the global notify alone often misses existing .lnks).
|
||||
foreach ($lnk in $lnks) { try { [UnslothShell.Notify]::SHChangeNotify(0x00002000, 0x0005, $lnk, [System.IntPtr]::Zero) } catch {} }
|
||||
# SHCNE_ASSOCCHANGED (0x08000000) with SHCNF_IDLIST (0) -> flush global icon
|
||||
# associations. Both item args are unused for this event, so pass NULL/IDLIST.
|
||||
# SHCNE_ASSOCCHANGED (0x08000000), SHCNF_IDLIST (0): flush global icon associations
|
||||
# (item args unused for this event).
|
||||
[UnslothShell.Notify]::SHChangeNotify(0x08000000, 0, $null, [System.IntPtr]::Zero)
|
||||
} catch {}
|
||||
} catch {
|
||||
substep "(could not create shortcuts: $($_.Exception.Message))" "Yellow"
|
||||
}
|
||||
# GGUF *inference* needs a CUDA-linked llama-server. There is no published
|
||||
# aarch64+CUDA llama.cpp prebuilt (NVIDIA DGX Spark / N1X), so build one into
|
||||
# ~/.unsloth/llama.cpp (Studio's resolver path) IN THE BACKGROUND: the user gets
|
||||
# Studio + training immediately, and GGUF inference lights up a few minutes later
|
||||
# with zero manual steps. Best-effort; opt out with UNSLOTH_NO_LLAMA_CUDA=1.
|
||||
# GGUF *inference* needs a CUDA-linked llama-server and no aarch64+CUDA prebuilt exists, so
|
||||
# build one into ~/.unsloth/llama.cpp in the BACKGROUND: Studio + training are usable now and
|
||||
# GGUF inference lights up minutes later. Best-effort; opt out with UNSLOTH_NO_LLAMA_CUDA=1.
|
||||
if ($env:UNSLOTH_NO_LLAMA_CUDA -ne '1') {
|
||||
$prevEapL = $ErrorActionPreference; $ErrorActionPreference = "Continue"
|
||||
try {
|
||||
$_llamaUrl = "https://raw.githubusercontent.com/unslothai/unsloth/$(Get-UnslothInstallRef)/studio/scripts/provision_llama_cuda.sh"
|
||||
# Propagate UNSLOTH_LLAMA_BUILD_JOBS into the WSL build (Windows env
|
||||
# vars do not cross into WSL by default), so thermally/power-limited
|
||||
# laptops can cap the CUDA build's parallelism (`env` with no
|
||||
# assignment is a harmless passthrough when the var is unset).
|
||||
# Step 1: fetch the provision script + write a small runner (quick session).
|
||||
# The runner is built here and shipped as base64 (dodges every quoting layer).
|
||||
# It (a) restores a sane PATH so a NON-login shell still finds nvidia-smi
|
||||
# (/usr/lib/wsl/lib) and apt (/usr/bin) -- otherwise provision would early-exit
|
||||
# "no nvidia-smi"; (b) caps build jobs; (c) runs provision with logging. Using a
|
||||
# runner FILE lets the detached launcher below pass ONLY space-free args, avoiding
|
||||
# Start-Process arg-quoting (a space-containing `bash -lc <str>` gets mis-split and
|
||||
# silently runs just `env`).
|
||||
# Step 1: fetch the provision script + write a small runner, shipped as base64 to
|
||||
# dodge quoting layers. The runner (a) restores PATH so a non-login shell finds
|
||||
# nvidia-smi (/usr/lib/wsl/lib) and apt -- else provision early-exits "no nvidia-smi";
|
||||
# (b) caps build jobs from UNSLOTH_LLAMA_BUILD_JOBS (Windows env vars don't cross into
|
||||
# WSL); (c) runs provision with logging. A runner FILE lets the detached launcher below
|
||||
# pass only space-free args, avoiding Start-Process mis-splitting `bash -lc <str>`.
|
||||
$_pathLine = 'export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/lib/wsl/lib:$PATH"' + "`n"
|
||||
$_jobsLine = if ($env:UNSLOTH_LLAMA_BUILD_JOBS) { "export UNSLOTH_LLAMA_BUILD_JOBS=$($env:UNSLOTH_LLAMA_BUILD_JOBS)`n" } else { "" }
|
||||
$_runner = "#!/usr/bin/env bash`n" + $_pathLine + $_jobsLine + "exec bash /root/.unsloth/provision_llama_cuda.sh > /root/.unsloth/llama_cuda_build.log 2>&1`n"
|
||||
|
|
@ -1746,12 +1707,10 @@ shell.Run cmd, 0, False
|
|||
$_fetchCmd = 'mkdir -p /root/.unsloth; if curl -fsSL "' + $_llamaUrl + '" -o /root/.unsloth/provision_llama_cuda.sh && [ -s /root/.unsloth/provision_llama_cuda.sh ]; then chmod +x /root/.unsloth/provision_llama_cuda.sh; echo ' + $_runnerB64 + ' | base64 -d > /root/.unsloth/run_llama_build.sh; chmod +x /root/.unsloth/run_llama_build.sh; echo PROV_FETCHED; else echo PROV_NOSCRIPT; fi'
|
||||
$_fetchOut = & wsl.exe -d $distro --cd /root -u root -- bash -lc $_fetchCmd 2>$null
|
||||
if ("$_fetchOut" -match 'PROV_FETCHED') {
|
||||
# Step 2: run the build anchored to a DETACHED WINDOWS process. A WSL-side
|
||||
# `nohup setsid ... &` does NOT survive: WSL shuts the distro's VM down once
|
||||
# the launching wsl.exe session exits, killing any backgrounded build
|
||||
# (observed: no log, only a CPU server left behind). A persistent Windows-side
|
||||
# wsl.exe (Start-Process, no -Wait) holds the VM up for the whole build while
|
||||
# install.ps1 returns immediately. All ArgumentList tokens are space-free.
|
||||
# Step 2: anchor the build to a detached Windows process. A WSL-side `nohup &`
|
||||
# doesn't survive -- WSL stops the VM when the launching session exits, killing
|
||||
# the build. A persistent Windows-side wsl.exe (Start-Process, no -Wait) keeps the
|
||||
# VM up for the whole build while install.ps1 returns. All tokens are space-free.
|
||||
Start-Process -WindowStyle Hidden -FilePath 'wsl.exe' -ArgumentList @('-d', $distro, '--cd', '/root', '-u', 'root', '--', 'bash', '/root/.unsloth/run_llama_build.sh') | Out-Null
|
||||
step "llama.cpp" "building CUDA llama.cpp for GGUF inference in the background (a few min); log: ~/.unsloth/llama_cuda_build.log" "Green"
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -337,9 +337,8 @@ function Uninstall-UnslothStudio {
|
|||
} catch { }
|
||||
|
||||
# ── Windows-on-Arm WSL-fallback artifacts ──
|
||||
# The ARM64+NVIDIA fallback installs Studio INSIDE WSL and drops a native shim + launcher under
|
||||
# %LOCALAPPDATA%\Unsloth (note: "Unsloth", not "Unsloth Studio") with a PATH entry, while the real
|
||||
# install lives in the WSL distro(s). The native cleanup above misses all of that -- handle it here.
|
||||
# The ARM64+NVIDIA fallback puts Studio inside WSL plus a native shim + launcher under
|
||||
# %LOCALAPPDATA%\Unsloth (not "Unsloth Studio") with a PATH entry -- all missed by the cleanup above.
|
||||
_Step "Removing WSL-fallback artifacts (shim, launcher, PATH entry, WSL install)..."
|
||||
$unslothDir = if ($env:LOCALAPPDATA) { Join-Path $env:LOCALAPPDATA "Unsloth" } else { $null }
|
||||
if ($unslothDir) {
|
||||
|
|
@ -366,26 +365,13 @@ function Uninstall-UnslothStudio {
|
|||
# Remove the Studio install inside each WSL distro (the real GPU install + any CUDA llama.cpp build).
|
||||
if (Get-Command wsl.exe -ErrorAction SilentlyContinue) {
|
||||
try {
|
||||
# `wsl --list` emits UTF-16 that PowerShell frequently mis-parses (yielding an
|
||||
# EMPTY list -> the cleanup silently skipped, leaving the WSL install behind).
|
||||
# So probe a candidate set by exit code instead ('' = the default distro),
|
||||
# which is encoding-proof. In the cleanup, rm runs FIRST: `pkill -f "<pattern>"`
|
||||
# matches this very bash -lc (its argv contains the pattern) and would SIGKILL
|
||||
# the shell before a trailing rm -- so remove files first (guaranteed), then
|
||||
# best-effort kill via fuser by port (does not self-match) + pkill.
|
||||
# Also remove the `unsloth` launcher symlink install.sh drops at
|
||||
# ~/.local/bin/unsloth -> <venv>/bin/unsloth. rm -rf of ~/.unsloth
|
||||
# above deletes its target but leaves the symlink dangling, so the
|
||||
# `unsloth` command still resolves on PATH after an uninstall.
|
||||
# The pkill patterns use the [x]-regex self-exclusion trick: this very
|
||||
# `bash -lc <cmd>` shell's own argv contains the literal pattern text, so a
|
||||
# plain `pkill -f unsloth_studio` would match (and SIGKILL) the shell itself
|
||||
# before the next command runs -- which is why rm goes first AND why the second
|
||||
# pkill (llama-server, a dynamic port not covered by `fuser -k 8888`) never
|
||||
# fired. Writing the pattern as '[u]nsloth_studio' means the shell's argv holds
|
||||
# "[u]nsloth_studio" (no literal "unsloth_studio" substring) so it no longer
|
||||
# self-matches, while real target processes (cmdline contains "unsloth_studio")
|
||||
# still match. Same for '[l]lama-server'.
|
||||
# `wsl --list` emits UTF-16 PowerShell mis-parses (empty list -> cleanup skipped), so probe a
|
||||
# candidate set by exit code instead ('' = default distro), which is encoding-proof.
|
||||
# rm runs FIRST (guaranteed) since the kills could SIGKILL this shell. Also rm the dangling
|
||||
# ~/.local/bin/unsloth symlink (its target under ~/.unsloth is gone but the link still resolves
|
||||
# on PATH). pkill patterns use the [x]-regex self-exclusion trick: '[u]nsloth_studio' keeps the
|
||||
# shell's own argv from matching (no literal "unsloth_studio" substring) while real processes
|
||||
# still match. Same for '[l]lama-server' (a dynamic port not covered by fuser -k 8888).
|
||||
$_clean = 'rm -rf /root/.unsloth /home/*/.unsloth /root/llama-cuda /root/provision_llama_cuda.sh /root/llama_cuda_build.log 2>/dev/null; rm -f /root/.local/bin/unsloth /home/*/.local/bin/unsloth 2>/dev/null; fuser -k 8888/tcp 2>/dev/null; pkill -9 -f ''[u]nsloth_studio'' 2>/dev/null; pkill -9 -f ''[l]lama-server'' 2>/dev/null; true'
|
||||
$_cands = @('', 'Ubuntu', 'Ubuntu-24.04', 'Ubuntu-22.04', 'Debian')
|
||||
if ($env:UNSLOTH_WSL_DISTRO) { $_cands = @($env:UNSLOTH_WSL_DISTRO) + $_cands }
|
||||
|
|
@ -415,13 +401,9 @@ function Uninstall-UnslothStudio {
|
|||
Write-Host " `$env:UNSLOTH_STUDIO_HOME = 'C:\your\path'; irm https://raw.githubusercontent.com/unslothai/unsloth/main/scripts/uninstall.ps1 | iex"
|
||||
}
|
||||
|
||||
# A successful uninstall must report success. The WSL distro-probe loop above
|
||||
# leaves $LASTEXITCODE set by the last `wsl -d <name> -- true` probe, and the
|
||||
# candidate list intentionally includes distros that may not exist (their
|
||||
# probes fail by design) -- so without this reset `& .\uninstall.ps1` would
|
||||
# exit non-zero (255) even though every cleanup step succeeded. Set the var
|
||||
# rather than calling `exit 0` so the `irm ... | iex` usage does not terminate
|
||||
# the caller's shell.
|
||||
# The distro-probe loop leaves $LASTEXITCODE from its last probe, which fails by design for
|
||||
# absent distros -- reset it so a successful uninstall exits 0. Set the var rather than `exit 0`
|
||||
# so `irm ... | iex` doesn't terminate the caller's shell.
|
||||
$global:LASTEXITCODE = 0
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -209,10 +209,8 @@ _custom_studio_roots | while IFS= read -r _custom_root; do
|
|||
_remove_path "$_custom_root"
|
||||
done
|
||||
_remove_path "$HOME/.unsloth/studio"
|
||||
# CUDA llama.cpp built by provision_llama_cuda.sh on native-Linux Spark/aarch64
|
||||
# (and the fetched provision script). On WSL ~/.unsloth/llama.cpp is a symlink to
|
||||
# the real build, which install.ps1's uninstall removes; here rm -rf clears the
|
||||
# native-Linux build dir / the symlink.
|
||||
# CUDA llama.cpp from provision_llama_cuda.sh (+ the fetched script). Clears the
|
||||
# native-Linux build dir, or on WSL the symlink to the build install.ps1 removes.
|
||||
_remove_path "$HOME/.unsloth/llama.cpp"
|
||||
_remove_path "$HOME/.unsloth/provision_llama_cuda.sh"
|
||||
_remove_path "$HOME/.local/share/unsloth"
|
||||
|
|
|
|||
101
studio/setup.sh
101
studio/setup.sh
|
|
@ -756,11 +756,10 @@ LLAMA_CPP_DIR="$UNSLOTH_HOME/llama.cpp"
|
|||
LLAMA_SERVER_BIN="$LLAMA_CPP_DIR/build/bin/llama-server"
|
||||
_NEED_LLAMA_SOURCE_BUILD=false
|
||||
_LLAMA_CPP_DEGRADED=false
|
||||
# Distinct from _LLAMA_CPP_DEGRADED: on WSL2 aarch64+NVIDIA with no nvcc yet, the
|
||||
# CPU source build is skipped because install.ps1 builds the real CUDA server in
|
||||
# the BACKGROUND. There is temporarily no llama-server, but that is a SUCCESS
|
||||
# (CUDA build in progress), NOT a degraded/failed install -- so it must not trip
|
||||
# the arm64 CPU-prebuilt last-resort or the install-failure exit 1.
|
||||
# Distinct from _LLAMA_CPP_DEGRADED: on WSL2 aarch64+NVIDIA with no nvcc, the CPU
|
||||
# build is skipped because install.ps1 builds the real CUDA server in the background.
|
||||
# A temporarily-absent server here is success, not failure, so it must not trip the
|
||||
# arm64 CPU-prebuilt last-resort or the exit 1.
|
||||
_LLAMA_CPP_DEFERRED=false
|
||||
_LLAMA_FORCE_COMPILE="${UNSLOTH_LLAMA_FORCE_COMPILE:-0}"
|
||||
_REQUESTED_LLAMA_TAG="${UNSLOTH_LLAMA_TAG:-${_DEFAULT_LLAMA_TAG}}"
|
||||
|
|
@ -934,26 +933,12 @@ if [ "$_NEED_LLAMA_SOURCE_BUILD" = true ] && \
|
|||
fi
|
||||
|
||||
# ── WSL2 aarch64 + NVIDIA, no nvcc yet: defer to the background CUDA build ──
|
||||
# On Windows-on-ARM + NVIDIA (DGX Spark / N1X "RTX Spark"), install.ps1 routes
|
||||
# through WSL2 and, after this install finishes, launches provision_llama_cuda.sh
|
||||
# in the BACKGROUND (installs CUDA 13.3 + gcc-14, builds the real sm_121 CUDA
|
||||
# llama-server into ~/.unsloth/llama.cpp, replacing whatever is here). On a fresh
|
||||
# WSL distro there is no CUDA toolkit (nvcc) yet, so the section-9 source build
|
||||
# below can only produce a CPU-only server ("building (CPU, CUDA driver found but
|
||||
# nvcc missing)") -- which is SLOW and immediately thrown away by that background
|
||||
# CUDA build. So skip the source build entirely on this exact path: the
|
||||
# background CUDA provision is the sole builder, and the CPU build is pure waste.
|
||||
#
|
||||
# Strictly gated. ALL must hold:
|
||||
# - running under WSL (grep microsoft /proc/version)
|
||||
# - aarch64/arm64 ($_HOST_MACHINE)
|
||||
# - an NVIDIA GPU is present (nvidia-smi lists a GPU)
|
||||
# - nvcc is MISSING (no nvcc on PATH, none under /usr/local/cuda*)
|
||||
# - the CUDA provision is NOT opted out (UNSLOTH_NO_LLAMA_CUDA != 1)
|
||||
# - user did not force a compile / pin a PR (_LLAMA_FORCE_COMPILE != 1, no _LLAMA_PR)
|
||||
# If nvcc IS already present we fall through to section 9 and build CUDA directly.
|
||||
# If UNSLOTH_NO_LLAMA_CUDA=1 the background build never runs, so we KEEP the CPU
|
||||
# source build as the user's only llama-server (do not defer).
|
||||
# On Windows-on-ARM + NVIDIA, install.ps1 builds the real CUDA llama-server in the
|
||||
# background after this install. Without nvcc yet the section-9 build can only make a
|
||||
# slow CPU server that the background build throws away, so skip it on this exact path.
|
||||
# Gated: WSL + aarch64/arm64 + NVIDIA GPU + nvcc missing + CUDA not opted out
|
||||
# (UNSLOTH_NO_LLAMA_CUDA!=1) + no forced compile / PR pin. If nvcc is present we fall
|
||||
# through to section 9; if opted out we keep the CPU build as the only server.
|
||||
if [ "$_NEED_LLAMA_SOURCE_BUILD" = true ] \
|
||||
&& [ "$_LLAMA_FORCE_COMPILE" != "1" ] \
|
||||
&& [ -z "$_LLAMA_PR" ] \
|
||||
|
|
@ -967,9 +952,8 @@ if [ "$_NEED_LLAMA_SOURCE_BUILD" = true ] \
|
|||
step "llama.cpp" "GGUF engine: CUDA build running in background (WSL aarch64 + NVIDIA)" "$C_WARN"
|
||||
substep "skipping slow CPU build; the background CUDA llama.cpp will provide the server"
|
||||
substep "(opt out / keep CPU build with UNSLOTH_NO_LLAMA_CUDA=1)"
|
||||
# Sole builder is install.ps1's background provision_llama_cuda.sh. Do NOT set
|
||||
# _LLAMA_CPP_DEGRADED (that would trigger the arm64 CPU-prebuilt last resort
|
||||
# and the install-failure exit 1); use the distinct DEFERRED state instead.
|
||||
# Use DEFERRED, not DEGRADED: DEGRADED would trigger the CPU-prebuilt last
|
||||
# resort + exit 1, but install.ps1's background build is the intended builder.
|
||||
_NEED_LLAMA_SOURCE_BUILD=false
|
||||
_LLAMA_CPP_DEFERRED=true
|
||||
fi
|
||||
|
|
@ -1211,13 +1195,10 @@ else
|
|||
else
|
||||
CMAKE_ARGS="$CMAKE_ARGS -DGGML_CUDA=ON"
|
||||
|
||||
# glibc >= 2.41 added rsqrt()/rsqrtf() (gated by __GLIBC_USE(IEC_60559_FUNCS_EXT_C23),
|
||||
# which g++ enables via _GNU_SOURCE). CUDA Toolkits < 13.3 declare these in
|
||||
# <crt/math_functions.h> without a matching exception specifier -> every .cu fails
|
||||
# "exception specification is incompatible", and the GPU build silently drops to CPU.
|
||||
# -allow-unsupported-compiler does NOT fix this (header clash, not the GNU-version
|
||||
# #error); no host gcc avoids it. NVIDIA fixed it in CUDA 13.3 (_NV_RSQRT_SPECIFIER).
|
||||
# Diagnostic only: never changes flags / never aborts -> cannot regress any platform.
|
||||
# glibc >= 2.41 vs CUDA < 13.3: rsqrt/rsqrtf header clash makes every .cu
|
||||
# fail "exception specification is incompatible" and the GPU build drops to
|
||||
# CPU. No workaround but CUDA >= 13.3. Diagnostic only: never changes flags
|
||||
# or aborts, so it cannot regress any platform.
|
||||
_GLIBC_VER="$(getconf GNU_LIBC_VERSION 2>/dev/null | awk '{print $2}')" || _GLIBC_VER=""
|
||||
if [ -n "$_GLIBC_VER" ]; then
|
||||
_GLIBC_MAJ="${_GLIBC_VER%%.*}"; _GLIBC_MIN="${_GLIBC_VER#*.}"; _GLIBC_MIN="${_GLIBC_MIN%%.*}"
|
||||
|
|
@ -1442,26 +1423,19 @@ fi # end _SKIP_GGUF_BUILD check
|
|||
|
||||
# ── aarch64 + NVIDIA (DGX Spark / GB10 / N1X "RTX Spark"): provision a CUDA
|
||||
# llama.cpp when the source build above could not (no CUDA toolkit found) ──
|
||||
# There is no published aarch64+CUDA llama.cpp prebuilt, so these hosts always
|
||||
# source-build for the GPU above. But that build only emits a CUDA llama-server
|
||||
# when a CUDA toolkit (nvcc) is already present; on a fresh Spark that ships only
|
||||
# the driver + nvidia-smi, the build silently falls back to CPU. The Windows path
|
||||
# closes this exact gap from its WSL2 fallback by invoking provision_llama_cuda.sh
|
||||
# (installs CUDA 13.3 + gcc-14, then builds a CUDA-linked server). Mirror that here
|
||||
# so native-Linux Spark users get the same GGUF *inference* robustness, shared by
|
||||
# every Linux install instead of bolted onto the Windows installer.
|
||||
# No aarch64+CUDA prebuilt exists, and the source build above only emits a CUDA
|
||||
# server when nvcc is already present (a fresh Spark ships only driver + nvidia-smi,
|
||||
# so it falls back to CPU). The Windows/WSL path closes this gap via
|
||||
# provision_llama_cuda.sh; mirror it here so native-Linux Spark gets the same.
|
||||
#
|
||||
# Strictly gated + additive: only fires on Linux aarch64/arm64 WITH an NVIDIA GPU
|
||||
# AND when we do NOT already have a CUDA-linked llama-server. x86_64 (CUDA prebuilt
|
||||
# or its own source build), ROCm, macOS/Metal, CPU-only ARM, and any ARM host that
|
||||
# already built a CUDA server are byte-for-byte unaffected. Opt out with
|
||||
# UNSLOTH_NO_LLAMA_CUDA=1. Best-effort: never aborts setup (provision script always
|
||||
# exits 0; failures leave the prior CPU/degraded state for the fallback below).
|
||||
# CUDA-capable in either build layout: old monolithic (libggml-cuda is a direct
|
||||
# ldd dependency) or current split build (CUDA is a dlopen-ed backend, libggml-cuda.so*,
|
||||
# beside the binary -- ldd will NOT list it). Checking only ldd is a false negative on
|
||||
# current llama.cpp and would force a needless rebuild; a CPU-only build has no
|
||||
# libggml-cuda.so at all, so its presence beside the binary is the reliable signal.
|
||||
# Gated + additive: only on Linux aarch64/arm64 + NVIDIA GPU with no CUDA server
|
||||
# yet (opt out via UNSLOTH_NO_LLAMA_CUDA=1). x86_64, ROCm, Metal, CPU-only ARM, and
|
||||
# ARM hosts that already built CUDA are unaffected. Best-effort: provision always
|
||||
# exits 0; on failure the prior CPU/degraded state stands for the fallback below.
|
||||
# CUDA-capable in two layouts: old monolithic (libggml-cuda is a direct ldd dep) or
|
||||
# split build (dlopen-ed backend libggml-cuda.so* beside the binary, not in ldd). ldd
|
||||
# alone false-negatives; a CPU-only build has no libggml-cuda.so, so its presence is
|
||||
# the reliable signal.
|
||||
_have_cuda_llama_server() {
|
||||
[ -x "$LLAMA_SERVER_BIN" ] || return 1
|
||||
ldd "$LLAMA_SERVER_BIN" 2>/dev/null | grep -qi 'libggml-cuda' && return 0
|
||||
|
|
@ -1475,15 +1449,11 @@ if [ "$_HOST_SYSTEM" = "Linux" ] \
|
|||
&& command -v nvidia-smi >/dev/null 2>&1 \
|
||||
&& nvidia-smi -L 2>/dev/null | awk '/^GPU[[:space:]]+[0-9]+:/{found=1} END{exit !found}' \
|
||||
&& ! _have_cuda_llama_server; then
|
||||
# NOTE: WSL2 is intentionally excluded above (grep microsoft /proc/version) --
|
||||
# under WSL the Windows installer (install.ps1) provisions the CUDA llama.cpp
|
||||
# in the BACKGROUND after setup completes, so doing it here too would (a) run a
|
||||
# heavy build in the FOREGROUND during install and (b) duplicate that work.
|
||||
# This block is for NATIVE Linux (DGX Spark / GB10) only.
|
||||
# Resolve provision_llama_cuda.sh: prefer the copy shipped beside setup.sh
|
||||
# (packaged via studio/scripts/*.sh), then the local-dev repo, else fetch
|
||||
# the pinned raw copy from GitHub (mirrors install.ps1's WSL fetch) so the
|
||||
# normal `curl | sh` install works even on an older wheel without the script.
|
||||
# WSL2 is excluded above: there install.ps1 runs this in the background after
|
||||
# setup, so doing it here would duplicate the work in the foreground. Native
|
||||
# Linux (DGX Spark / GB10) only.
|
||||
# Resolve provision_llama_cuda.sh: copy beside setup.sh, then local-dev repo,
|
||||
# else fetch from GitHub so `curl | sh` works on an older wheel without it.
|
||||
_PROV_SH=""
|
||||
if [ -f "$SCRIPT_DIR/scripts/provision_llama_cuda.sh" ]; then
|
||||
_PROV_SH="$SCRIPT_DIR/scripts/provision_llama_cuda.sh"
|
||||
|
|
@ -1499,9 +1469,8 @@ if [ "$_HOST_SYSTEM" = "Linux" ] \
|
|||
if [ -n "$_PROV_SH" ]; then
|
||||
step "llama.cpp" "aarch64 + NVIDIA: provisioning CUDA toolkit + building CUDA llama.cpp for GGUF inference..." "$C_WARN"
|
||||
substep "(opt out with UNSLOTH_NO_LLAMA_CUDA=1; lower load with UNSLOTH_LLAMA_BUILD_JOBS=N)"
|
||||
# provision_llama_cuda.sh installs the toolkit + gcc-14 and builds into
|
||||
# $LLAMA_CPP_DIR. It always exits 0; honor UNSLOTH_LLAMA_CPP_PATH so a
|
||||
# custom STUDIO_HOME build lands in the same dir setup.sh validates.
|
||||
# Builds into $LLAMA_CPP_DIR (via UNSLOTH_LLAMA_CPP_PATH so a custom
|
||||
# STUDIO_HOME lands where setup.sh validates); always exits 0.
|
||||
UNSLOTH_LLAMA_CPP_PATH="$LLAMA_CPP_DIR" bash "$_PROV_SH" || true
|
||||
if _have_cuda_llama_server; then
|
||||
step "llama.cpp" "CUDA llama-server ready (aarch64 + NVIDIA)"
|
||||
|
|
|
|||
|
|
@ -27,9 +27,8 @@ torch_compile_options = {
|
|||
|
||||
|
||||
def _flex_is_dgx_spark():
|
||||
# Mirror of unsloth.models._utils.is_dgx_spark(), inlined to avoid importing
|
||||
# `unsloth.models` from this low-level `kernels` module (circular at import).
|
||||
# DGX Spark / N1X = aarch64 + NVIDIA CUDA + a Spark device-name token.
|
||||
# Inlined copy of _utils.is_dgx_spark() to avoid a circular import.
|
||||
# Spark = aarch64 + NVIDIA CUDA + a Spark device-name token.
|
||||
_force = os.environ.get("UNSLOTH_FORCE_DGX_SPARK")
|
||||
if _force == "1":
|
||||
return True
|
||||
|
|
@ -51,9 +50,8 @@ def _flex_is_dgx_spark():
|
|||
return False
|
||||
|
||||
|
||||
# DGX Spark / N1X has 48 SMs (< inductor's 68-SM is_big_gpu threshold), so
|
||||
# max_autotune_gemm is already skipped; dropping max_autotune only saves the
|
||||
# wasted compile-time search -- identical kernels, no accuracy/throughput change.
|
||||
# Spark's 48 SMs are below inductor's 68-SM is_big_gpu threshold, so max_autotune
|
||||
# is already skipped; disabling it just avoids a wasted compile-time search.
|
||||
if _flex_is_dgx_spark():
|
||||
torch_compile_options["max_autotune"] = False
|
||||
|
||||
|
|
|
|||
|
|
@ -940,12 +940,9 @@ from transformers.modeling_utils import logger as transformers_logger
|
|||
|
||||
|
||||
# ---- NVIDIA DGX Spark (GB10) / N1X "RTX Spark" (Blackwell unified-memory) support ----
|
||||
# These Blackwell unified-memory (UMA) machines report different device names:
|
||||
# "NVIDIA GB10" on DGX Spark, "JMJWOA-Generic-GPU" on the pre-launch N1X laptop.
|
||||
# One shared detector so every Spark-specific workaround uses the same definition.
|
||||
# The aarch64 + CUDA gate makes this a strict no-op on x86_64 NVIDIA, AMD/ROCm,
|
||||
# Intel/XPU, Mac/MLX, and discrete aarch64 GPUs (GH200/GB200) -- those report
|
||||
# non-matching names and/or are not aarch64, so behaviour there is unchanged.
|
||||
# Shared detector for Spark-class UMA machines, which report varying device names
|
||||
# ("NVIDIA GB10" on DGX Spark, "JMJWOA-Generic-GPU" on the N1X laptop). The
|
||||
# aarch64 + CUDA gate keeps every Spark workaround a strict no-op elsewhere.
|
||||
_DGX_SPARK_DEVICE_TOKENS = ("GB10", "JMJWOA", "N1X", "DGX SPARK", "GB110")
|
||||
|
||||
|
||||
|
|
@ -1028,7 +1025,7 @@ def patch_dgx_spark_memory_config():
|
|||
return
|
||||
conf = os.environ.get("PYTORCH_CUDA_ALLOC_CONF", "")
|
||||
if "expandable_segments" in conf:
|
||||
return # user already configured it -- do not override
|
||||
return # respect user's setting
|
||||
os.environ["PYTORCH_CUDA_ALLOC_CONF"] = (
|
||||
conf + "," if conf else ""
|
||||
) + "expandable_segments:True"
|
||||
|
|
@ -1686,12 +1683,8 @@ torch_compile_options = {
|
|||
"trace.enabled": UNSLOTH_COMPILE_DEBUG,
|
||||
"triton.cudagraphs": False,
|
||||
}
|
||||
# DGX Spark / N1X: this GPU has 48 SMs, below inductor's hardcoded 68-SM
|
||||
# `is_big_gpu` threshold, so `max_autotune_gemm` is already skipped by inductor
|
||||
# (the "Not enough SMs to use max_autotune_gemm mode" warning). Dropping
|
||||
# max_autotune on Spark only avoids the wasted compile-time autotuning search --
|
||||
# the produced Triton/inductor kernels are identical, so steady-state throughput
|
||||
# and accuracy are unchanged. Strict no-op off-Spark (gated by is_dgx_spark()).
|
||||
# Spark's 48 SMs are below inductor's 68-SM is_big_gpu threshold, so max_autotune
|
||||
# is already skipped; disabling it just avoids a wasted compile-time search.
|
||||
if is_dgx_spark():
|
||||
torch_compile_options["max_autotune"] = False
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue