Skip to content

[WinError 5] install_llama_prebuilt.py fails on Windows ARM64 (Snapdragon X Elite) – fix included #6130

@gaiagent0

Description

@gaiagent0

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} -&gt; {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} -&gt; {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

  1. os.replace() fallback in install_llama_prebuilt.py (safe on all platforms, os.replace() is still attempted first as the fast path)

  2. 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()
  1. 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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions