DPDA-GA-AASIST / implementation-notes.md
korallll's picture
Wrapper code (speech-spoof-bench)
7c35645 verified
|
Raw History Blame Contribute Delete
3.48 kB

DPDA-GA-AASIST — implementation notes

Source

  • Code: github.com/ductuantruong/dpda_ga @ aab89614 (MIT, LICENSE.source), nets/aasist.py.
  • nets/aasist.py is byte-identical to TakHemlata/SSL_Anti-spoofing model.py, i.e. the same network as benchmarks/W2V2-AASIST/_net.py (same 674 state_dict keys, 317,837,834 params). _net.py here = W2V2-AASIST's port (merge_with_parent XLS-R build, args=None) plus one extra edit: self.model.train() in extract_feat removed (would re-enable XLS-R dropout).
  • xlsr2_300m.pt is a symlink to ../W2V2-AASIST/xlsr2_300m.pt (architecture only; all weights are overwritten by the checkpoint).

Checkpoint

  • HF tuantd/dpda_ga @ 531554e0a1c28d6a6ccf22a355281e3d3acefeb5, pcgrad/xlsr_aasist/best/best_{0..4}.pth (plain state_dicts, 674 keys: 654 float32, 20 int64 BN num_batches_tracked).
  • make_avg.py -> dpda_ga_aasist_avg5.pth (sha256 d794360c...6033b): reproduces main.py's averaging exactly — float32 running sum in order best_0 + best_1 + ... + best_4, then / 5; int64 buffers: int sum, true division, truncation on copy into the int64 buffer (what load_state_dict does in main.py). num_batches_tracked is unused at eval.

Wrapper decisions

  • Input: first 66,800 samples, shorter clips repeat-tiled (source utils.pad / data_utils cut=66800); no resampling, no normalisation, no RawBoost at test.
  • Score = logits[:, 1] (bonafide = class 1 in source read_metadata; main.py writes batch_out[:,1]).
  • .to(device) then .eval(); strict load (0 missing / 0 unexpected).
  • Batch independence: with cuDNN TF32 convs (PyTorch default) batched vs single differ by up to ~2e-4 (kernel selection per batch size); with TF32 off 1.4e-6, CPU 1.9e-6. Test checks both. The wrapper keeps the default (TF32 on), like W2V2-AASIST.

Batch sweep (sweep.py, 66,800-sample random input)

  • RTX 5060 Ti (idx 3), 2026-10-29: 1:27.7, 2:42.6, 4:47.6, 8:32.2, 16:32.0, 24:31.8, 32:31.2, 48:30.7 utt/s -> batch 4 (set in load() for "5060" cards).
  • RTX 4070 Ti SUPER (idx 2), 2026-10-29: 1:30.1, 2:58.0, 4:110.6, 8:115.0, 16:121.2, 24:123.1, 32:118.5, 48:120.1 utt/s -> batch 24 (class default).

Sanity

  • Full J-SPAW_LA (PyTorch, RTX 5060 Ti, bs 4): EER 13.00% (2397 trials, ~45 utt/s). For reference W2V2-AASIST (64,600 window) gets 26.17% on J-SPAW_LA.
  • In-the-Wild random 1,500-clip subset (shard 1, seed 0): EER 4.74% (paper full ITW: 5.42%).

TensorRT

trt_dpda_ga_aasist.py = XLSR-MamBo's TRT script with the entry/slug swapped (single XLS-R, 1.2 GB ONNX < 2 GB, no export patches beyond the fairseq pad_to_multiple swap). ONNX dpda-ga-aasist.onnx; per-card sidecar trt_dpda-ga-aasist.json.

  • RTX 5060 Ti (idx 3): FP16 build parity Spearman 0.99963 (< 0.9999 keep-FP16 threshold) -> FP32 (TF32 on). Build parity (64 ITW clips) Spearman 0.99945, max|Δ| 0.051. Sweep: best batch 4 at 120.5 utt/s (vs PyTorch 47.6). Full J-SPAW_LA: EER 12.96% vs PyTorch 13.00% (|ΔEER| 0.04), Spearman 0.99987, max|Δscore| 0.080 -> ACCEPTED. Runner ~112 utt/s. FP16 plan deleted.
  • RTX 4070 Ti SUPER (idx 2): FP16 build parity Spearman 0.99876 -> FP32 (TF32 on). Build parity Spearman 0.99940, max|Δ| 0.052. Sweep: best batch 32 at 172.2 utt/s (vs PyTorch 123.1). Full J-SPAW_LA: EER 13.00% vs PyTorch 13.00% (|ΔEER| 0.00), Spearman 0.99992, max|Δscore| 0.063 -> ACCEPTED. Runner ~125 utt/s. FP16 plan deleted.
  • J-SPAW_LA is to be submitted from the PyTorch scores (results_pt).