#!/usr/bin/env python3 """Deterministic LAION-DISCO audio tranche ingestion.""" from __future__ import annotations import argparse, array, hashlib, heapq, json, math, os, re, shutil, subprocess, sys, time, unicodedata, wave from collections import Counter from concurrent.futures import ThreadPoolExecutor from pathlib import Path from typing import Any ROOT=Path("/home/ubuntu/minimax-laion-corpus") REVISION="6e7bf3758a77301e46a715af894fefd79bb1da53" CANDIDATES=ROOT/"manifests/candidates.jsonl"; CANDIDATE_SUMMARY=ROOT/"manifests/candidates.summary.json" KNOWN_HASHES=ROOT/"manifests/known_user22_hashes.json"; RESULTS=ROOT/"manifests/ingest-results.jsonl" CANONICAL=ROOT/"canonical"; TMP=ROOT/"tmp"; YTDLP=ROOT/".venv/bin/yt-dlp" FFMPEG=shutil.which("ffmpeg") or "/usr/bin/ffmpeg"; FFPROBE=shutil.which("ffprobe") or "/usr/bin/ffprobe" ID_RE=re.compile(r"^[A-Za-z0-9_-]{11}$") def sha256_file(path:Path,chunk:int=8<<20)->str: h=hashlib.sha256() with path.open("rb") as f: while b:=f.read(chunk):h.update(b) return h.hexdigest() def norm(value:Any)->str: if value is None:return "" return " ".join(unicodedata.normalize("NFKC",str(value)).casefold().split()) def stable_rank(song_id:str)->str:return hashlib.sha256((REVISION+"\0"+song_id).encode()).hexdigest() def artist_keys(row:dict[str,Any])->list[str]: ids=sorted({"id:"+norm(x) for x in (row.get("artist_ids") or []) if norm(x)}) if ids:return ids names=sorted({"name:"+norm(x) for x in (row.get("artist_names") or []) if norm(x)}) return names or ["song:"+row["song_id"]] def album_key(row:dict[str,Any])->str: aid=norm(row.get("album_id")) if aid:return "id:"+aid name=norm(row.get("album_name")); artists=artist_keys(row) if name:return "name:"+name+"|artist:"+(artists[0] if artists else row["song_id"]) return "song:"+row["song_id"] def atomic_text(path:Path,text:str)->None: path.parent.mkdir(parents=True,exist_ok=True);tmp=path.with_suffix(path.suffix+".tmp");tmp.write_text(text,encoding="utf-8");os.replace(tmp,path) def write_json(path:Path,obj:Any)->None:atomic_text(path,json.dumps(obj,sort_keys=True,indent=2,ensure_ascii=False)+"\n") def read_jsonl(path:Path)->list[dict[str,Any]]: with path.open(encoding="utf-8") as f:return [json.loads(x) for x in f if x.strip()] def build_candidates(pool_size:int,target:int)->dict[str,Any]: import pyarrow.parquet as pq if pool_size= target") shards=sorted((ROOT/"metadata").glob("train-*-of-00005.parquet")) if len(shards)!=5:raise RuntimeError(f"expected five shards, got {len(shards)}") heap=[];seq=0;totals=Counter() cols=["song_id","title","artist_names","artist_ids","album_name","album_id","isExplicit","views","duration"] for shard_no,shard in enumerate(shards): pf=pq.ParquetFile(shard);totals["metadata_rows"]+=pf.metadata.num_rows for rg in range(pf.metadata.num_row_groups): for raw in pf.read_row_group(rg,columns=cols).to_pylist(): totals["rows_scanned"]+=1;sid=str(raw.get("song_id") or "").strip() try:duration=int(raw.get("duration")) except (TypeError,ValueError):totals["invalid_duration"]+=1;continue if duration<45 or duration>360:totals["duration_filtered"]+=1;continue if not ID_RE.fullmatch(sid):totals["invalid_song_id"]+=1;continue rank=stable_rank(sid) rec={"rank_sha256":rank,"song_id":sid,"url":"https://www.youtube.com/watch?v="+sid,"title":raw.get("title") or "", "artist_names":raw.get("artist_names") or [],"artist_ids":raw.get("artist_ids") or [], "album_name":raw.get("album_name") or "","album_id":raw.get("album_id") or "", "is_explicit":bool(raw.get("isExplicit")) if raw.get("isExplicit") is not None else None, "views":raw.get("views") or "","metadata_duration_seconds":duration,"source_shard":shard_no} item=(-int(rank,16),sid,seq,rec);seq+=1 if len(heap)heap[0][0]:heapq.heapreplace(heap,item) ranked=sorted((x[3] for x in heap),key=lambda x:(x["rank_sha256"],x["song_id"])) accepted=[];seen_song=set();seen_album=set();artist_count=Counter() for rec in ranked: sid=rec["song_id"] if sid in seen_song:totals["duplicate_song_id"]+=1;continue seen_song.add(sid);ak=album_key(rec);artists=artist_keys(rec) if ak in seen_album:totals["album_cap_rejected"]+=1;continue if any(artist_count[a]>=2 for a in artists):totals["artist_cap_rejected"]+=1;continue rec["album_cap_key"]=ak;rec["artist_cap_keys"]=artists;rec["candidate_index"]=len(accepted);accepted.append(rec);seen_album.add(ak) for a in artists:artist_count[a]+=1 if len(accepted)==target:break if len(accepted)!=target:raise RuntimeError(f"only {len(accepted)} candidates after caps; increase pool_size") atomic_text(CANDIDATES,"".join(json.dumps(x,sort_keys=True,ensure_ascii=False,separators=(",",":"))+"\n" for x in accepted)) summary={"schema_version":1,"dataset":"laion/LAION-DISCO-12M","revision":REVISION, "selection":{"rank":"ascending sha256(revision + NUL + song_id)","metadata_duration_seconds_inclusive":[45,360], "album_cap":1,"artist_cap":2,"cap_scope":"all listed artist IDs; normalized names when IDs absent", "pool_size":pool_size,"candidate_count":target,"intended_success_count":2000}, "counts":dict(totals),"candidate_manifest_sha256":sha256_file(CANDIDATES), "first_rank":accepted[0]["rank_sha256"],"last_rank":accepted[-1]["rank_sha256"]} write_json(CANDIDATE_SUMMARY,summary);return summary def validate_candidates()->dict[str,Any]: rows=read_jsonl(CANDIDATES) if len(rows)<2000:raise AssertionError("candidate pool cannot support 2,000 successes even with zero failures") if len({r["song_id"] for r in rows})!=len(rows):raise AssertionError("duplicate song_id") ordered=[(r["rank_sha256"],r["song_id"]) for r in rows] if ordered!=sorted(ordered):raise AssertionError("not rank sorted") albums=Counter(r["album_cap_key"] for r in rows) if max(albums.values(),default=0)>1:raise AssertionError("album cap violated") artists=Counter(a for r in rows for a in r["artist_cap_keys"]) if max(artists.values(),default=0)>2:raise AssertionError("artist cap violated") for i,r in enumerate(rows): if r["candidate_index"]!=i:raise AssertionError("candidate index mismatch") if stable_rank(r["song_id"])!=r["rank_sha256"]:raise AssertionError("rank mismatch") if not 45<=int(r["metadata_duration_seconds"])<=360:raise AssertionError("duration filter violated") if r["url"]!="https://www.youtube.com/watch?v="+r["song_id"]:raise AssertionError("URL mismatch") out={"status":"PASS","candidate_count":len(rows),"unique_albums":len(albums),"unique_artist_keys":len(artists), "max_artist_uses":max(artists.values(),default=0),"manifest_sha256":sha256_file(CANDIDATES),"bytes":CANDIDATES.stat().st_size} print(json.dumps(out,sort_keys=True));return out def probe(path:Path)->dict[str,Any]: cp=subprocess.run([FFPROBE,"-v","error","-select_streams","a:0","-show_entries", "stream=codec_name,codec_long_name,sample_fmt,sample_rate,channels,channel_layout,bits_per_sample,duration:format=duration,size", "-of","json",str(path)],check=True,capture_output=True,text=True,timeout=60) return json.loads(cp.stdout) def wav_stats(path:Path)->dict[str,Any]: pcm_hash=hashlib.sha256();n=ss=sall=peak=clipped=diff=ls=rs=0 with wave.open(str(path),"rb") as w: channels,rate,width,fc,ctype=w.getnchannels(),w.getframerate(),w.getsampwidth(),w.getnframes(),w.getcomptype() if (channels,rate,width,ctype)!=(2,44100,2,"NONE"):raise ValueError(f"not canonical PCM16 stereo 44.1k: {(channels,rate,width,ctype)}") while data:=w.readframes(65536): pcm_hash.update(data);vals=array.array("h");vals.frombytes(data) if sys.byteorder!="little":vals.byteswap() n+=len(vals) for i in range(0,len(vals),2): l,r=vals[i],vals[i+1];ls+=l;rs+=r;diff+=(l-r)*(l-r) for v in vals: av=abs(v);peak=max(peak,av);clipped+=int(av>=32767);sall+=v;ss+=v*v if n==0:raise ValueError("empty canonical audio") fc=n//2 return {"pcm_sha256":pcm_hash.hexdigest(),"sample_rate":44100,"channels":2,"sample_width_bytes":2,"frame_count":fc, "duration_seconds":fc/44100.0,"peak_linear":peak/32768.0,"rms_linear":math.sqrt(ss/n)/32768.0, "dc_linear":(sall/n)/32768.0,"left_dc_linear":(ls/fc)/32768.0,"right_dc_linear":(rs/fc)/32768.0, "stereo_difference_rms_linear":math.sqrt(diff/fc)/32768.0,"clipped_sample_fraction":clipped/n} def canonicalize(source:Path,dest:Path)->tuple[dict[str,Any],dict[str,Any]]: dest.parent.mkdir(parents=True,exist_ok=True) cp=subprocess.run([FFMPEG,"-nostdin","-hide_banner","-loglevel","error","-i",str(source),"-map","0:a:0","-vn","-sn","-dn", "-ac","2","-ar","44100","-c:a","pcm_s16le","-fflags","+bitexact","-flags:a","+bitexact","-map_metadata","-1","-y",str(dest)], capture_output=True,text=True,timeout=600) if cp.returncode:raise RuntimeError("ffmpeg: "+cp.stderr[-2000:]) return probe(dest),wav_stats(dest) def classify_download_error(error:str)->str: text=(error or "").casefold() systemic=("http error 429","too many requests","rate limit","sign in to confirm","not a bot","authentication required") if any(x in text for x in systemic):return "SYSTEMIC_RATE_LIMIT_OR_AUTH" unavailable=("video unavailable","not available","private video","private","removed","copyright removal","geo","country","http error 403","members-only") if any(x in text for x in unavailable):return "SKIP_UNAVAILABLE" return "DOWNLOAD_ERROR" def ytdlp_download(rec:dict[str,Any],attempts:int=3)->dict[str,Any]: idx,sid=rec["candidate_index"],rec["song_id"];work=TMP/f"{idx:05d}_{sid}" if work.exists():shutil.rmtree(work) work.mkdir(parents=True);output=work/"%(id)s.%(ext)s";error="" for attempt in range(attempts): cp=subprocess.run([str(YTDLP),"--no-playlist","--no-cache-dir","--no-mtime","--quiet","--no-warnings","--socket-timeout","30", "--retries","3","--fragment-retries","3","-f","bestaudio/best","-o",str(output),rec["url"]], capture_output=True,text=True,timeout=900) if cp.returncode==0:break error=(cp.stderr or cp.stdout)[-4000:] if attempt+1tuple[dict[str,str],dict[str,str]]: if not KNOWN_HASHES.exists():return {},{} obj=json.loads(KNOWN_HASHES.read_text(encoding="utf-8"));by_wav={};by_pcm={} for r in obj["files"]:by_wav[r["canonical_sha256"]]=r["source_label"];by_pcm[r["audio_stats"]["pcm_sha256"]]=r["source_label"] return by_wav,by_pcm def append_results(rows:list[dict[str,Any]])->None: RESULTS.parent.mkdir(parents=True,exist_ok=True) with RESULTS.open("a",encoding="utf-8") as f: for r in rows:f.write(json.dumps(r,sort_keys=True,ensure_ascii=False,separators=(",",":"))+"\n") f.flush();os.fsync(f.fileno()) def systemic_failure(row:dict[str,Any])->bool: if row.get("accepted"):return False text=(str(row.get("error") or "")+" "+str(row.get("stage") or "")).casefold() terms=("http error 429","too many requests","rate limit","sign in to confirm","not a bot","authentication required") return any(x in text for x in terms) def ingest(limit:int,workers:int,smoke:bool)->dict[str,Any]: if workers<1 or workers>4:raise ValueError("workers must be 1..4") candidates=read_jsonl(CANDIDATES);known_wav,known_pcm=load_known() history=read_jsonl(RESULTS) if RESULTS.exists() else [];attempted={x["song_id"] for x in history} accepted=[x for x in history if x.get("accepted")];seen_wav=dict(known_wav);seen_pcm=dict(known_pcm) for x in accepted: final=Path(x["canonical_path"]) if not final.is_file():raise RuntimeError(f"accepted file missing: {final}") seen_wav[x["canonical_sha256"]]=x["song_id"];seen_pcm[x["audio_stats"]["pcm_sha256"]]=x["song_id"] successes=len(accepted);cursor=0;start=time.monotonic();base_successes=successes;base_attempts=len(history) checkpoints=[x for x in (250,500,1000,1500,2000) if x<=limit] while successes=len(candidates):raise RuntimeError(f"candidate list exhausted at {successes}/{limit}") next_checkpoint=next((x for x in checkpoints if x>successes),limit) remaining=min(limit-successes,next_checkpoint-successes);batch=[] while cursor=8 or (len(tail)==20 and systemic_tail>=16 and not any(x.get("accepted") for x in tail)): stop={"status":"STOPPED","reason":"systemic_rate_limit_or_auth_failure","accepted_total":successes, "attempted_total":len(history),"consecutive_systemic_failures":consecutive,"systemic_failures_last_20":systemic_tail} write_json(ROOT/"manifests/tranche.stopped.json",stop);raise RuntimeError(json.dumps(stop,sort_keys=True)) if successes in checkpoints: elapsed=max(time.monotonic()-start,1e-9);new_successes=successes-base_successes;rate_s=new_successes/elapsed checkpoint={"event":"checkpoint","accepted_total":successes,"attempted_total":len(history), "new_accepted":new_successes,"new_attempts":len(history)-base_attempts, "acceptance_rate_total":successes/len(history),"accepted_per_minute":rate_s*60, "eta_seconds":(limit-successes)/rate_s if rate_s>0 else None, "failure_counts":dict(Counter(x.get("stage","unknown") for x in history if not x.get("accepted"))), "canonical_bytes":sum(p.stat().st_size for p in CANONICAL.glob("*.wav")),"elapsed_seconds":elapsed} with (ROOT/"logs/checkpoints.jsonl").open("a",encoding="utf-8") as f:f.write(json.dumps(checkpoint,sort_keys=True)+"\n") print(json.dumps(checkpoint,sort_keys=True),flush=True) allrows=read_jsonl(RESULTS) summary={"status":"PASS","mode":"smoke" if smoke else "tranche","target_successes":limit, "accepted_total":sum(bool(x.get("accepted")) for x in allrows),"attempted_total":len(allrows), "failure_counts":dict(Counter(x.get("stage","accepted") for x in allrows if not x.get("accepted"))), "results_sha256":sha256_file(RESULTS),"canonical_bytes":sum(p.stat().st_size for p in CANONICAL.glob("*.wav")), "known_hash_count":len(known_pcm),"workers":workers} write_json(ROOT/("manifests/smoke.summary.json" if smoke else "manifests/tranche.summary.json"),summary);return summary def build_known(inputs_manifest:Path)->dict[str,Any]: obj=json.loads(inputs_manifest.read_text(encoding="utf-8"));rows=[];work=TMP/"known_hashes" if work.exists():shutil.rmtree(work) work.mkdir(parents=True) try: for i,item in enumerate(obj["files"]): source=Path(item["path"]) if not source.is_file():raise FileNotFoundError(source) dest=work/f"{i:03d}.wav";canonical_probe,stats=canonicalize(source,dest) rows.append({"source_label":item["source_label"],"raw_sha256":sha256_file(source),"canonical_sha256":sha256_file(dest), "canonical_probe":canonical_probe,"audio_stats":stats}) finally:shutil.rmtree(work,ignore_errors=True) if len({x["source_label"] for x in rows})!=len(rows):raise AssertionError("duplicate source label") out={"schema_version":1,"pipeline":"ffmpeg -ac 2 -ar 44100 -c:a pcm_s16le; metadata stripped; bitexact flags","file_count":len(rows),"files":rows} write_json(KNOWN_HASHES,out);out["manifest_sha256"]=sha256_file(KNOWN_HASHES);return out def main()->None: ap=argparse.ArgumentParser();sub=ap.add_subparsers(dest="cmd",required=True) b=sub.add_parser("build-candidates");b.add_argument("--pool-size",type=int,default=250000);b.add_argument("--target",type=int,default=20000) sub.add_parser("validate-candidates");k=sub.add_parser("build-known-hashes");k.add_argument("inputs_manifest",type=Path) s=sub.add_parser("smoke");s.add_argument("--successes",type=int,default=3) r=sub.add_parser("run");r.add_argument("--successes",type=int,default=2000);r.add_argument("--workers",type=int,default=4) a=ap.parse_args() if a.cmd=="build-candidates":print(json.dumps(build_candidates(a.pool_size,a.target),indent=2,sort_keys=True)) elif a.cmd=="validate-candidates":validate_candidates() elif a.cmd=="build-known-hashes":print(json.dumps(build_known(a.inputs_manifest),indent=2,sort_keys=True)) elif a.cmd=="smoke":print(json.dumps(ingest(a.successes,min(a.successes,3),True),indent=2,sort_keys=True)) elif a.cmd=="run":print(json.dumps(ingest(a.successes,a.workers,False),indent=2,sort_keys=True)) if __name__=="__main__":main()