melmass commited on
Commit
7264ecd
·
verified ·
1 Parent(s): 24b86f6

Upload folder using huggingface_hub

Browse files
Files changed (2) hide show
  1. README.md +48 -0
  2. convert.py +35 -0
README.md ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ license: mit
3
+ library_name: mlx
4
+ tags:
5
+ - audio
6
+ - audio-super-resolution
7
+ - mlx
8
+ base_model: haoheliu/audiosr_basic
9
+ ---
10
+
11
+ # AudioSR basic, trimmed
12
+
13
+ The released [AudioSR](https://github.com/haoheliu/versatile_audio_super_resolution)
14
+ `basic` checkpoint, cut down to what super-resolution runs and saved as
15
+ safetensors. It is used by IntelligenceKit's `MLXAudioSR` (Swift, MLX) and
16
+ by `afm upscale`.
17
+
18
+ `basic.safetensors`, 2.69 GB, float32, with PyTorch names and layouts. It holds:
19
+
20
+ - `model.`: the diffusion UNet
21
+ - `first_stage_model.`: the VAE and its 48 kHz HiFi-GAN vocoder
22
+ - the scale factor and the noise schedule's buffers
23
+
24
+ These are left out:
25
+
26
+ - CLAP, which super-resolution doesn't use;
27
+ - the EMA copy of the UNet, since inference uses the live weights;
28
+ - the condition encoder's VAE, which is identical to `first_stage_model`.
29
+
30
+ The MLX port casts to float16 at load time.
31
+
32
+ `convert.py`, the script that made the file:
33
+
34
+ ```sh
35
+ python convert.py basic basic.safetensors
36
+ ```
37
+
38
+ ## Parity
39
+
40
+ The MLX port matches PyTorch stage by stage, from 76 to 137 dB SNR. It was
41
+ tested on a clip low-passed at 6 kHz and scored by LSD against the original
42
+ (lower is better):
43
+
44
+ | | LSD |
45
+ |---|---|
46
+ | input | 3.88 |
47
+ | PyTorch | 1.16 |
48
+ | MLX | 1.14 |
convert.py ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """The released AudioSR checkpoint, trimmed to what super-resolution uses, as safetensors.
2
+
3
+ python convert.py basic audiosr-basic.safetensors
4
+
5
+ Kept: the diffusion UNet (`model.`), the VAE with its HiFi-GAN vocoder
6
+ (`first_stage_model.`) and the scalar/schedule buffers. Dropped: CLAP
7
+ (`clap.`, unused for super-resolution), the EMA copy of the UNet (`model_ema.`,
8
+ inference uses the live weights) and the condition encoder's VAE
9
+ (`cond_stage_models.0.vae.`), after checking it equals `first_stage_model`.
10
+ """
11
+
12
+ import sys
13
+
14
+ import torch
15
+ from audiosr.utils import download_checkpoint
16
+ from safetensors.torch import save_file
17
+
18
+ name, out = sys.argv[1], sys.argv[2]
19
+ state = torch.load(download_checkpoint(name), map_location="cpu", weights_only=False)["state_dict"]
20
+
21
+ cond_prefix = "cond_stage_models.0.vae."
22
+ mismatched = [
23
+ k for k in state
24
+ if k.startswith(cond_prefix) and not torch.equal(state[k], state["first_stage_model." + k[len(cond_prefix):]])
25
+ ]
26
+ assert not mismatched, f"condition VAE differs from first_stage_model: {mismatched[:5]}"
27
+
28
+ dropped = ("clap.", "model_ema.", "cond_stage_models.")
29
+ kept = {k: v.contiguous() for k, v in state.items() if not k.startswith(dropped)}
30
+ total = sum(v.numel() for v in kept.values())
31
+ print(f"kept {len(kept)} of {len(state)} tensors, {total / 1e6:.0f}M values, {total * 4 / 1e9:.2f} GB at fp32")
32
+ for prefix in ("model.", "first_stage_model.encoder", "first_stage_model.decoder", "first_stage_model.vocoder"):
33
+ n = sum(v.numel() for k, v in kept.items() if k.startswith(prefix))
34
+ print(f" {prefix:30} {n / 1e6:7.1f}M")
35
+ save_file(kept, out, metadata={"source": f"audiosr {name}", "dtype": "float32"})