Skip to content

transcribe-cli and transcribe-bench never register backend modules: model loads fail with TRANSCRIBE_ERR_BACKEND in a GGML_BACKEND_DL build #167

Description

@shaba

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.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions