diff --git a/0001-Load-the-dynamic-backends-from-the-library-itself.patch b/0001-Load-the-dynamic-backends-from-the-library-itself.patch new file mode 100644 index 0000000..d27ad81 --- /dev/null +++ b/0001-Load-the-dynamic-backends-from-the-library-itself.patch @@ -0,0 +1,48 @@ +From: Onuralp Sezer +Date: Sun, 23 Aug 2026 15:10:00 +0300 +Subject: [PATCH] Load the dynamic backends from the library itself + +When whisper.cpp is built with GGML_BACKEND_DL the compute backends become +loadable modules, and something has to call ggml_backend_load_all() before any +device can be found. Today only the bundled example programs do that, so a +program that links libwhisper and calls whisper_init_* directly finds no +devices at all and ggml aborts on GGML_ASSERT(device). + +Do it inside whisper_backend_init_gpu, guarded by std::call_once so repeated +context creation stays cheap. It is a no-op for a build that is not using +loadable backends. + +Signed-off-by: Onuralp Sezer +--- + src/whisper.cpp | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/src/whisper.cpp b/src/whisper.cpp +index 1111111..2222222 100644 +--- a/src/whisper.cpp ++++ b/src/whisper.cpp +@@ -28,6 +28,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -1290,6 +1291,16 @@ static size_t whisper_backend_buffer_size(const whisper_context_params & params) + static ggml_backend_t whisper_backend_init_gpu(const whisper_context_params & params) { + ggml_log_set(g_state.log_callback, g_state.log_callback_user_data); + ++ // With GGML_BACKEND_DL the backends are loadable modules and nothing has ++ // registered them yet. Callers that link this library rather than using the ++ // bundled examples would otherwise find no devices at all. ++ { ++ static std::once_flag flag; ++ std::call_once(flag, [] { ++ ggml_backend_load_all(); ++ }); ++ } ++ + ggml_backend_dev_t dev = nullptr; + + int cnt = 0; diff --git a/whisper-cpp.spec b/whisper-cpp.spec index 15090bf..0db33a8 100644 --- a/whisper-cpp.spec +++ b/whisper-cpp.spec @@ -14,6 +14,11 @@ Release: %autorelease URL: https://github.com/ggerganov/whisper.cpp Source0: %{url}/archive/refs/tags/v%{version}.tar.gz#/whisper.cpp-%{version}.tar.gz +# A library built with GGML_BACKEND_DL has to register its own backends, or +# anything linking it finds no devices and aborts. Drop this once ggml does +# the registration itself. +Patch0: 0001-Load-the-dynamic-backends-from-the-library-itself.patch + ExclusiveArch: x86_64 aarch64 ppc64le %global toolchain gcc @@ -43,6 +48,17 @@ ExclusiveArch: x86_64 aarch64 ppc64le %global rocm_gpu_list %{nil} %endif +# GGML_CPU_ALL_VARIANTS builds one CPU backend per microarchitecture and picks +# the best one at startup, so we keep running on old hardware while still using +# AVX2 and friends where they exist. Upstream supports it on x86, ARM and +# PowerPC, which is every arch in ExclusiveArch above. +# +# The backends become dlopened modules, and they are only looked for in this +# directory, the executable's directory and the current one. Without +# GGML_BACKEND_DIR they would land in %%{_bindir} and never be found. Keep it +# package private, llama-cpp ships its own copy of ggml. +%global backend_dir %{_libdir}/%{name} + %bcond_with test %if %{with test} %global build_test ON @@ -118,6 +134,9 @@ recognition (ASR) model: -DWHISPER_OPENVINO=%{build_openvino} \ -DGGML_HIP=%{build_rocm} \ -DGGML_NATIVE=OFF \ + -DGGML_BACKEND_DL=ON \ + -DGGML_CPU_ALL_VARIANTS=ON \ + -DGGML_BACKEND_DIR=%{backend_dir} \ -DGGML_AMX_TILE=OFF \ -DGGML_AMX_INT8=OFF \ -DGGML_AMX_BF16=OFF \ @@ -156,20 +175,18 @@ find %{buildroot} -name 'whisper.pc' -delete %license LICENSE %{_libdir}/libggml.so.* %{_libdir}/libggml-base.so.* -%{_libdir}/libggml-cpu.so.* %{_libdir}/libwhisper.so.* %{_libdir}/libparakeet.so.* -%if %{with rocm} -%{_libdir}/libggml-hip.so.* -%endif +# The backend modules carry no version, but they are dlopened at runtime, so +# they belong here and not in the devel package. +%{backend_dir}/ %files devel %doc README.md %{_includedir}/*.h %{_libdir}/libggml.so %{_libdir}/libggml-base.so -%{_libdir}/libggml-cpu.so %{_libdir}/libparakeet.so %{_libdir}/libwhisper.so %{_libdir}/cmake/ggml/ @@ -177,10 +194,6 @@ find %{buildroot} -name 'whisper.pc' -delete %{_libdir}/cmake/whisper/ %{_libdir}/pkgconfig/parakeet.pc -%if %{with rocm} -%{_libdir}/libggml-hip.so -%endif - %changelog %autochangelog