In a build configured with -DTRANSCRIBE_GGML_BACKEND_DL=ON, every run of
transcribe-cli or transcribe-bench that loads a model fails with
TRANSCRIBE_ERR_BACKEND.
Root cause
Nothing registers the backend modules. transcribe_init_backends_default() is
called only in list_devices_main() (examples/cli/main.cpp:362), which main()
reaches solely for --list-devices; tools/transcribe-bench/main.cpp never calls
it. With an empty device registry init_cpu_backend() returns nullptr and the
load fails. transcribe-bench also rejects --device N up front, since the index
resolves through the same registry (:334).
examples/hello and examples/hello_stream call transcribe_open() without
registering either.
The comment at tools/transcribe-bench/main.cpp:327 is misleading: it says
--backend is consumed "via transcribe::load_common::init_backends", which
selects a device from the registry but does not populate it.
Reproduction
cmake -B build -DCMAKE_BUILD_TYPE=Release \
-DTRANSCRIBE_GGML_BACKEND_DL=ON -DTRANSCRIBE_BUILD_SHARED=ON \
-DTRANSCRIBE_BUILD_EXAMPLES=ON -DTRANSCRIBE_BUILD_TOOLS=ON
cmake --build build -j
cp -a build/bin/libggml-*.so build/src/ # modules next to libtranscribe
export LD_LIBRARY_PATH=$PWD/build/src:$PWD/build/ggml/src
build/bin/transcribe-cli --list-devices # works: 1 compute device(s)
build/bin/transcribe-bench --model m.gguf --sample a.wav --device 0
# error: --device index 0 is not available
Fix
Calling transcribe_init_backends_default() once at the top of each tool's
main() is enough. Verified against the reproduction above:
--- a/examples/cli/main.cpp
+++ b/examples/cli/main.cpp
@@ -754,6 +754,16 @@ int main(int argc, char ** argv) {
transcribe_log_set(log_cb, nullptr);
}
+ // Register the backend modules before the first model load. In a
+ // dynamic-backend build nothing is registered until a host asks for it,
+ // and the loader then finds no CPU device and fails the load with
+ // TRANSCRIBE_ERR_BACKEND; in a compiled-in build this is a no-op.
+ if (const transcribe_status st = transcribe_init_backends_default(); st != TRANSCRIBE_OK) {
+ std::fprintf(stderr, "error: transcribe_init_backends_default: %s\n", transcribe_status_string(st));
+ return EXIT_FAILURE;
+ }
+
std::ofstream output_file;
The same block goes into tools/transcribe-bench/main.cpp after the log setup
(before --device is resolved), and into the two examples.
In a build configured with
-DTRANSCRIBE_GGML_BACKEND_DL=ON, every run oftranscribe-cliortranscribe-benchthat loads a model fails withTRANSCRIBE_ERR_BACKEND.Root cause
Nothing registers the backend modules.
transcribe_init_backends_default()iscalled only in
list_devices_main()(examples/cli/main.cpp:362), whichmain()reaches solely for
--list-devices;tools/transcribe-bench/main.cppnever callsit. With an empty device registry
init_cpu_backend()returnsnullptrand theload fails.
transcribe-benchalso rejects--device Nup front, since the indexresolves through the same registry (
:334).examples/helloandexamples/hello_streamcalltranscribe_open()withoutregistering either.
The comment at
tools/transcribe-bench/main.cpp:327is misleading: it says--backendis consumed "viatranscribe::load_common::init_backends", whichselects a device from the registry but does not populate it.
Reproduction
cmake -B build -DCMAKE_BUILD_TYPE=Release \ -DTRANSCRIBE_GGML_BACKEND_DL=ON -DTRANSCRIBE_BUILD_SHARED=ON \ -DTRANSCRIBE_BUILD_EXAMPLES=ON -DTRANSCRIBE_BUILD_TOOLS=ON cmake --build build -j cp -a build/bin/libggml-*.so build/src/ # modules next to libtranscribe export LD_LIBRARY_PATH=$PWD/build/src:$PWD/build/ggml/src build/bin/transcribe-cli --list-devices # works: 1 compute device(s) build/bin/transcribe-bench --model m.gguf --sample a.wav --device 0 # error: --device index 0 is not availableFix
Calling
transcribe_init_backends_default()once at the top of each tool'smain()is enough. Verified against the reproduction above:The same block goes into
tools/transcribe-bench/main.cppafter the log setup(before
--deviceis resolved), and into the two examples.