Skip to content

Expose actual OpenVINO execution devices through the Parakeet C API #14

Open

Description

@evo-social-world

Problem

Eddy's Parakeet OpenVINO path can fall back individual graphs from NPU to CPU through compile_with_npu_fallback(), but embeddings using eddy_c cannot inspect the resulting execution devices.

Today a service can report the requested device and the devices visible to OpenVINO, but neither proves where the preprocessor, encoder, decoder, and joint graphs actually compiled. The only fallback signal is diagnostic output, and detailed compiler output is gated by EDDY_DEBUG.

This makes it difficult for local services and health checks to distinguish:

  • an NPU that is merely available;
  • a model requested on NPU;
  • a model whose inference graphs actually execute on NPU;
  • a partial CPU fallback.

Proposed API

OpenVINO already exposes ov::execution_devices / EXECUTION_DEVICES on each ov::CompiledModel. Expose those values through the Parakeet C++ and C APIs after compilation.

One additive C API shape is:

typedef struct {
    char* preprocessor;
    char* encoder;
    char* decoder;
    char* joint;
} EddyParakeetComponentDevices;

EDDY_API EddyError eddy_parakeet_get_component_devices(
    EddyParakeetModel model,
    EddyParakeetComponentDevices* devices,
    char** error_message);

EDDY_API void eddy_parakeet_free_component_devices(
    EddyParakeetComponentDevices* devices);

The corresponding OpenVINOParakeet::component_devices() method can call get_property(ov::execution_devices) for each compiled model. The getter should force ensure_compiled_model() if necessary, return owned strings with explicit cleanup, and serialize access with the existing request mutex.

A later API could also add a strict allow_cpu_fallback/require_device option, but machine-readable introspection is independently useful and keeps fallback policy in the embedding application.

Local implementation and validation

I implemented and tested this locally as an additive patch against commit 07028cf333f97244f0f3ff718cc748d7dd0a8915.

Test system:

  • Intel Core Ultra X7 358H / Panther Lake NPU50xx
  • Intel NPU driver 1.35.0 and compiler 2026.28
  • OpenVINO 2026.3
  • Parakeet TDT 0.6B V3 INT8

Observed component devices:

{
  "preprocessor": "CPU",
  "encoder": "NPU",
  "decoder": "NPU",
  "joint": "NPU"
}

The CPU preprocessor is expected. The embedding service now refuses startup if encoder, decoder, or joint does not report NPU.

Validation performed:

  • C++ test that a tiny CPU ov::CompiledModel reports CPU through the helper.
  • C API ownership/error-path test for the new struct and cleanup function.
  • Hardware integration test that all three Parakeet inference graphs report NPU.
  • Exported C symbols verified in libeddy_c.so.
  • Patch cleanly applies to the pinned commit.

The change is startup-only and does not affect inference throughput. On 107 real recordings totaling 1,805.7 seconds:

  • before introspection: 13.792 seconds, 130.9x real time;
  • after introspection: 13.789 / 13.925 / 14.057 seconds, 131.0x / 129.7x / 128.5x real time;
  • introspection getter: 0.0026 ms median over 1,000 calls.

I can submit the tested patch as a focused PR if this API direction is acceptable.

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