speaker-verification
audio
nemotron
tyger
experimental
ChristophSchuhmann's picture
Publish audited Robby source and completed Nemotron speaker-prediction experiments
b21cfae verified
Raw History Blame Contribute Delete
3.15 kB
"""Tiny artificial-data integration test, NOT evidence of speaker quality.
Tests the complete four-model train/checkpoint/validation/test/report workflow.
All temporary weights/data are removed automatically. No real source identities,
held-out utterances, live microphone data, or published quality metrics are used.
"""
import json,tempfile,unittest
from pathlib import Path
import numpy as np
import torch
from .train import run_four,Student,CONFIGS
class TrainingTests(unittest.TestCase):
def test_shapes_and_parameter_budget(self):
torch.set_num_threads(2)
for cfg in CONFIGS:
m=Student(cfg['architecture']);self.assertTrue(100000<=sum(p.numel() for p in m.parameters())<=1000000)
for context in (4,8,13,25):
e,l=m(torch.randn(2,context,1024),torch.randn(2,2,1024),torch.full((2,context),-30.))
self.assertEqual(tuple(e.shape),(2,192));self.assertTrue(torch.isfinite(e).all());self.assertEqual(tuple(l.shape),(2,3))
def test_full_workflow_on_artificial_data(self):
rng=np.random.default_rng(13);count=400
with tempfile.TemporaryDirectory(prefix='tyger-training-selfcheck-') as name:
root=Path(name);folder=root/'arrays';folder.mkdir()
prototypes=rng.normal(size=(500,192)).astype(np.float32);prototypes/=np.linalg.norm(prototypes,axis=-1,keepdims=True)
ids=np.r_[np.arange(200)%2,480+np.arange(100)%2,490+np.arange(100)%2].astype(np.int16)
activity=np.where(np.arange(count)%7==0,1,0).astype(np.uint8)
targets=prototypes[ids].copy();targets[activity!=0]=0;ids[activity!=0]=-1
data={'q':rng.integers(-127,128,(count,25,1024),dtype=np.int8),'scale':np.full((count,25,1),.01,np.float16),
'pool':rng.normal(size=(count,2,1024)).astype(np.float16),'energy':np.full((count,25),-25,np.float16),
'local_target':targets.astype(np.float16),'speaker':ids,'activity':activity,
'scenario':(np.arange(count)%5).astype(np.uint8),'emotion':(np.arange(count)%9).astype(np.uint8),'filled':np.ones(count,np.uint8)}
for key,value in data.items():np.save(folder/(key+'.npy'),value)
np.save(root/'prototypes.npy',prototypes)
(root/'sources_manifest.json').write_text(json.dumps([{'speaker_idx':i,'split':'train' if i<480 else 'validation' if i<490 else 'test'} for i in range(500)]))
(root/'splits.json').write_text(json.dumps({'train':list(range(200)),'validation':list(range(200,300)),'test':list(range(300,400))}))
events=[];run_four(root,lambda **fields:events.append(fields))
result=json.loads((root/'models/results.json').read_text());self.assertTrue(result['finished']);self.assertEqual(len(result['results']),4)
selected=[r for r in result['results'] if r.get('selected')];self.assertEqual(len(selected),1)
self.assertEqual(len(selected[0]['test_contexts']),5);self.assertIn('test_controls',selected[0]);self.assertTrue(events)
self.assertTrue((root/'models/report.html').exists())
if __name__=='__main__':unittest.main()