"""FocalCodec 12.5 Hz weight-quantization lab (Gradio / ZeroGPU).""" import hashlib import time import gradio as gr import numpy as np import soundfile as sf import spaces # patches torch.cuda for ZeroGPU; must stay above `import torch` import torch from scipy.signal import resample_poly import core import int8nn from core import QUANT_LEVELS MODEL_REPO = "lucadellalib/focalcodec_12_5hz" HUB_REPO = "lucadellalib/focalcodec" LS_REPO = "cantabile-kwok/lscodec_25hz" LS_PREFIX = "lscodec-" MAX_SECONDS = 20 HEADERS = ["Level", "SI-SDR (dB)", "STOI", "LSD (dB)", "Model size (MB)", "Bitrate (kbps)", "RTF"] DATATYPES = ["str", "number", "number", "number", "number", "number", "number"] EXAMPLES = [ ["assets/251-118436-0003.wav"], ["assets/p226_006.wav"], ["assets/5_1812_20170628135856.wav"], ] LS_BITRATE_KBPS = 25 * 10 / 1000 # 25 tokens/s x 10-bit codebook codec = torch.hub.load(HUB_REPO, "focalcodec", config=MODEL_REPO, trust_repo=True) codec.eval().requires_grad_(False) codec.to("cuda") BASE_STATE = {k: v.detach().cpu().clone() for k, v in codec.state_dict().items()} SIZES = {level: core.model_size_mb(BASE_STATE, level) for level in QUANT_LEVELS} NATIVE_LEVEL = "int8-native" try: # fresh instance, not deepcopy: a second copy of the live (CUDA) codec is not deep-copyable there codec_i8 = int8nn.apply_int8( torch.hub.load(HUB_REPO, "focalcodec", config=MODEL_REPO, trust_repo=True).eval().requires_grad_(False).cuda(), BASE_STATE, ) except Exception as exc: # noqa: BLE001 a runtime quirk must not take the demo down codec_i8 = None print(f"[int8] native FocalCodec disabled: {exc!r}") NATIVE_LEVELS = (NATIVE_LEVEL,) if codec_i8 is not None else () if codec_i8 is not None: SIZES[NATIVE_LEVEL] = core.model_size_mb(BASE_STATE, "int8") # + fp32 scales, <1% overhead FOCAL_LEVELS = QUANT_LEVELS + NATIVE_LEVELS # focal rows; LS natives stay out (LS_PREFIX) SAMPLE_RATE = codec.sample_rate_input assert codec.sample_rate_output == SAMPLE_RATE, "demo assumes a 16/16 kHz codec" def _boot_lscodec() -> dict | None: """LSCodec-25 Hz baseline: WavLM-Large (first 6 layers) prompt encoder + encoder/vocoder.""" from scipy import signal if not hasattr(signal, "kaiser"): # their pqmf.py imports scipy<1.15's top-level kaiser from scipy.signal.windows import kaiser signal.kaiser = kaiser from pathlib import Path import yaml from huggingface_hub import hf_hub_download from transformers import WavLMModel from lscodec.utils import load_model, load_vocoder files = { name: hf_hub_download(LS_REPO, name, repo_type="model") for name in ( "encoder_config.yml", "vocoder_config.yml", "codebook.npy", "lscodec_encoder.pt", "lscodec_vocoder.pt", ) } encoder_config = yaml.safe_load(Path(files["encoder_config.yml"]).read_text()) vocoder_config = yaml.safe_load(Path(files["vocoder_config.yml"]).read_text()) encoder_config["pretrain_codebook"] = files["codebook.npy"] vocoder_config["vq_codebook"] = files["codebook.npy"] enc = load_model(encoder_config, files["lscodec_encoder.pt"]).eval().requires_grad_(False) dec = load_vocoder(vocoder_config, files["lscodec_vocoder.pt"]).eval().requires_grad_(False) codebook = torch.as_tensor(np.load(files["codebook.npy"], allow_pickle=True)) books = torch.nn.ModuleList( [torch.nn.Embedding.from_pretrained(b, freeze=True) for b in (codebook if codebook.ndim == 3 else [codebook])] ) wavlm = WavLMModel.from_pretrained("microsoft/wavlm-large").eval().requires_grad_(False) wavlm.encoder.layers = wavlm.encoder.layers[:6] # prompt features come from layers 0..5 for model in (enc, dec, books, wavlm): model.cuda() # ZeroGPU wants module-level cuda placement (docs: model loading) states = { key: {k: v.detach().cpu().clone() for k, v in mod.state_dict().items()} for key, mod in (("enc", enc), ("dec", dec), ("books", books)) } out = { "enc": enc, "dec": dec, "books": books, "wavlm": wavlm, "enc_state": states["enc"], "dec_state": states["dec"], "books_state": states["books"], "repeat": bool(vocoder_config.get("repeat_input_tokens")), "out_sr": int(vocoder_config["sampling_rate"]), } for key, mod in (("enc", enc), ("dec", dec), ("books", books)): out[key + "_fp"] = mod # fp32 module for state swaps; `_load_lscodec` restores it out[key + "_i8"] = None try: # fresh instances, not deepcopy: legacy weight-normed modules hold non-leaf tensors fresh_enc = load_model(encoder_config, files["lscodec_encoder.pt"]).eval().requires_grad_(False) fresh_dec = load_vocoder(vocoder_config, files["lscodec_vocoder.pt"]).eval().requires_grad_(False) fresh_books = torch.nn.ModuleList( [torch.nn.Embedding.from_pretrained(b, freeze=True) for b in (codebook if codebook.ndim == 3 else [codebook])] ) out["enc_i8"] = int8nn.apply_int8(fresh_enc.cuda(), states["enc"]) out["dec_i8"] = int8nn.apply_int8(fresh_dec.cuda(), states["dec"]) out["books_i8"] = int8nn.apply_int8(fresh_books.cuda(), states["books"]) except Exception as exc: # noqa: BLE001 native LSCodec is optional, all-or-nothing out["enc_i8"] = out["dec_i8"] = out["books_i8"] = None print(f"[int8] native LSCodec disabled: {exc!r}") return out try: LS = _boot_lscodec() except Exception as exc: # noqa: BLE001 a third-party dep breaking must not take the demo down LS = None print(f"[lscodec] baseline disabled: {exc!r}") LS_LEVELS = tuple(LS_PREFIX + level for level in QUANT_LEVELS) if LS is not None else () LS_NATIVE_LEVELS = ( (LS_PREFIX + NATIVE_LEVEL,) if LS is not None and all(LS[key + "_i8"] is not None for key in ("enc", "dec", "books")) else () ) BENCH_LEVELS = QUANT_LEVELS + LS_LEVELS + NATIVE_LEVELS + LS_NATIVE_LEVELS def _lscodec_prompt(audio: torch.Tensor) -> torch.Tensor: """WavLM-Large layers 0..5 features: a function of the input only, so compute it once per clip.""" with torch.inference_mode(): prompt_input = torch.nn.functional.layer_norm(audio, audio.shape) # fairseq WavLM cfg.normalize return LS["wavlm"](prompt_input, output_hidden_states=True).hidden_states[6] def _lscodec_decode(prompt: torch.Tensor, audio: torch.Tensor, sr: int) -> np.ndarray: """Reconstruct `audio` with LSCodec at the currently loaded weight level, resampled back to `sr`.""" with torch.inference_mode(): _, _, index = LS["enc"].encode(audio.unsqueeze(0)) if LS["repeat"]: index = index.repeat_interleave(2, dim=0) vqvec = torch.cat([book(index[:, i]) for i, book in enumerate(LS["books"])], dim=-1).unsqueeze(0) rec = LS["dec"].inference(vqvec, prompt)[-1].view(-1).float().cpu().numpy() out_sr = LS["out_sr"] if out_sr != sr: g = np.gcd(out_sr, sr) rec = resample_poly(rec, sr // g, out_sr // g).astype(np.float32) return rec def _load_lscodec(level: str) -> None: """Point the LSCodec encoder, vocoder and codebook at `level` (QUANT_LEVELS entry or int8-native).""" if level == NATIVE_LEVEL: for key in ("enc", "dec", "books"): LS[key] = LS[key + "_i8"] return for key in ("enc", "dec", "books"): if LS[key] is not LS[key + "_fp"]: # a previous native swap is active -> restore fp32 module LS[key] = LS[key + "_fp"] state = LS[key + "_state"] LS[key].load_state_dict(state if level == "fp32" else core.quantize_state(state, level)) def _lscodec_size_mb(level: str) -> float: """Stored size of the codec at `level`; the WavLM prompt encoder is excluded (see the tab note).""" grid = "int8" if level == NATIVE_LEVEL else level # native twins share int8's storage grid return sum(core.model_size_mb(LS[key + "_state"], grid) for key in ("enc", "dec", "books")) def _estimate_duration(audio_path: str, levels: tuple) -> float: try: seconds = min(sf.info(audio_path).duration, MAX_SECONDS) except Exception: # noqa: BLE001 unreadable input falls back to the full cap seconds = float(MAX_SECONDS) native_slack = 2.5 * sum(1 for level in levels if level.endswith("native")) # W8A8 rows run heavier # ZeroGPU rejects a request above the visitor's tier cap, so never ask for more than 60 s. return min(60.0, 3.0 + len(levels) + 1.5 * seconds + native_slack) @spaces.GPU(duration=_estimate_duration) def _encode_decode(audio_path: str, levels: tuple) -> dict: """Reconstruct `audio_path` once per weight-quantization level, scoring each result.""" ref, sr = core.load_audio(audio_path, SAMPLE_RATE, MAX_SECONDS) seconds = len(ref) / sr rows, reconstructed = [], {} focal_levels = tuple(level for level in levels if level in FOCAL_LEVELS) ls_levels = tuple(level for level in levels if level.startswith(LS_PREFIX)) if focal_levels: sig = torch.from_numpy(ref).unsqueeze(0).cuda() with torch.inference_mode(): # untimed warmup so the first row's RTF isn't inflated codec.sig_to_sig(sig) if NATIVE_LEVEL in focal_levels: codec_i8.sig_to_sig(sig) for level in focal_levels: model = codec_i8 if level == NATIVE_LEVEL else codec if level != NATIVE_LEVEL: codec.load_state_dict(BASE_STATE if level == "fp32" else core.quantize_state(BASE_STATE, level)) torch.cuda.synchronize() start = time.perf_counter() with torch.inference_mode(): rec = model.sig_to_sig(sig).squeeze(0).float().cpu().numpy() torch.cuda.synchronize() rtf = (time.perf_counter() - start) / seconds rows.append(core.evaluate(ref, rec, sr, rtf, SIZES[level], level)) reconstructed[level] = (sr, rec) codec.load_state_dict(BASE_STATE) if ls_levels: audio = torch.from_numpy(ref).float().view(1, -1).cuda() with torch.inference_mode(): # one prompt for every level, plus an untimed warmup pass prompt = _lscodec_prompt(audio) _lscodec_decode(prompt, audio, sr) if any(level[len(LS_PREFIX) :] == NATIVE_LEVEL for level in ls_levels): _load_lscodec(NATIVE_LEVEL) _lscodec_decode(prompt, audio, sr) _load_lscodec("fp32") for level in ls_levels: _load_lscodec(level[len(LS_PREFIX) :]) torch.cuda.synchronize() start = time.perf_counter() rec = _lscodec_decode(prompt, audio, sr) torch.cuda.synchronize() rtf = (time.perf_counter() - start) / seconds base = level[len(LS_PREFIX) :] rows.append(core.evaluate(ref, rec, sr, rtf, _lscodec_size_mb(base), level, LS_BITRATE_KBPS)) reconstructed[level] = (sr, rec) _load_lscodec("fp32") # leave the baseline weights in place for the next request return {"input": (sr, ref), "rows": rows, "audio": reconstructed} def _table(rows: list[dict]) -> list[list]: return [[row[header] for header in HEADERS] for row in rows] _CACHE: dict[str, dict] = {} def run(audio_path: str, levels: list | tuple) -> dict: """Encode and decode the audio at every requested level (either codec), cached per level set.""" if not audio_path: raise gr.Error("Provide audio first: upload, record, or pick an example.") levels = tuple(levels) with open(audio_path, "rb") as fh: key = hashlib.md5(fh.read()).hexdigest() + "|" + ",".join(levels) if key not in _CACHE: if len(_CACHE) >= 6: _CACHE.clear() _CACHE[key] = _encode_decode(audio_path, levels) return _CACHE[key] def compare(audio_path: str): """Rebuild the audio at all eight levels and return one player + spectrogram per level.""" result = run(audio_path, QUANT_LEVELS) audio = [result["audio"][level] for level in QUANT_LEVELS] plots = [ core.spectrogram_figure(result["input"][1], result["audio"][level][1], SAMPLE_RATE, level) for level in QUANT_LEVELS ] return audio + plots def playground(audio_path: str, level: str): """Rebuild the audio at a single quantization level, with its metrics row.""" result = run(audio_path, [level]) rec = result["audio"][level] return ( rec, core.spectrogram_figure(result["input"][1], rec[1], SAMPLE_RATE, level), _table(result["rows"]), ) def benchmark(audio_path: str): """Score every level of both codecs on one input: metrics table plus summary chart.""" rows = run(audio_path, BENCH_LEVELS)["rows"] return _table(rows), core.metrics_figure(rows) HEADER = f"""# ⚡ FocalCodec 12.5 Hz — weight quantization lab Same checkpoint ([`lucadellalib/focalcodec_12_5hz`](https://huggingface.co/lucadellalib/focalcodec_12_5hz)), eight numeric formats for its **{sum(v.numel() for v in BASE_STATE.values()) / 1e6:.0f} M weights**: `int4 … int32` and `fp4 … fp32`. The bitrate never changes — **{core.BITRATE_KBPS:g} kbps** (12.5 tokens/s × 13 bits) — only the storage precision of the network itself. **Method:** post-training fake quantization, per-output-channel absmax scaling, round-to-nearest, dequantized back to fp32 for inference. `fp4` = E2M1, `fp8` = E4M3, `fp16`/`fp32` are exact casts. No fine-tuning. **`int8-native` rows** run the same int8 weights through a real **W8A8 runtime** instead: weights stay int8 in memory (never dequantized), each GEMM quantizes its activations per row on the fly and computes `int8 × int8 → int32` (`torch._int_mm`). ⚠️ *SI-SDR sits far below 0 dB at every level: at 0.16 kbps the codec does not preserve waveform phase, and the FocalCodec paper reports SI-SNR ≈ −37 dB for the untouched model. It is an anchor, not a quality score — read **STOI** (intelligibility) and **LSD** (log-spectral distance, lower is better) instead.* """ FOOTER = """Audio examples from the [FocalCodec repository](https://github.com/lucadellalib/focalcodec) (LibriSpeech, VoiceBank, MagicData). Model and method by Luca Della Libera et al., Apache-2.0. The **`lscodec-…`** rows are [LSCodec](https://github.com/X-LANCE/LSCodec-Inference) by Yiwei Guo et al. (MIT), quantized identically and self-prompted with WavLM-Large from [`microsoft/wavlm-large`](https://huggingface.co/microsoft/wavlm-large).""" with gr.Blocks(title="FocalCodec quantization lab") as demo: gr.Markdown(HEADER) with gr.Tab("Compare"): with gr.Row(): with gr.Column(scale=1, min_width=320): cmp_input = gr.Audio( sources=["upload", "microphone"], type="filepath", label="Input audio" ) gr.Examples(examples=EXAMPLES, inputs=cmp_input, label="Examples") cmp_button = gr.Button("Reconstruct at all 8 levels", variant="primary") gr.Markdown(f"Input capped at {MAX_SECONDS} s.") with gr.Column(scale=4): cmp_audio, cmp_plot = {}, {} for chunk in (QUANT_LEVELS[:4], QUANT_LEVELS[4:]): with gr.Row(): for level in chunk: with gr.Column(): gr.Markdown(f"**{level}**") cmp_audio[level] = gr.Audio(interactive=False, label=level) cmp_plot[level] = gr.Plot(label=f"{level} spectrogram") cmp_button.click( compare, inputs=cmp_input, outputs=[cmp_audio[level] for level in QUANT_LEVELS] + [cmp_plot[level] for level in QUANT_LEVELS], ) with gr.Tab("Playground"): with gr.Row(): with gr.Column(scale=1, min_width=320): pg_input = gr.Audio( sources=["upload", "microphone"], type="filepath", label="Input audio" ) gr.Examples(examples=EXAMPLES, inputs=pg_input, label="Examples") pg_level = gr.Dropdown( choices=list(BENCH_LEVELS), value="int8", label="Codec / weight format", ) pg_button = gr.Button("Encode + decode", variant="primary") with gr.Column(scale=3): pg_output = gr.Audio(interactive=False, label="Reconstruction") pg_plot = gr.Plot(label="Input vs reconstruction") pg_table = gr.Dataframe(headers=HEADERS, datatype=DATATYPES, interactive=False) pg_button.click( playground, inputs=[pg_input, pg_level], outputs=[pg_output, pg_plot, pg_table] ) with gr.Tab("Benchmark"): with gr.Row(): with gr.Column(scale=1, min_width=320): bm_input = gr.Audio( sources=["upload", "microphone"], type="filepath", label="Input audio" ) gr.Examples(examples=EXAMPLES, inputs=bm_input, label="Examples") bm_button = gr.Button(f"Run all {len(BENCH_LEVELS)} levels", variant="primary") with gr.Column(scale=3): gr.Markdown( "**STOI** ↑ intelligibility · **LSD** ↓ spectral error · " "**RTF** = encode+decode time ÷ audio duration · size assumes " "the stored weight format." ) if LS_LEVELS: gr.Markdown( f"Rows prefixed `lscodec-` are the second codec, quantized the same way: " f"it runs at **{LS_BITRATE_KBPS:g} kbps** (25 tokens/s × 10 bits) versus " f"FocalCodec's **{core.BITRATE_KBPS:g} kbps**, and its size covers the encoder, " "vocoder and codebook only — the WavLM-Large prompt encoder it needs is 1.2 GB " "and stays excluded." ) if NATIVE_LEVELS: gr.Markdown( f"`{NATIVE_LEVEL}` and `{LS_PREFIX}{NATIVE_LEVEL}` are the same int8 weights run " "natively (W8A8-dynamic, int8-resident) — their STOI/LSD should track the plain " "`int8` rows, but the weights are never dequantized." ) bm_table = gr.Dataframe(headers=HEADERS, datatype=DATATYPES, interactive=False) bm_plot = gr.Plot(label="Quality and size per level") bm_button.click(benchmark, inputs=bm_input, outputs=[bm_table, bm_plot]) gr.Markdown(FOOTER) demo.launch(mcp_server=True, theme=gr.themes.Soft())