huseinzolkepliscicom commited on
Commit
4aa51fc
·
verified ·
1 Parent(s): 40c5c7c

Add self-contained inference CLI

Browse files
Files changed (1) hide show
  1. infer_widecodec.py +72 -0
infer_widecodec.py ADDED
@@ -0,0 +1,72 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """WideCodec — self-contained inference (44.1 kHz neural codec, depth-20 decoder).
3
+
4
+ Encode -> decode any audio to a 44.1 kHz reconstruction. The encoder ingests mono
5
+ 16 kHz; the frozen FSQ codebook (single codebook, 50 tokens/s, ~0.8 kbps) yields the
6
+ code stream; the depth-20 decoder renders it back to 44.1 kHz.
7
+
8
+ This script + the bundled `neucodec/` package are ALL you need — no other source
9
+ repo. Weights (`pytorch_model.bin`) are pulled from the HF model repo on first run.
10
+
11
+ pip install torch transformers huggingface_hub local-attention einops librosa soundfile
12
+ huggingface-cli login # if the repo is private (or export HF_TOKEN=hf_...)
13
+ python infer_widecodec.py --input my.wav --out-dir out
14
+ python infer_widecodec.py --input folder/ --out-dir out # batch a directory
15
+ """
16
+ import argparse
17
+ import glob
18
+ import os
19
+ import sys
20
+
21
+ # make the bundled `neucodec/` package importable regardless of CWD
22
+ sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
23
+
24
+ os.environ.setdefault("HF_HUB_DISABLE_XET", "1") # plain HTTPS: Xet can hang on some networks
25
+
26
+ import librosa
27
+ import soundfile as sf
28
+ import torch
29
+
30
+ from neucodec import NeuCodec
31
+
32
+ AUDIO_EXTS = (".wav", ".mp3", ".flac", ".m4a", ".ogg", ".opus")
33
+
34
+
35
+ def main():
36
+ ap = argparse.ArgumentParser()
37
+ ap.add_argument("--input", required=True, help="audio file OR a directory of audio")
38
+ ap.add_argument("--out-dir", default="out")
39
+ ap.add_argument("--repo", default="Scicom-intl/WideCodec")
40
+ ap.add_argument("--depth", type=int, default=20, help="decoder depth (WideCodec=20)")
41
+ ap.add_argument("--device", default="cuda" if torch.cuda.is_available() else "cpu")
42
+ a = ap.parse_args()
43
+
44
+ os.makedirs(a.out_dir, exist_ok=True)
45
+ print(f"[infer] loading {a.repo} (decoder_depth={a.depth}) on {a.device} …")
46
+ model = NeuCodec._from_pretrained(
47
+ model_id=a.repo, decoder_depth=a.depth, token=os.environ.get("HF_TOKEN")
48
+ ).eval().to(a.device)
49
+ sr_out = model.sample_rate
50
+ print(f"[infer] output sample_rate = {sr_out}")
51
+
52
+ if os.path.isdir(a.input):
53
+ files = sorted(f for f in glob.glob(os.path.join(a.input, "*"))
54
+ if f.lower().endswith(AUDIO_EXTS))
55
+ else:
56
+ files = [a.input]
57
+ print(f"[infer] {len(files)} file(s)")
58
+
59
+ for f in files:
60
+ wav16, _ = librosa.load(f, sr=16000, mono=True) # frozen encoder wants 16 kHz mono
61
+ x = torch.from_numpy(wav16).float().view(1, 1, -1).to(a.device)
62
+ with torch.no_grad():
63
+ codes = model.encode_code(x)
64
+ wav = model.decode_code(codes).squeeze().detach().cpu().float().numpy()
65
+ base = os.path.splitext(os.path.basename(f))[0]
66
+ out = os.path.join(a.out_dir, f"{base}_44k.wav")
67
+ sf.write(out, wav, sr_out)
68
+ print(f"[infer] {f} -> {out} ({len(wav) / sr_out:.2f}s @ {sr_out} Hz)")
69
+
70
+
71
+ if __name__ == "__main__":
72
+ main()