fix(parakeet): request word-granularity segments (was per-subword 'T Est Ing')
transcribe-rs 0.3.10's ParakeetModel::transcribe_raw ignores its
options argument and calls self.infer(samples, &TimestampGranularity::default())
where default is TimestampGranularity::Token — per-subword segments.
That surfaces in Kon as output like 'T Est Ing One , Two , Three . W Ow ,
This Is T Ri Ble .' because DictationPage joins segment texts with ' '.
Introduce a thin ParakeetWordGranularity wrapper that implements
SpeechModel and overrides transcribe_raw to call the concrete
ParakeetModel::transcribe_with() with ParakeetParams { timestamp_granularity:
Some(Word) }. Pre-existing bug unrelated to Phase 2 work — surfaced during
Group 1 dogfooding because Parakeet was being tested for the first time.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -113,6 +113,42 @@ impl LocalEngine {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Thin wrapper over `ParakeetModel` that overrides `transcribe_raw` to
|
||||||
|
/// request word-granularity segments. `transcribe-rs` 0.3's trait impl for
|
||||||
|
/// `ParakeetModel::transcribe_raw` ignores `TranscribeOptions` and uses
|
||||||
|
/// `TimestampGranularity::Token` (per-subword) — which surfaces in Kon as
|
||||||
|
/// "T Est Ing . One , Two , Three" output. The concrete-type method
|
||||||
|
/// `ParakeetModel::transcribe_with` accepts `ParakeetParams` with an
|
||||||
|
/// explicit granularity; this wrapper exposes that to the trait object.
|
||||||
|
struct ParakeetWordGranularity(transcribe_rs::onnx::parakeet::ParakeetModel);
|
||||||
|
|
||||||
|
impl transcribe_rs::SpeechModel for ParakeetWordGranularity {
|
||||||
|
fn capabilities(&self) -> transcribe_rs::ModelCapabilities {
|
||||||
|
self.0.capabilities()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn default_leading_silence_ms(&self) -> u32 {
|
||||||
|
self.0.default_leading_silence_ms()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn default_trailing_silence_ms(&self) -> u32 {
|
||||||
|
self.0.default_trailing_silence_ms()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn transcribe_raw(
|
||||||
|
&mut self,
|
||||||
|
samples: &[f32],
|
||||||
|
options: &TranscribeOptions,
|
||||||
|
) -> std::result::Result<TranscriptionResult, transcribe_rs::TranscribeError> {
|
||||||
|
use transcribe_rs::onnx::parakeet::{ParakeetParams, TimestampGranularity};
|
||||||
|
let params = ParakeetParams {
|
||||||
|
language: options.language.clone(),
|
||||||
|
timestamp_granularity: Some(TimestampGranularity::Word),
|
||||||
|
};
|
||||||
|
self.0.transcribe_with(samples, ¶ms)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Load a Parakeet model from a directory path.
|
/// Load a Parakeet model from a directory path.
|
||||||
pub fn load_parakeet(
|
pub fn load_parakeet(
|
||||||
model_dir: &Path,
|
model_dir: &Path,
|
||||||
@@ -127,7 +163,7 @@ pub fn load_parakeet(
|
|||||||
"Failed to load Parakeet: {e}"
|
"Failed to load Parakeet: {e}"
|
||||||
))
|
))
|
||||||
})?;
|
})?;
|
||||||
Ok(Box::new(model))
|
Ok(Box::new(ParakeetWordGranularity(model)))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Load a Whisper model from a GGML file path.
|
/// Load a Whisper model from a GGML file path.
|
||||||
|
|||||||
Reference in New Issue
Block a user