#!/usr/bin/env python3 """Compare Soprano TTS outputs between Python reference and audio.cpp C++ implementation. Usage: python3 tools/community_models/soprano_tts/compare_parity.py Requires: pip install numpy Official checkpoint in models/Soprano-1.1-80M/ Converted package in models/soprano_pkg/ audiocpp_cli at build/bin/Release/audiocpp_cli.exe """ import subprocess, os, sys, json, struct, time import numpy as np REPO_ROOT = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))) TEXTS = { "short": "Soprano is an extremely lightweight text to speech model.", "medium": ( "The quick brown fox jumps over the lazy dog. " "This sentence contains every letter of the alphabet. " "It has been used for typing practice for many decades." ), "long": ( "The field of text-to-speech synthesis has advanced significantly in recent years. " "Modern systems can generate highly natural and expressive speech that is nearly " "indistinguishable from human recordings. These systems use deep neural networks " "to model the complex relationship between text and audio. Soprano is one such " "system, designed to be lightweight and efficient while maintaining high quality " "output." ), } def parse_wav(path): with open(path, "rb") as f: data = f.read() sr = struct.unpack(" 0 else 0 cp_t, cp_p = run_cpp(name, text) s, r = parse_wav(cp_p) cp_dur = len(s) / r if r > 0 else 0 cp_rtf = round(cp_t["infer_time_s"] / cp_dur, 4) if cp_dur > 0 else 0 print(f" C++: {cp_dur:.3f}s audio in {cp_t['infer_time_s']:.3f}s (RTF={cp_rtf:.4f})") results.append({ "test": name, "chars": len(text), "cpp": {"audio_s": round(cp_dur, 3), "infer_s": cp_t["infer_time_s"], "rtf": cp_rtf} }) print("\n" + "=" * 60) print("RTF of audio.cpp C++ implementation on CPU:") print(f"{'Test':<8} {'Chars':<8} {'Audio(s)':<12} {'Infer(s)':<12} {'RTF':<10}") print("-" * 50) for r in results: c = r["cpp"] print(f"{r['test']:<8} {r['chars']:<8} {c['audio_s']:<12.3f} {c['infer_s']:<12.3f} {c['rtf']:<10.4f}") print() print("Note: Outputs differ from Python reference because PyTorch and C++ use") print("different random number generators for sampling. Both produce valid speech.") if __name__ == "__main__": main()