File size: 3,482 Bytes
7c35645 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | # 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).
|