Skip to content

feat: add native Windows support (server + windows/amd64 llama-cpp backend) - #11429

Open
LionelColaso wants to merge 1 commit into
mudler:masterfrom
LionelColaso:windows-backends-llama-cpp
Open

feat: add native Windows support (server + windows/amd64 llama-cpp backend)#11429
LionelColaso wants to merge 1 commit into
mudler:masterfrom
LionelColaso:windows-backends-llama-cpp

Conversation

@LionelColaso

@LionelColaso LionelColaso commented Aug 9, 2026

Copy link
Copy Markdown

Description

Adds native Windows support end to end: LocalAI now releases a windows/amd64 server binary, and the llama-cpp backend is built natively for windows/amd64 under MSYS2 UCRT64 and packaged as an OCI image tar that LocalAI installs and runs as a native process - no docker daemon or WSL required on the host.

Server side

  • goreleaser: add windows (amd64/arm64) to the release targets
  • Makefile: download the win64 protoc zip and rename protoc.exe to protoc, resolve code-gen plugins via --plugin instead of PATH, force SHELL=sh and name the binary local-ai.exe on Windows, ignore protoc.exe
  • build-test.yaml: add a native windows-latest build gate that installs GNU make via Chocolatey, adds Git for Windows' usr/bin to PATH and builds with CGO_ENABLED=0
  • pkg/downloader: close the write handle before removing or renaming a partial download so Windows file locks do not break the resume and error paths; guard the POSIX-permission and symlink tests on non-Windows
  • tests: Windows guards and path fixes for core/gallery, video_internal, loader and the testcontainers database setup

Backend side

  • scripts/build/llama-cpp-windows.sh: builds gRPC from source (pinned v1.59.0, with mingw-w64 fixes for c-ares, boringssl and zlib), then the three llama.cpp variants (cpu-all with GGML_CPU_ALL_VARIANTS + Vulkan, rpc, and the AVX-off fallback), bundles the mingw runtime DLLs and ships an OCI tar via local-ai util create-oci-image. Re-runnable and auto-dispatches into MSYS2 when launched from Git for Windows' bash. JOBS override supported for memory-limited hosts.
  • backend/cpp/llama-cpp/run.ps1: PowerShell launcher (mirrors run.sh) that pkg/model/process.go starts on Windows
  • backend/index.yaml: windows/amd64 backend entry and variants
  • pkg/system/capabilities.go: windows engine preference rules so the gallery picks the native build on Windows hosts
  • .github/backend-matrix.yml + backend_build_windows.yml: windows matrix entries and a reusable windows build workflow; backend.yml and backend_pr.yml wire the windows backend jobs (build on PR, publish on master)
  • docs/content/getting-started/windows.md plus related page updates (GPU-acceleration, install)

Notes for Reviewers

  • The Windows backend image ships three llama-cpp executables picked by the run.ps1 launcher: llama-cpp-cpu-all.exe (all ggml CPU variants, auto-detects a Vulkan device at runtime and falls back to CPU), llama-cpp-grpc.exe (gRPC-RPC build, selected when LLAMACPP_GRPC_SERVERS is set) and llama-cpp-fallback.exe (static, AVX-off fallback). The mingw runtime DLLs are bundled in the image, so no MSYS2 install is needed on the host.
  • macOS is intentionally unaffected; the Darwin matrix entries are unchanged.

Signed commits

  • Yes, I signed my commits.
  • Documentation updated (docs/content/) for user-facing changes, or not applicable

Assisted-by: opencode:big-pickle

Closes #2368

@LionelColaso
LionelColaso force-pushed the windows-backends-llama-cpp branch 2 times, most recently from 6caf372 to b347f46 Compare August 9, 2026 18:16
@LionelColaso LionelColaso changed the title feat: add native Windows support with a windows/amd64 llama-cpp backend feat: add native Windows support (server + windows/amd64 llama-cpp backend) Aug 9, 2026
@LionelColaso
LionelColaso force-pushed the windows-backends-llama-cpp branch from b347f46 to c16c463 Compare August 9, 2026 18:25
}
dir := filepath.Dir(exe)

binary := "llama-cpp-fallback.exe"

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why a separate main?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good question. Windows has no shell to run run.sh through, so the gallery's run.sh contract can't work there directly. run.exe is a small native PE that mirrors run.sh's selection logic — prefer llama-cpp-cpu-all.exe, fall back to the gRPC-RPC build when LLAMACPP_GRPC_SERVERS is set, else llama-cpp-fallback.exe — and prepends the bundled lib\ dir to PATH. pkg/model/process.go picks it up when it exists next to run.sh.

It's built at CI time by scripts/build/llama-cpp-windows.sh (CGO_ENABLED=0 go build ./backend/cpp/llama-cpp/run-windows), so changing the launcher needs no C++ toolchain. As part of this cleanup I also removed the orphaned run.cmd (see the other thread).

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what I mean is, why not having then just a windows power shell script instead? adding a compiled binary for a launcher is really wasting space. And startup times should be nearly the same (and in any case, neglectible)

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed — that's cleaner. I've replaced run.exe with run.ps1, a small PowerShell launcher that mirrors run.sh (same binary-selection and lib\ PATH logic). pkg/model/process.go now spawns powershell.exe -NoProfile -ExecutionPolicy Bypass -File run.ps1 on Windows, and the build script just copies the script into the image instead of compiling a binary — no Go build step for the launcher anymore. The compiled run-windows main is deleted.

