voice_audio_multi/tests/parakeet_tdt/bark3_reference.py
Fabio c36510c21e
Some checks failed
Linux Build / Linux cpu (push) Has been cancelled
Linux Build / Linux cpu-clang (push) Has been cancelled
Linux Build / Linux vulkan (push) Has been cancelled
mac-build / macOS CPU (push) Has been cancelled
Nix Build / Nix (cpu) (push) Has been cancelled
Nix Build / Nix (vulkan) (push) Has been cancelled
windows-build / Windows CPU (push) Has been cancelled
Initial import: audio.cpp with Orange Pi documentation
2026-11-04 19:05:22 +01:00

79 lines
3.6 KiB
Python

#!/usr/bin/env python3
"""Generate original Transformers Bark 3.0 Pro references from local WAV files.
Use the pinned source snapshot described in docs/models/underdog_bark3.md.
This deliberately does not import or use audio.cpp's prepared weights.
"""
import argparse
import json
from pathlib import Path
import time
import numpy as np
import soundfile as sf
import torch
from transformers import AutoProcessor, ParakeetForTDT
def main():
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--source", type=Path, required=True)
parser.add_argument("--audio", type=Path, nargs="+", required=True)
parser.add_argument("--output", type=Path, required=True)
parser.add_argument("--threads", type=int, default=8)
parser.add_argument("--device", choices=["cpu", "cuda"], default="cpu")
parser.add_argument("--dtype", choices=["float32", "bfloat16"], default="float32")
parser.add_argument("--iterations", type=int, default=1)
parser.add_argument("--warmup-audio", type=Path)
args = parser.parse_args()
if args.iterations < 1 or args.threads < 1:
parser.error("iterations and threads must be positive")
if args.device == "cpu" and args.dtype != "float32":
parser.error("the publisher's CPU fallback uses float32")
if args.device == "cuda" and not torch.cuda.is_available():
parser.error("CUDA is unavailable in this PyTorch environment")
if args.device == "cuda" and args.dtype == "bfloat16" and not torch.cuda.is_bf16_supported():
parser.error("this GPU does not support BF16")
torch.set_num_threads(args.threads)
dtype = getattr(torch, args.dtype)
processor = AutoProcessor.from_pretrained(args.source, local_files_only=True)
model = ParakeetForTDT.from_pretrained(args.source, dtype=dtype, local_files_only=True).to(args.device).eval()
def read_wave(path):
wave, rate = sf.read(path, dtype="float32")
if rate != 16000 or wave.ndim != 1 or len(wave) == 0:
raise ValueError("reference fixtures must be nonempty mono 16 kHz WAVs")
return wave
def inputs_for(wave):
# Same once-per-recording prefix as runtime/transcribe_bark_pro.py.
padded = np.concatenate([np.zeros(4000, np.float32), wave])
return processor(padded, sampling_rate=16000, return_tensors="pt").to(args.device, dtype)
def synchronize():
if args.device == "cuda":
torch.cuda.synchronize()
if args.warmup_audio:
with torch.inference_mode():
model.generate(**inputs_for(read_wave(args.warmup_audio)))
synchronize()
records = []
for path in args.audio:
wave = read_wave(path) # File I/O and model loading are outside the timer.
runs = []
for _ in range(args.iterations):
synchronize()
started = time.perf_counter()
inputs = inputs_for(wave)
with torch.inference_mode():
generated = model.generate(**inputs)
synchronize()
ids = generated.sequences if hasattr(generated, "sequences") else generated
text = processor.batch_decode(ids, skip_special_tokens=True)[0]
runs.append(dict(seconds=time.perf_counter() - started, text=text))
records.append(dict(name=path.stem, path=str(path.resolve()), audio_seconds=len(wave) / 16000,
device=args.device, dtype=args.dtype, text=text, ids=ids.cpu().tolist(), runs=runs))
print(path.name, repr(text), flush=True)
args.output.parent.mkdir(parents=True, exist_ok=True)
args.output.write_text(json.dumps(records, indent=2), encoding="utf-8")
if __name__ == "__main__":
main()