Qxotic jinfer Transcriptions

jinfer is a pure-JVM inference engine from the Qxotic AI project. JinferTranscriptionModel implements Spring AI’s TranscriptionModel. It transcribes speech locally from a GGUF model inside your application’s JVM, without an API key or external service. On a CPU, it transcribes faster than real time.

The jinfer Spring AI integration is an external module maintained by the Qxotic AI project, not part of the Spring AI repository. Its artifacts are published to Maven Central under the com.qxotic group.

Prerequisites

  • The same Java 25, JVM flag and Spring Boot requirements as the jinfer chat model.

  • A transcription model family on the classpath. NVIDIA Parakeet models are provided by jinfer-parakeet.

Auto-configuration

Add the jinfer Spring Boot starter and the Parakeet model family. Import both BOMs as shown in the jinfer chat model documentation.

<dependency>
    <groupId>com.qxotic</groupId>
    <artifactId>jinfer-spring-ai-spring-boot-starter</artifactId>
</dependency>
<dependency>
    <groupId>com.qxotic</groupId>
    <artifactId>jinfer-parakeet</artifactId>
</dependency>

or, for Gradle:

dependencies {
    implementation 'com.qxotic:jinfer-spring-ai-spring-boot-starter'
    implementation 'com.qxotic:jinfer-parakeet'
}

Transcription Properties

The JinferTranscriptionModel bean is created when spring.ai.jinfer.transcription.model is set. It does not use the spring.ai.model.audio.transcription selection property.

Property

Description

Default

spring.ai.jinfer.transcription.model

A local GGUF path or a model reference for a transcription model. Setting it creates the bean.

-

spring:
  ai:
    jinfer:
      transcription:
        model: mudler/parakeet-cpp-gguf/tdt-0.6b-v3-q8_0.gguf

Runtime Options

JinferTranscriptionModel has no tunable options. A per-request model option is rejected with an UnsupportedOperationException, because each instance is bound to the GGUF file it loaded.

Audio Input

The Resource passed to the model is decoded locally to 16 kHz mono audio. On a JVM, decoding uses javax.sound, which handles WAV, AIFF and AU. Other formats, such as MP3, M4A or OGG, automatically fall back to ffmpeg, which must be on the PATH. To always use one decoder, set -Djinfer.audioDecoder=ffmpeg or -Djinfer.audioDecoder=javasound. Audio is limited to 60 minutes by default. Raise the limit with -Djinfer.codecs.maxAudioMinutes.

String text = transcriptionModel.transcribe(new FileSystemResource("speech.wav"));

Word Timings and Confidences

The portable call method returns only the text. JinferTranscriptionModel also offers typed transcribe(Path) and transcribe(byte[]) methods, plus transcribe(Media.Audio) for audio already decoded into jinfer’s own com.qxotic.jinfer.media.Media.Audio type (16 kHz mono). They return jinfer’s full Transcription, which includes per-token time spans and confidences, and can group the tokens into words with words().

Transcription transcription = jinferTranscriptionModel.transcribe(Path.of("speech.wav"));
System.out.println(transcription.text());

JinferTranscriptionModel is thread-safe. Concurrent requests use independent states and can run in parallel.

Manual Configuration

Depend on com.qxotic:jinfer-spring-ai and com.qxotic:jinfer-parakeet, then build the model:

try (var transcriber = JinferTranscriptionModel.builder()
        .model("mudler/parakeet-cpp-gguf/tdt-0.6b-v3-q8_0.gguf")   // or .modelPath(Path.of("parakeet.gguf"))
        .build()) {

    System.out.println(transcriber.transcribe(new FileSystemResource("speech.wav")));
}

close() blocks until in-flight transcriptions have finished, then frees the model weights.