install: four round-seven review fixes across installer and uninstall
Seventh review round; each item reproduced against the live tree first. The aarch64 bitsandbytes step gated on a bare nvidia-smi, which root login shells cannot see under WSL2 GPU-PV (the binary lives only in /usr/lib/wsl/lib, dropped from PATH by the /etc/profile reset), so Spark and N1X WSL installs finished with CUDA torch but no 4-bit QLoRA. The gate now resolves nvidia-smi explicitly with the same PATH, /usr/lib/wsl/lib, /usr/bin order as setup.sh's resolver. uninstall.sh's CUDA-build kill matched patterns against argv, but the provisioner cds into the tree before `cmake --build build`, so cmake and make children carry relative argv no pattern can match; killing only the wrapper orphaned them mid-build. Each match's whole process group is now signalled (TERM then KILL), with a plain PID kill as fallback when the pgid is unreadable or shared with init. Verified in a sandbox: a child with unmatchable argv in the wrapper's group dies with it. The WSL shim dir was appended to user PATH while the native installer prepends its own %USERPROFILE%\.unsloth\studio\bin, whose unsloth.exe outlives the venv the fallback rolls aside, so on a native-to-WSL rerun a new terminal resolved unsloth to the dead native launcher. The shim is now prepended via Add-ToUserPath (which de-dupes and hoists), and the dead default-root native shim is removed when the venv binary it targets is gone; custom-root shims are left alone since the prepend outranks them. UNSLOTH_NPM_REGISTRY was not forwarded into the inner WSL shell even though setup.sh threads it into every npm/bun install, so mirror-required networks failed the frontend step (and with it the install) while the outer installer honored the mirror. It is now forwarded with the same strict http(s) allow-list and single-quoting as UNSLOTH_PYTORCH_MIRROR. Verified: bash -n on both shell scripts, PowerShell AST parse on install.ps1, the group-kill sandbox above, resolver smoke tests for the bitsandbytes gate, and the sh test battery matches the branch baseline.
This commit is contained in:
parent
6ea6c621c0
commit
9ca396b665
3 changed files with 52 additions and 16 deletions
32
install.ps1
32
install.ps1
|
|
@ -2223,6 +2223,13 @@ exit 0
|
|||
if ($env:UNSLOTH_PYTORCH_MIRROR -and ($env:UNSLOTH_PYTORCH_MIRROR -match '^https?://[A-Za-z0-9._~:/?#@%+=&-]+$')) {
|
||||
$_fwdEnv += "export UNSLOTH_PYTORCH_MIRROR='$($env:UNSLOTH_PYTORCH_MIRROR)'; "
|
||||
}
|
||||
# Forward the npm mirror the same way: setup.sh threads UNSLOTH_NPM_REGISTRY
|
||||
# into every npm/bun install, and on mirror-required networks the WSL
|
||||
# frontend/OXC steps would otherwise hit registry.npmjs.org and fail the
|
||||
# install. Same strict http(s) allow-list + single-quote as above.
|
||||
if ($env:UNSLOTH_NPM_REGISTRY -and ($env:UNSLOTH_NPM_REGISTRY -match '^https?://[A-Za-z0-9._~:/?#@%+=&-]+$')) {
|
||||
$_fwdEnv += "export UNSLOTH_NPM_REGISTRY='$($env:UNSLOTH_NPM_REGISTRY)'; "
|
||||
}
|
||||
# Forward an explicit UNSLOTH_PYTHON pin: Windows env vars do not cross into
|
||||
# WSL, so without this the inner install.sh silently built the venv on its
|
||||
# default Python while the installer reported success. Strict version shape
|
||||
|
|
@ -2379,14 +2386,23 @@ exit 0
|
|||
# Record the distro so the uninstaller can clean a custom UNSLOTH_WSL_DISTRO install
|
||||
# without the env var set.
|
||||
try { Set-Content -LiteralPath (Join-Path (Split-Path $shimDir -Parent) "wsl-distro.txt") -Value $distro -Encoding ASCII } catch {}
|
||||
# A fresh profile may have no HKCU 'Path'; null would make TrimEnd() throw.
|
||||
$userPath = [Environment]::GetEnvironmentVariable("Path", "User")
|
||||
if (-not $userPath) { $userPath = "" }
|
||||
if (($userPath -split ';') -notcontains $shimDir) {
|
||||
$newUserPath = if ($userPath.Trim()) { $userPath.TrimEnd(';') + ";" + $shimDir } else { $shimDir }
|
||||
[Environment]::SetEnvironmentVariable("Path", $newUserPath, "User")
|
||||
}
|
||||
$env:Path = $env:Path.TrimEnd(';') + ";" + $shimDir
|
||||
# PREPEND (not append): a previous NATIVE install prepended
|
||||
# %USERPROFILE%\.unsloth\studio\bin (unsloth.exe) to user PATH,
|
||||
# and that exe outlives the venv this fallback just rolled aside
|
||||
# -- an appended shim would lose to the dead native launcher in
|
||||
# every new terminal. Add-ToUserPath de-dupes and hoists.
|
||||
$null = Add-ToUserPath -Directory $shimDir -Position 'Prepend'
|
||||
$env:Path = $shimDir + ";" + $env:Path.TrimStart(';')
|
||||
# Drop the dead default-root native shim outright when the venv
|
||||
# binary it launches is gone (custom-root shims are left alone;
|
||||
# the PATH prepend above already outranks them).
|
||||
try {
|
||||
$staleNativeShim = Join-Path $env:USERPROFILE ".unsloth\studio\bin\unsloth.exe"
|
||||
$staleNativeTarget = Join-Path $env:USERPROFILE ".unsloth\studio\unsloth_studio\Scripts\unsloth.exe"
|
||||
if ((Test-Path -LiteralPath $staleNativeShim) -and -not (Test-Path -LiteralPath $staleNativeTarget)) {
|
||||
Remove-Item -LiteralPath $staleNativeShim -Force -ErrorAction Stop
|
||||
}
|
||||
} catch {}
|
||||
step "shim" "created native 'unsloth' command -> forwards to WSL '$distro'" "Green"
|
||||
substep "open a NEW terminal, then (no WSL knowledge needed):" "Cyan"
|
||||
substep " unsloth studio # runs in WSL; opens http://localhost:8888" "Cyan"
|
||||
|
|
|
|||
10
install.sh
10
install.sh
|
|
@ -2979,10 +2979,16 @@ elif [ -n "$TORCH_INDEX_URL" ]; then
|
|||
# extras break 4-bit QLoRA, but aarch64 manylinux wheels work (verified on
|
||||
# sm_121 via PTX JIT). Best-effort: no wheel keeps 16-bit LoRA / full finetuning.
|
||||
# SKIP_TORCH gate stops a --no-torch (GGUF-only) install dragging torch back in.
|
||||
# nvidia-smi may live only in /usr/lib/wsl/lib (WSL2 GPU-PV), which root login
|
||||
# shells drop from PATH -- resolve explicitly (same order as setup.sh's
|
||||
# _resolve_nvsmi) so the WoA/WSL install still gets 4-bit QLoRA support.
|
||||
_bnb_nvsmi="$(command -v nvidia-smi 2>/dev/null || true)"
|
||||
[ -z "$_bnb_nvsmi" ] && [ -x /usr/lib/wsl/lib/nvidia-smi ] && _bnb_nvsmi=/usr/lib/wsl/lib/nvidia-smi
|
||||
[ -z "$_bnb_nvsmi" ] && [ -x /usr/bin/nvidia-smi ] && _bnb_nvsmi=/usr/bin/nvidia-smi
|
||||
if [ "$SKIP_TORCH" = false ] \
|
||||
&& { [ "$(uname -m)" = "aarch64" ] || [ "$(uname -m)" = "arm64" ]; } \
|
||||
&& command -v nvidia-smi >/dev/null 2>&1 \
|
||||
&& nvidia-smi -L 2>/dev/null | awk '/^GPU[[:space:]]+[0-9]+:/{found=1} END{exit !found}' \
|
||||
&& [ -n "$_bnb_nvsmi" ] \
|
||||
&& "$_bnb_nvsmi" -L 2>/dev/null | awk '/^GPU[[:space:]]+[0-9]+:/{found=1} END{exit !found}' \
|
||||
&& ! "$_VENV_PY" -c "import bitsandbytes" >/dev/null 2>&1; then
|
||||
substep "installing bitsandbytes (aarch64 wheels; enables 4-bit QLoRA)..."
|
||||
if ! uv pip install --python "$_VENV_PY" "bitsandbytes>=0.45.5,!=0.46.0,!=0.48.0" >/dev/null 2>&1; then
|
||||
|
|
|
|||
|
|
@ -219,13 +219,27 @@ _remove_path "$HOME/.unsloth/studio"
|
|||
# _pkill_studio uses.
|
||||
if command -v pkill >/dev/null 2>&1; then
|
||||
_llama_re=$(_pkill_escape "$HOME/.unsloth/llama.cpp")
|
||||
for _pat in "run_llama_build\.sh" "provision_llama_cuda\.sh" "$_llama_re"; do
|
||||
pkill -TERM -f "$_pat" 2>/dev/null || true
|
||||
done
|
||||
# Signal the whole process GROUP of each match, not just the matching PID:
|
||||
# the provisioner cds into the tree before `cmake --build build`, so cmake/
|
||||
# make children carry relative argv that no pattern can match, and killing
|
||||
# only the wrapper orphans them mid-build. Group kill sweeps the tree; PID
|
||||
# kill remains the fallback when pgid is unreadable or shared with init.
|
||||
_kill_llama_build() {
|
||||
_sig="$1"
|
||||
for _pat in "run_llama_build\.sh" "provision_llama_cuda\.sh" "$_llama_re"; do
|
||||
for _pid in $(pgrep -f "$_pat" 2>/dev/null); do
|
||||
_pgid=$(ps -o pgid= -p "$_pid" 2>/dev/null | tr -d '[:space:]')
|
||||
case "$_pgid" in
|
||||
''|0|1) kill -s "$_sig" "$_pid" 2>/dev/null || true ;;
|
||||
*) kill -s "$_sig" -- "-$_pgid" 2>/dev/null \
|
||||
|| kill -s "$_sig" "$_pid" 2>/dev/null || true ;;
|
||||
esac
|
||||
done
|
||||
done
|
||||
}
|
||||
_kill_llama_build TERM
|
||||
sleep 0.5
|
||||
for _pat in "run_llama_build\.sh" "provision_llama_cuda\.sh" "$_llama_re"; do
|
||||
pkill -KILL -f "$_pat" 2>/dev/null || true
|
||||
done
|
||||
_kill_llama_build KILL
|
||||
fi
|
||||
# Default-mode shared llama.cpp build + cache are siblings of studio (not removed
|
||||
# by deleting it). No-op in env/custom mode (they nest under the custom root) and
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue