Download implementation-notes.md from SpeechAntiSpoofingBenchmarks/LaST-Net: direct link, hf CLI and curl.
- Browser
- Download file 6.08 kB
-
https://huggingface.co/SpeechAntiSpoofingBenchmarks/LaST-Net/resolve/main/implementation-notes.md
- Command line
-
hf download hf://SpeechAntiSpoofingBenchmarks/LaST-Net/implementation-notes.md
-
curl -L -o implementation-notes.md https://huggingface.co/SpeechAntiSpoofingBenchmarks/LaST-Net/resolve/main/implementation-notes.md
LaST-Net β implementation notes
Plan: speech-spoof-bench/docs/plans/2026-11-09-thirteen-model-batch-arena-submission.md (model #3).
Source
- Code: github.com/JunXue-tech/LaST-Net @
3838f0c7108313f771f6c1e208ac8f1e3bde60b0(MIT), clone atbenchmarks/_ckpt_dl/gh__JunXue-tech__LaST-Net/:model.py(LaSTNet),infer.py(single-file scoring),eval.py(dataset eval +load_model),load_dataset.py(read_audio,crop_or_repeat). - Weights: HF JunXueTech/LaST-Net @
7b18ff0abff078c60745aaaaf5165e3f9542fa1bbest.pt(3.8 GB, sha2568fee6178d19b398fac9e1b1bfcf13720c4eb5ff722b5b52e4bc698e0de0fa28b): epoch 52, keys model / optimizer / epoch / global_step / best_mean_dev_eer (1.383) / args / rng_states / initialization (xlsr_only) / pretrained_path / architecture (LCF24_LengthSelectiveKernelResidualBiFPN_v18b) / training_view / consistency. No license β linked. - Extraction (
extract_state.py, run once withpython -I): plainweights_only=Truefails on the numpy RNG states (numpy.dtype[uint32]); loaded withweights_only=True+torch.serialization.add_safe_globalslimited tonumpy.core.multiarray._reconstruct,numpy.ndarray,numpy.dtype,_codecs.encodeand the uint32/float64/int64/ float32 dtype classes (the pickle's only globals, checked withpickletoolsfirst).ck["model"](522 fp32 tensors) β_ckpt_dl/JunXueTech__LaST-Net/last_net_model.safetensors(sha2563ec3ff415654931474fe0949b5ed1030a84b8c0b2ee28a4fce37f238e952b264, metadata: train args), symlinked here. Train args: router_temperature 0.8, uniform_floor 0.05, layer_dropout 0.1 (= constructor defaults). - XLS-R architecture:
xlsr2_300m_model_cfg.jsoncopied from DeepFense-CodecFake-W2V2-MLP (model cfg of fairseqxlsr2_300m.pt);Wav2Vec2Model.build_model(merge_with_parent(...))with fairseq 0.12.2 β the 3.6 GB base pickle is not needed (all its tensors are replaced by best.pt anyway, as the authors' README says). - Paper: none found (web search "LaST-Net Length-Aware Layer and Scale-Adaptive Temporal Network", 2026-11-09) β unpublished tier.
Wrapper (last_net.py:LaSTNetModel, _net.py:LaSTNet)
_net.py= model.py verbatim except: SSLModel built from the vendored cfg; forward returns logits only;nn.init.zeros_calls dropped. extract_feat =model(wav, mask=False, features_only=True, layer=23)["layer_results"].- Length-aware input: the model takes
available_seconds(B,) besides the waveform;duration_featuresbuilds [requested/6, log1p(requested)/log 7, available/requested] with requested = 4.0. As infer.py/eval.py: available = min(len, 64000)/16000 (so a repeated short clip is scored differently from the same tiled audio given as a full 4 s clip β unit-tested). - Window: authors' 4 s =
seconds * 16000= 64000 samples (not 64600). Prefix crop; shorter βnp.tileto ceil(64000/len) copies, cropped. No amplitude normalisation, no resampling. Empty clip β zeros, available 0 (clamped to 1 ms in the model; the source raises instead). - Score =
log_softmax(logits)[:, 1](=bonafide_log_score; labels spoof 0 / bona fide 1) β higher = bona fide. - FP32, TF32 off for cuDNN + matmul (authors' eval.py turns TF32 matmuls on; strict FP32 keeps scores batch-independent).
- Strict load: all 522 tensors, 0 missing / 0 unexpected. Inference-path check (backward on a forward pass): exactly
10 tensors get no gradient =
UNUSED_ON_FORWARD(mask_emb; quantizer.vars / weight_proj.; project_q.; final_proj.; encoder.layer_norm. β skipped by fairseq whenlayeris given). Asserted in the tests. - Params: 318,910,608 loaded; 316,955,664 on the inference path β meta 316.955664.
Checks
test_last_net.py: crop/repeat + available seconds, empty clip, duration-feature formula, strict load, eval mode + param counts, unused set == allow-list, available-duration effect, batch == single (atol 1e-4), determinism, bona fide > spoof on J-SPAW clips. 11 passed (idx 3).- Source parity (
source_parity.py <clone>βlogs_source_parity.txt): authors'model.LaSTNet(fairseq loader patched to the vendored cfg; same safetensors tensors, strict=True) +read_audio/crop_or_repeat+ the infer.py loop per clip, vs the wrapper batched, on 16 J-SPAW_LA clips (8 bona fide / 8 spoof) + a 20000, a 5000 and a 102912-sample clip: max |Ξ| 1.57e-5 at 4 s, 1.78e-5 at 6 s (authors' default). (Whole-utterance "window off" is not an authors' mode: infer/eval only accept 1β6 s.) - Batch sweep (
sweep.py, 64000 samples, FP32): RTX 4070 Ti SUPER (idx 2) 117.8 utt/s @24 (plateau 16β64, 118.2 @32) βbatch_size = 24; RTX 5060 Ti (idx 3) 41.9 utt/s @4, ~32 at bs β₯ 8 β 4. - Full J-SPAW_LA, PyTorch, RTX 5060 Ti idx 3 (
run_pt.sh): EER 14.500% (2397 trials, 0 skipped). Sane.
TensorRT (trt_last_net.py, sidecar trt_last-net.json)
Two-input engine (wav (B,64000) + available (B,)), FP32 with TF32 cleared, profile 1/16/32. Export-only patches:
fairseq pad_to_multiple β static pad (199 β 200 frames + mask, as eager); _net.duration_features β a trace-safe copy
(full_like(available, T/16000) instead of new_full((len(wav),)), which would bake the batch size). Build parity on
64 InTheWild clips + 3 truncated (repeat-path) clips.
| card | precision | best batch | utt/s (sweep) | build Spearman / max Ξ | J-SPAW EER | J-SPAW Spearman vs PT / max Ξ |
|---|---|---|---|---|---|---|
| RTX 4070 Ti SUPER (idx 2) | FP32 (no TF32) | 16 | 135.6 | 1.0 / 6.1e-5 | 14.500 (=PT) | 1.000000 / 2.7e-4 |
| RTX 5060 Ti (idx 3) | FP32 (no TF32) | 16 | 88.8 | 1.0 / 3.7e-5 | 14.500 (=PT) | 1.000000 / 3.5e-4 |
Both cards pass (|ΞEER| = 0 β€ 0.25, Spearman β₯ 0.999) β TRT accepted on both card types. Engines
engine_<GPU>_fp32_b1-16-32.plan (gitignored); only the 4070 ONNX is kept. TRT runs in results_trt2/, results_trt3/
(cmp_scores.py, logs_trt_done.txt). FP16 not tried (plan: FP32).
Scripts: run_pt.sh, run_trt_export.sh <gpu>, run_trt_jspaw.sh <gpu>.