[Linux] CUDA12 backend silently falls back to CPU due to hardcoded RUNPATH in shipped .so files #1369
Cognameton
started this conversation in
General
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Summary
On Linux,
LLamaSharp.Backend.Cuda120.25.0 silently falls back to CPUregardless of
GpuLayerCount. No error is thrown. The model loads andruns normally, just entirely on CPU.
Root Cause
The shipped Linux
.sofiles (libggml-cuda.so,libllama.so, etc.)have a hardcoded absolute RUNPATH:
RUNPATH: /home/runner/work/LLamaSharp/LLamaSharp/build/bin
This is the CI build machine's path. On any end-user system that path
does not exist. When
libggml-cuda.soloads and looks for its dependencylibggml-base.so, the OS dynamic linker cannot find it, the CUDA backendfails to initialise, and LLamaSharp silently falls back to the CPU backend.
Impact
Every Linux user installing
LLamaSharp.Backend.Cuda12via NuGet isrunning on CPU without knowing it. The only clue is
dev = CPUin thellama.cpp layer log, which most users won't see or know to look for.
Workaround
private static void PreloadCudaBackend()
{
if (!OperatingSystem.IsLinux()) return;
}
private static string? BestCpuDir(string nativeDir)
{
try
{
var flags = File.ReadAllText("/proc/cpuinfo");
string[] candidates = flags.Contains("avx512") ? new[] { "avx512", "avx2", "avx", "noavx" }
: flags.Contains("avx2") ? new[] { "avx2", "avx", "noavx" }
: flags.Contains(" avx ") ? new[] { "avx", "noavx" }
: new[] { "noavx" };
foreach (var c in candidates)
{
var dir = Path.Combine(nativeDir, c);
if (Directory.Exists(dir)) return dir;
}
}
catch { }
return null;
}
private static void LoadLib(string path)
{
if (!File.Exists(path)) return;
try { NativeLibrary.Load(path); }
catch (Exception ex)
{
Console.WriteLine($"[WARN] Pre-load failed: {Path.GetFileName(path)} — {ex.Message}");
}
}
Worth noting in the update that libggml.so in the cuda12 folder is a combined backend dispatcher that depends on both libggml-cuda.so and libggml-cpu.so, so both need to be pre-loaded.
Fix
Build the Linux native libraries with -Wl,-rpath,$ORIGIN so the RUNPATH
resolves relative to the library's own directory rather than the CI
machine's absolute path.
Environment
Beta Was this translation helpful? Give feedback.
All reactions