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
74 lines
3.1 KiB
Python
74 lines
3.1 KiB
Python
"""Retain a bounded separation run and optionally compare PCM16 stems.
|
|
|
|
Run baseline and candidate sequentially with the same model and input. A timeout
|
|
is reported as a lower bound, never as a measured completed baseline duration.
|
|
"""
|
|
import argparse
|
|
import array
|
|
import hashlib
|
|
import json
|
|
import math
|
|
import os
|
|
from pathlib import Path
|
|
import subprocess
|
|
import sys
|
|
import time
|
|
import wave
|
|
|
|
|
|
def digest(path):
|
|
return hashlib.sha256(Path(path).read_bytes()).hexdigest()
|
|
|
|
|
|
def pcm(path):
|
|
with wave.open(str(path)) as stream:
|
|
if stream.getsampwidth() != 2:
|
|
raise ValueError('Comparison expects PCM16 WAV output')
|
|
signature = (stream.getnchannels(), stream.getframerate(), stream.getnframes())
|
|
data = array.array('h', stream.readframes(stream.getnframes()))
|
|
if sys.byteorder != 'little':
|
|
data.byteswap()
|
|
return signature, data
|
|
|
|
|
|
def main():
|
|
parser = argparse.ArgumentParser(description=__doc__)
|
|
for name in ('binary', 'model', 'audio', 'out'):
|
|
parser.add_argument('--' + name, required=True, type=Path)
|
|
parser.add_argument('--reference', type=Path)
|
|
parser.add_argument('--timeout', type=float, default=180)
|
|
args = parser.parse_args()
|
|
args.out.mkdir(parents=True, exist_ok=False)
|
|
command = [str(args.binary.resolve()), '--family', 'bs_roformer', '--task', 'sep',
|
|
'--backend', 'hip', '--model', str(args.model.resolve()),
|
|
'--audio', str(args.audio.resolve()), '--out-dir', str(args.out.resolve()), '--log']
|
|
result = dict(command=command, binary_sha256=digest(args.binary), input_sha256=digest(args.audio))
|
|
result['environment'] = {key: value for key, value in os.environ.items()
|
|
if key.startswith(('GGML_', 'HIP_', 'ROCBLAS_', 'HIPBLASLT_'))}
|
|
started = time.monotonic()
|
|
with (args.out / 'run.log').open('w') as log:
|
|
try:
|
|
result['returncode'] = subprocess.run(command, stdout=log, stderr=subprocess.STDOUT,
|
|
timeout=args.timeout).returncode
|
|
except subprocess.TimeoutExpired:
|
|
result['timed_out'] = True
|
|
result['seconds'] = time.monotonic() - started
|
|
if args.reference and result.get('returncode') == 0:
|
|
result['comparison'] = {}
|
|
for stem in ('vocals', 'instrumental'):
|
|
shape, candidate = pcm(args.out / (stem + '.wav'))
|
|
ref_shape, reference = pcm(args.reference / (stem + '.wav'))
|
|
if shape != ref_shape:
|
|
raise ValueError('Reference and candidate WAV dimensions differ')
|
|
errors = [int(a) - int(b) for a, b in zip(candidate, reference)]
|
|
result['comparison'][stem] = dict(
|
|
identical=not any(errors),
|
|
max_abs_pcm16_steps=max(map(abs, errors), default=0),
|
|
rms_difference=math.sqrt(sum(e * e for e in errors) / max(1, len(errors))) / 32768)
|
|
(args.out / 'result.json').write_text(json.dumps(result, indent=2) + '\n')
|
|
print(json.dumps(result, indent=2))
|
|
return 0 if result.get('returncode') == 0 else 1
|
|
|
|
|
|
if __name__ == '__main__':
|
|
raise SystemExit(main())
|