Verified locally on Windows with a fake backend: binary selection (cpu-all / grpc / fallback), arg forwarding, lib\ PATH prepend, exit-code propagation, and a backend dir with spaces all behave correctly.

Comment thread pkg/model/process.go Outdated
// run.sh stub keeps discovery, validation and upgrades uniform, while
// run.exe is the PE binary os.StartProcess actually starts.
if runtime.GOOS == "windows" {
if _, err := os.Stat(filepath.Join(workDir, "run.exe")); err == nil {

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is not correct, or at least is not coherent with the PR - you add a run.cmd wrapper, but then you don't call it here

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right — run.cmd was never invoked, and I've now removed it. The launcher this PR wires in is run.exe, a native PE built from backend/cpp/llama-cpp/run-windows, and pkg/model/process.go explicitly selects it on Windows (the branch at the lines above). The run.sh stub stays in the image purely so discovery/validation/upgrades stay uniform with the other platforms; on a Windows host the actual process spawned is run.exe.

@LionelColaso
LionelColaso force-pushed the windows-backends-llama-cpp branch 3 times, most recently from b6bbe35 to 4e16c60 Compare August 10, 2026 02:45

@localai-org-maint-bot localai-org-maint-bot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mudler the Windows launcher concerns are resolved on the rebased head: the unused run.cmd is removed, the native run.exe path is now explained, and backends/llama-cpp-windows is serialized in .NOTPARALLEL. I reviewed the range-diff from the prior head; git diff --check, the launcher build, pkg/system, and all 48 backend-filter tests pass. Good from my side once the newly restarted Windows/backend CI completes.

…ckend)

Native Windows support end to end: LocalAI releases a windows/amd64 server
binary and the llama-cpp backend is built natively for windows/amd64 under
MSYS2 UCRT64 and packaged as an OCI image tar that LocalAI installs and
runs as a native process - no docker daemon or WSL required on the host.

Server side:
- goreleaser: add windows (amd64/arm64) to the release targets
- Makefile: download the win64 protoc zip and rename protoc.exe to protoc,
  resolve code-gen plugins via --plugin instead of PATH, force SHELL=sh and
  name the binary local-ai.exe on Windows, ignore protoc.exe
- build-test.yaml: add a native windows-latest build gate that installs GNU
  make via choco, adds Git for Windows' usr/bin to PATH and builds with
  CGO_ENABLED=0
- pkg/downloader: close the write handle before removing or renaming the
  partial so Windows file locks do not break resume and error paths; guard
  the POSIX-permission and symlink tests on non-Windows
- tests: Windows guards and path fixes for core/gallery, video_internal,
  loader and the testcontainers database setup

Backend side:
- scripts/build/llama-cpp-windows.sh: builds gRPC from source (pinned
  v1.59.0, with mingw-w64 fixes for c-ares, boringssl and zlib), then the
  three llama.cpp variants (cpu-all with GGML_CPU_ALL_VARIANTS + Vulkan,
  rpc, and the AVX-off fallback), bundles the mingw runtime DLLs and ships
  an OCI tar via local-ai util create-oci-image. Re-runnable and
  auto-dispatchs into MSYS2 when launched from Git for Windows' bash.
- backend/cpp/llama-cpp/run.ps1: PowerShell launcher (mirrors run.sh) that
  pkg/model/process.go starts on Windows.
- backend/index.yaml: windows/amd64 backend entry and variants.
- pkg/system/capabilities.go: windows engine preference rules so the
  gallery picks the native build on Windows hosts.
- .github/backend-matrix.yml + backend_build_windows.yml: windows matrix
  entries and a reusable windows build workflow; backend.yml and
  backend_pr.yml wire the windows backend jobs (build on PR, publish on
  master).
- docs: getting-started/windows.md plus related page updates.

JOBS in the build script honors an override so memory-limited hosts can
build with reduced parallelism.

Signed-off-by: Lionel Colaso <lionelcolaso@outlook.com>
@LionelColaso
LionelColaso force-pushed the windows-backends-llama-cpp branch from 319917b to b269dde Compare August 12, 2026 09:29
@localai-org-maint-bot

Copy link
Copy Markdown
Collaborator

@mudler the requested launcher change is addressed on the rebased head: the compiled run.exe helper is gone, run.ps1 mirrors the binary selection and PATH setup, and pkg/model/process.go invokes it through Windows PowerShell. I isolated the patch from the rebase and verified git diff --check, all 48 backend-filter tests, and pkg/system; the contributor also reports native Windows launcher coverage for selection, argument forwarding, paths with spaces, and exit propagation. Good from my side; only DCO is currently reported, so the Windows/backend workflow result is still pending.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Native windows version?

3 participants