Title
[WinError 5] Access Denied on Windows ARM64 (Snapdragon X Elite) – install_llama_prebuilt.py fix included
Summary
Installing Unsloth Studio on Windows ARM64 (Snapdragon X Elite) consistently fails
with [WinError 5] Access Denied during the llama.cpp prebuilt activation step.
The source build fallback also fails. A working fix exists — one-time patch to
install_llama_prebuilt.py.
Environment
- OS: Windows 11 ARM64
- Hardware: Qualcomm Snapdragon X Elite (Oryon cores, no NVIDIA GPU)
- RAM: 64 GB unified memory
- Unsloth version: 2026.6.1 (studio v0.1.44-beta)
- llama.cpp build: b9585
- Install command:
.\install.ps1 --no-torch
Error
[llama-prebuilt] activation failed for staged install: [WinError 5] Access is denied:
'C:\Users\<user>\.unsloth\.staging\llama.cpp.staging-XXXXXXXX' -> 'C:\Users\<user>\.unsloth\llama.cpp'
[llama-prebuilt] prebuilt install path failed; falling back to source build
CMake Error at CMakeLists.txt:2 (project):
Failed to run MSBuild command ... Platform='ARM64'
The BaseOutputPath/OutputPath property is not set for 'VCTargetsPath.vcxproj'
[ERROR] unsloth studio setup failed (exit code 1)
Also note in the log:
platform=Windows machine=amd64 <- misdetected, actually ARM64
chosen_asset=llama-b9585-bin-win-cpu-x64.zip
Root Cause
Two issues compound:
1. os.replace() fails on ARM64 Windows due to AV race condition
install_llama_prebuilt.py activates the install via:
os.replace(staging_dir, install_dir)
On Windows ARM64, after ZIP extraction, Windows Defender immediately opens the
freshly extracted ggml-base.dll for scanning. This locks the file at the exact
moment os.replace() calls MoveFileEx, causing WinError 5.
This is reproducible even with Add-MpPreference -ExclusionPath set, because the
DLL is already open before the exclusion takes effect for that file handle.
2. Architecture misdetection
The installer's Python process runs under x64 WoW64 emulation, so
platform.machine() returns amd64 instead of ARM64. The installer therefore
downloads the x64 prebuilt binary — which is fine (WoW64 runs it), but means
Unsloth Studio runs at ~5-6 t/s instead of the ~9-10 t/s achievable with a native
ARM64 binary (confirmed by Ollama benchmark on same hardware).
Fix (tested and working)
Patch install_llama_prebuilt.py to fall back from os.replace() to shutil.copytree()
when the rename fails. File-by-file copy bypasses MoveFileEx entirely.
File: %USERPROFILE%\.unsloth\studio\unsloth_studio\Lib\site-packages\studio\install_llama_prebuilt.py
Find (around line 4816):
os.replace(install_dir, rollback_dir)
log(f"moved existing install to rollback path {rollback_dir.name}")
log(f"activating staged install {staging_dir} -> {install_dir}")
os.replace(staging_dir, install_dir)
Replace with:
try:
os.replace(install_dir, rollback_dir)
except OSError:
shutil.move(str(install_dir), str(rollback_dir))
log(f"moved existing install to rollback path {rollback_dir.name}")
log(f"activating staged install {staging_dir} -> {install_dir}")
try:
os.replace(staging_dir, install_dir)
except OSError:
shutil.copytree(str(staging_dir), str(install_dir), dirs_exist_ok=True)
shutil.rmtree(str(staging_dir), ignore_errors=True)
log(f"activated via shutil.copytree fallback (ARM64 os.replace workaround)")
After this patch, .\install.ps1 --no-torch completes successfully and Unsloth Studio
runs on http://127.0.0.1:8888.
Additional context: Ollama must be stopped before install
If Ollama is running, it holds its own ggml-*.dll in memory, causing the same
WinError 5. Before running the installer:
Stop-Process -Name "ollama" -Force -ErrorAction SilentlyContinue
Stop-Service -Name "ollama" -Force -ErrorAction SilentlyContinue
Add-MpPreference -ExclusionPath "$env:USERPROFILE\.unsloth"
Suggested proper fix for the codebase
-
os.replace() fallback in install_llama_prebuilt.py (safe on all platforms,
os.replace() is still attempted first as the fast path)
-
ARM64 architecture detection via Windows registry instead of platform.machine():
import winreg
try:
key = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE,
r"SYSTEM\CurrentControlSet\Control\Session Manager\Environment")
arch = winreg.QueryValueEx(key, "PROCESSOR_ARCHITECTURE")[0]
# Returns "ARM64" on ARM64 Windows regardless of Python WoW64 mode
except Exception:
arch = platform.machine()
- Native ARM64 Windows llama.cpp binary — benchmark shows ~1.5-2x performance
gap vs Ollama (which ships ARM64 native) on the same Snapdragon X Elite hardware.
Performance data (Snapdragon X Elite, Gemma 4 12B)
| Backend |
Binary |
Speed |
| Unsloth Studio |
x64 via WoW64 |
~5-6 t/s |
| Ollama |
native ARM64 |
~9-10 t/s |
A native ARM64 Unsloth binary should fully close this gap.
Related issues
Title
[WinError 5] Access Deniedon Windows ARM64 (Snapdragon X Elite) –install_llama_prebuilt.pyfix includedSummary
Installing Unsloth Studio on Windows ARM64 (Snapdragon X Elite) consistently fails with
[WinError 5] Access Deniedduring thellama.cppprebuilt activation step. The source build fallback also fails. A working fix exists — one-time patch toinstall_llama_prebuilt.py.Environment
.\install.ps1 --no-torchError
Also note in the log:
Root Cause
Two issues compound:
1.
os.replace()fails on ARM64 Windows due to AV race conditioninstall_llama_prebuilt.pyactivates the install via:On Windows ARM64, after ZIP extraction, Windows Defender immediately opens the freshly extracted
ggml-base.dllfor scanning. This locks the file at the exact momentos.replace()callsMoveFileEx, causing WinError 5.This is reproducible even with
Add-MpPreference -ExclusionPathset, because the DLL is already open before the exclusion takes effect for that file handle.2. Architecture misdetection
The installer's Python process runs under x64 WoW64 emulation, so
platform.machine()returnsamd64instead ofARM64. The installer therefore downloads the x64 prebuilt binary — which is fine (WoW64 runs it), but means Unsloth Studio runs at ~5-6 t/s instead of the ~9-10 t/s achievable with a native ARM64 binary (confirmed by Ollama benchmark on same hardware).Fix (tested and working)
Patch
install_llama_prebuilt.pyto fall back fromos.replace()toshutil.copytree()when the rename fails. File-by-file copy bypassesMoveFileExentirely.File:
%USERPROFILE%\.unsloth\studio\unsloth_studio\Lib\site-packages\studio\install_llama_prebuilt.pyFind (around line 4816):
Replace with:
After this patch,
.\install.ps1 --no-torchcompletes successfully and Unsloth Studio runs on http://127.0.0.1:8888.Additional context: Ollama must be stopped before install
If Ollama is running, it holds its own
ggml-*.dllin memory, causing the same WinError 5. Before running the installer:Suggested proper fix for the codebase
os.replace()fallback ininstall_llama_prebuilt.py(safe on all platforms,os.replace()is still attempted first as the fast path)ARM64 architecture detection via Windows registry instead of
platform.machine():Performance data (Snapdragon X Elite, Gemma 4 12B)
A native ARM64 Unsloth binary should fully close this gap.
Related issues