From e9ce91e9a609968e066859900e06e663b929d197 Mon Sep 17 00:00:00 2001 From: Daniel Hiltgen Date: Thu, 4 Jan 2024 08:41:41 -0800 Subject: [PATCH] Load dynamic cpu lib on windows On linux, we link the CPU library in to the Go app and fall back to it when no GPU match is found. On windows we do not link in the CPU library so that we can better control our dependencies for the CLI. This fixes the logic so we correctly fallback to the dynamic CPU library on windows. --- llm/ext_server_windows.go | 5 +---- llm/llama.cpp/gen_windows.ps1 | 3 +++ llm/llm.go | 3 ++- llm/shim_ext_server_windows.go | 13 ++++++++++--- 4 files changed, 16 insertions(+), 8 deletions(-) diff --git a/llm/ext_server_windows.go b/llm/ext_server_windows.go index 24b57b6d..52ee5a6a 100644 --- a/llm/ext_server_windows.go +++ b/llm/ext_server_windows.go @@ -1,8 +1,6 @@ package llm import ( - "fmt" - "github.com/jmorganca/ollama/api" ) @@ -10,6 +8,5 @@ func newDefaultExtServer(model string, adapters, projectors []string, numLayers // On windows we always load the llama.cpp libraries dynamically to avoid startup DLL dependencies // This ensures we can update the PATH at runtime to get everything loaded - // Should not happen - return nil, fmt.Errorf("no default impl on windows - all dynamic") + return newDynamicShimExtServer(AvailableShims["cpu"], model, adapters, projectors, numLayers, opts) } diff --git a/llm/llama.cpp/gen_windows.ps1 b/llm/llama.cpp/gen_windows.ps1 index 40cb8274..e8e5835d 100644 --- a/llm/llama.cpp/gen_windows.ps1 +++ b/llm/llama.cpp/gen_windows.ps1 @@ -49,6 +49,9 @@ function install { md "${script:buildDir}/lib" -ea 0 > $null cp "${script:buildDir}/bin/${script:config}/ext_server_shared.dll" "${script:buildDir}/lib" cp "${script:buildDir}/bin/${script:config}/llama.dll" "${script:buildDir}/lib" + + # Display the dll dependencies in the build log + dumpbin /dependents "${script:buildDir}/bin/${script:config}/ext_server_shared.dll" | select-string ".dll" } function cleanup { diff --git a/llm/llm.go b/llm/llm.go index c71a44e0..6179bb4e 100644 --- a/llm/llm.go +++ b/llm/llm.go @@ -87,7 +87,8 @@ func newLlmServer(library, model string, adapters, projectors []string, numLayer if err == nil { return srv, nil } - log.Printf("Failed to load dynamic library - falling back to CPU mode %s", err) + log.Printf("Failed to load dynamic library %s - falling back to CPU mode %s", library, err) + // TODO - update some state to indicate we were unable to load the GPU library for future "info" ux } return newDefaultExtServer(model, adapters, projectors, numLayers, opts) diff --git a/llm/shim_ext_server_windows.go b/llm/shim_ext_server_windows.go index 6a12b61d..b140c22c 100644 --- a/llm/shim_ext_server_windows.go +++ b/llm/shim_ext_server_windows.go @@ -4,6 +4,7 @@ import ( "embed" "log" "os" + "path/filepath" "strings" ) @@ -11,14 +12,20 @@ import ( var libEmbed embed.FS func updatePath(dir string) { + tmpDir := filepath.Dir(dir) pathComponents := strings.Split(os.Getenv("PATH"), ";") + i := 0 for _, comp := range pathComponents { - // Case incensitive - if strings.ToLower(comp) == strings.ToLower(dir) { + if strings.EqualFold(comp, dir) { return } + // Remove any other prior paths to our temp dir + if !strings.HasPrefix(strings.ToLower(comp), strings.ToLower(tmpDir)) { + pathComponents[i] = comp + i++ + } } - newPath := strings.Join(append(pathComponents, dir), ";") + newPath := strings.Join(append([]string{dir}, pathComponents...), ";") log.Printf("Updating PATH to %s", newPath) os.Setenv("PATH", newPath) }