Buckets:
| """Full-corpus MERT-v2-FullSong features, layers KEEP only, 25 Hz, fp16 [len(KEEP),T,1024]. Batches all 30 s chunks of a track in one forward.""" | |
| import glob, os, sys, time, json, numpy as np, torch, soundfile as sf | |
| from scipy.signal import resample_poly | |
| from math import gcd | |
| from transformers import AutoModel, AutoFeatureExtractor | |
| ROOT="/workspace/yue2-corpus/tracks"; OUT="/workspace/tok/full/feats"; os.makedirs(OUT, exist_ok=True) | |
| NAME="m-a-p/MERT-v2-FullSong"; KEEP=[1,8,14,20] | |
| LIMIT=int(sys.argv[1]) if len(sys.argv)>1 else 10**9 | |
| tracks=[d for d in sorted(glob.glob(f"{ROOT}/*")) if os.path.exists(f"{d}/semantic.npy") and os.path.exists(f"{d}/item.json")][:LIMIT] | |
| t0=time.time() | |
| proc=AutoFeatureExtractor.from_pretrained(NAME, trust_remote_code=True) | |
| model=AutoModel.from_pretrained(NAME, trust_remote_code=True).cuda().eval() | |
| sr_t=getattr(proc,"sampling_rate",24000); CH=sr_t*30 | |
| print(f"loaded in {time.time()-t0:.0f}s | {len(tracks)} tracks | keep layers {KEEP}", flush=True) | |
| done=0 | |
| for i,d in enumerate(tracks): | |
| pid=os.path.basename(d); out=f"{OUT}/{pid}.npy" | |
| if os.path.exists(out): continue | |
| a,sr=sf.read(f"{d}/audio.flac", dtype="float32"); a=a.mean(1) if a.ndim==2 else a | |
| g=gcd(sr,sr_t); a=resample_poly(a, sr_t//g, sr//g).astype(np.float32) | |
| chunks=[a[s:s+CH] for s in range(0,len(a),CH)]; chunks=[c for c in chunks if len(c)>=sr_t] | |
| full=[c for c in chunks if len(c)==CH]; tail=[c for c in chunks if len(c)<CH] | |
| feats=[] | |
| with torch.no_grad(), torch.autocast("cuda",dtype=torch.bfloat16): | |
| for group in ([full] if full else [])+[[c] for c in tail]: | |
| inp=proc(group, sampling_rate=sr_t, return_tensors="pt") | |
| inp={k:v.cuda() for k,v in inp.items()} | |
| o=model(**inp, output_hidden_states=True) | |
| hs=torch.stack([o.hidden_states[k] for k in KEEP]) # [K,B,T,C] | |
| K,B,T,C=hs.shape; feats.append(hs.reshape(K,B*T,C)) # chunks are in time order | |
| Hh=torch.cat(feats,1).float() | |
| T25=int(round(len(a)/sr_t*25)) | |
| H25=torch.nn.functional.interpolate(Hh.permute(0,2,1), size=T25, mode="linear", align_corners=False).permute(0,2,1) | |
| np.save(out, H25.half().cpu().numpy()); done+=1 | |
| if done%25==0: print(f"{i+1}/{len(tracks)} {pid} frames25={T25} {time.time()-t0:.0f}s", flush=True) | |
| json.dump({"keep":KEEP}, open(f"{OUT}/../info.json","w")); print("EXTRACT DONE", done, f"{time.time()-t0:.0f}s", flush=True) | |
Xet Storage Details
- Size:
- 2.41 kB
- Xet hash:
- 416ef4f2086b63bd6b3d50b1f827b5dc1a0c8e9e65e3513dd1eb4c74d8eae641
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.