* feat(parakeet): add optional Underdog Bark 3.0 int8 model Adds bark-3.0 to the Parakeet model picker: Underdog Bark 3.0, an English fine-tune of Parakeet TDT 0.6B v3, as the int8 sherpa-onnx conversion published at velddev/Underdog-Bark-3.0-sherpa-onnx. It runs on the existing sherpa-onnx recognizer, pinned to a revision with every file checked against model_checksums.txt, like Orukeet (#840). The conversion writes the unknown-word token where a quote mark was, so the Parakeet transcript drops <unk>; the other models never emit it. * docs(parakeet): say when to pick Bark 3.0; loosen its catalog test The README now says Bark suits English dictation of conversational speech and v3-european stays the choice for read or multilingual speech. The test checks that bark-3.0 is offered rather than that it is the last catalog entry, so a later model does not break it. * test(parakeet): add docstrings to the Bark tests * feat(parakeet): add optional 4-bit Underdog Bark 3.0 build Adds bark-3.0-int4: the same Bark 3.0 weights quantized to 4-bit with onnxruntime's HQQ quantizer, for machines short on memory. It needs about half the RAM of the int8 build (0.64 GB against 1.28 GB peak) and a 379 MiB download, at two to four times the CPU time (about 2x on Intel, 3.7x on AMD by the publisher's measurement). The files are published in velddev/Underdog-Bark-3.0-sherpa-onnx (Hugging Face PR #1), and both Bark entries now pin its revision 3ae3af1, which holds both builds; the int8 files are unchanged there. Catalog entries gain an optional "precision" key, so the loader opens encoder.int4.onnx and friends instead of assuming int8; every existing model keeps the int8 default. The README section now covers both builds in a few lines. * test(parakeet): type the Bark test signatures * docs(parakeet): name the Bark sherpa-onnx source and its pins The README now says where both Bark builds download from (a pinned revision of velddev/Underdog-Bark-3.0-sherpa-onnx), that it is an unofficial conversion, and that each file is checked against its bundled SHA-256 pin, as the Orukeet section does. --------- Co-authored-by: Jatin <jatinkrmalik@gmail.com>
56 lines
2.5 KiB
Python
56 lines
2.5 KiB
Python
"""Optional Underdog Bark 3.0 catalog entries, their file names and <unk> output."""
|
|
|
|
import sys
|
|
import threading
|
|
from pathlib import Path
|
|
from unittest.mock import MagicMock
|
|
|
|
import pytest
|
|
|
|
from vocalinux.speech_recognition.recognition_manager import SpeechRecognitionManager
|
|
from vocalinux.utils import parakeet_model_info as models
|
|
from vocalinux.utils.model_checksums import expected_for
|
|
|
|
REPO = "velddev/Underdog-Bark-3.0-sherpa-onnx"
|
|
|
|
|
|
@pytest.mark.parametrize("model, precision", [("bark-3.0", "int8"), ("bark-3.0-int4", "int4")])
|
|
def test_bark_is_optional_pinned_and_keeps_its_license_files(model: str, precision: str) -> None:
|
|
"""Both Bark builds are offered but not recommended, and every file they download is pinned."""
|
|
assert models.RECOMMENDED_MODEL == "v3-european"
|
|
assert model in models.MODEL_SIZES
|
|
assert {"LICENSE", "NOTICE", f"encoder.{precision}.onnx"} <= set(models.model_files(model))
|
|
for name in models.model_files(model):
|
|
assert expected_for(models.manifest_key(model, name)) is not None
|
|
assert models.get_model_file_url(model, "NOTICE").startswith(f"https://huggingface.co/{REPO}/")
|
|
|
|
|
|
def test_int4_build_loads_its_own_file_names(
|
|
monkeypatch: pytest.MonkeyPatch, tmp_path: Path
|
|
) -> None:
|
|
"""The 4-bit entry's precision key makes the loader open the *.int4.onnx files."""
|
|
manager = SpeechRecognitionManager.__new__(SpeechRecognitionManager)
|
|
manager.model_size = "bark-3.0-int4"
|
|
manager._defer_download = False
|
|
sherpa = MagicMock()
|
|
monkeypatch.setitem(sys.modules, "sherpa_onnx", sherpa)
|
|
monkeypatch.setattr(models, "get_model_path", lambda _: str(tmp_path))
|
|
monkeypatch.setattr(models, "is_model_downloaded", lambda _: True)
|
|
monkeypatch.setattr(manager, "_parakeet_model_is_verified", lambda *_: True)
|
|
manager._init_parakeet()
|
|
kwargs = sherpa.OfflineRecognizer.from_transducer.call_args.kwargs
|
|
assert [kwargs[part].rsplit("/", 1)[1] for part in ("encoder", "decoder", "joiner")] == [
|
|
"encoder.int4.onnx",
|
|
"decoder.int4.onnx",
|
|
"joiner.int4.onnx",
|
|
]
|
|
|
|
|
|
def test_unknown_word_token_is_dropped_from_the_transcript() -> None:
|
|
"""Parakeet transcripts drop <unk> and collapse the spaces it leaves."""
|
|
manager = SpeechRecognitionManager.__new__(SpeechRecognitionManager)
|
|
manager._model_lock = threading.Lock()
|
|
manager.model = MagicMock()
|
|
manager.model.create_stream.return_value.result.text = " like a shampooer,<unk>Next man.<unk>"
|
|
assert manager._transcribe_with_parakeet([b"\x00\x00" * 160]) == "like a shampooer, Next man."
|