m96-chan commited on
Commit
e15bee2
·
verified ·
1 Parent(s): 189a3a3

Publish weights repackaged for browser WebGPU inference

Browse files
Files changed (3) hide show
  1. README.md +121 -0
  2. encoder-weights.json +381 -0
  3. encoder-weights.safetensors +3 -0
README.md ADDED
@@ -0,0 +1,121 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ license: mit
3
+ base_model: Aratako/MioCodec-25Hz-24kHz
4
+ base_model_relation: adapter
5
+ language:
6
+ - ja
7
+ - en
8
+ tags:
9
+ - speaker-embedding
10
+ - webgpu
11
+ - browser
12
+ - voice-cloning
13
+ ---
14
+
15
+ # MioCodec's speaker encoder, in one file for the browser
16
+
17
+ The global-embedding path of
18
+ [Aratako/MioCodec-25Hz-24kHz](https://huggingface.co/Aratako/MioCodec-25Hz-24kHz)'s
19
+ encoder — reference audio in, a 128-dimensional speaker embedding out —
20
+ collected into a single f32 safetensors so a browser can fetch it in one
21
+ request. Built for [voxshot](https://github.com/m96-chan/voxshot).
22
+
23
+ **This is a repackaging, not a new model.** No weight here was trained; every
24
+ tensor is copied from one of the two sources below.
25
+
26
+ | | |
27
+ | --- | ---: |
28
+ | `encoder-weights.safetensors` | 117,303,232 B, 99 tensors, 29,322,838 params |
29
+ | `encoder-weights.json` | 8,905 B — tensor index and provenance |
30
+
31
+ ## Why it exists
32
+
33
+ The weights for this one path live in **two different places**: the
34
+ `GlobalEncoder` (50 tensors) is in MioCodec's own checkpoint, while the WavLM
35
+ front end it runs on top of is a torchaudio download. A browser should not
36
+ have to know that, nor fetch a 378 MB `.pth` to use 4 MB of it. So the path is
37
+ collected once, ahead of time, into one file.
38
+
39
+ Only the **global** branch is included. MioCodec's encoder also produces
40
+ content tokens — that half is not here, and is not needed for speaker
41
+ embedding.
42
+
43
+ ## What the path is
44
+
45
+ ```
46
+ 24 kHz mono
47
+ → symmetric zero pad
48
+ → resample 24k→16k (torchaudio's polyphase filter, precomputed
49
+ here as a conv1d kernel [2, 1, 23], stride 3)
50
+ → WavLM feature extractor (7 strided convs, GroupNorm on the first, GELU)
51
+ → LayerNorm + Linear 512→768
52
+ → positional conv (grouped k=128, weight-norm already folded)
53
+ → transformer layers 1 and 2 (12 heads; bucketed, gated relative-position
54
+ bias — the global branch reads only these two)
55
+ → mean of the two layers
56
+ → ConvNeXt backbone, 4 blocks, 768→384
57
+ → attentive statistics pooling → Linear 768→128 → LayerNorm
58
+ → 128-dim embedding
59
+ ```
60
+
61
+ Two details a reimplementation gets wrong and this file cannot tell you, so
62
+ they are written down here:
63
+
64
+ - torchaudio's Base+ WavLM is **post-norm**, so an encoder-level LayerNorm runs
65
+ between the positional-conv residual and layer 1.
66
+ - the pooling softmax is over **time**, not channels.
67
+
68
+ ## Naming
69
+
70
+ WavLM tensors keep torchaudio's own names under a `wavlm.` prefix, the
71
+ `GlobalEncoder` tensors keep MioCodec's names under `global_encoder.`, and the
72
+ precomputed resampler is `resample.kernel`. `encoder-weights.json` lists every
73
+ tensor with its shape.
74
+
75
+ The positional convolution's weight normalization is **already folded** into
76
+ its weight — there is no separate `weight_g` / `weight_v` to combine.
77
+
78
+ ## Provenance
79
+
80
+ Produced by [`spike/miocodec/export_encoder_weights.py`](https://github.com/m96-chan/voxshot/blob/main/spike/miocodec/export_encoder_weights.py) from:
81
+
82
+ ```
83
+ Aratako/MioCodec-25Hz-24kHz model.safetensors
84
+ 523,087,956 bytes
85
+ sha256 60483759cde136451d53ff5a2f7e283c015758ab540de9037b5d4519366a7705
86
+
87
+ torchaudio WAVLM_BASE_PLUS wavlm_base_plus.pth
88
+ 377,604,347 bytes
89
+ sha256 136a3e720c04f2c77bf7a4dc6a3868b14d5a2c145a988114b733cb1a8428be98
90
+ ```
91
+
92
+ Both digests are recorded in `encoder-weights.json` and cross-checked at export
93
+ time against the golden this port is verified with, so the weights and the
94
+ checkpoints they came from cannot drift apart unnoticed.
95
+
96
+ ## Accuracy
97
+
98
+ The TypeScript port that consumes this file was checked stage by stage against
99
+ the reference encoder running under torch, on two real reference clips and one
100
+ synthetic input. Every stage agrees to 1e-4 relative to its own peak, except
101
+ four ConvNeXt stages on one clip which reach 1e-4 in the reference's *own*
102
+ f32-versus-f64 comparison — conditioning of that clip, not port error. The
103
+ final embedding agrees to 7.3e-7.
104
+
105
+ ## License and attribution
106
+
107
+ MIT, which both sources carry.
108
+
109
+ - **MioCodec**: [Aratako/MioCodec-25Hz-24kHz](https://huggingface.co/Aratako/MioCodec-25Hz-24kHz) by Chihiro Arata, MIT.
110
+ - **WavLM Base+**: originally published by the authors of *WavLM* (Chen et al., 2022) under the MIT License and redistributed by torchaudio under the same license.
111
+ [Source](https://github.com/microsoft/unilm/tree/65f15af2a307ebb64cfb25adf54375b002e6fe8d/wavlm#pre-trained-models) ·
112
+ [License](https://github.com/microsoft/unilm/blob/65f15af2a307ebb64cfb25adf54375b002e6fe8d/LICENSE)
113
+
114
+ ```bibtex
115
+ @article{chen2022wavlm,
116
+ title = {WavLM: Large-Scale Self-Supervised Pre-Training for Full Stack Speech Processing},
117
+ author = {Chen, Sanyuan and Wang, Chengyi and Chen, Zhengyang and others},
118
+ journal = {IEEE Journal of Selected Topics in Signal Processing},
119
+ year = {2022}
120
+ }
121
+ ```
encoder-weights.json ADDED
@@ -0,0 +1,381 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "repo_id": "Aratako/MioCodec-25Hz-24kHz",
3
+ "torch": "2.10.0+cu128",
4
+ "sources": {
5
+ "miocodec": {
6
+ "file": "model.safetensors",
7
+ "bytes": 523087956,
8
+ "sha256": "60483759cde136451d53ff5a2f7e283c015758ab540de9037b5d4519366a7705"
9
+ },
10
+ "wavlm": {
11
+ "file": "wavlm_base_plus.pth",
12
+ "bytes": 377604347,
13
+ "sha256": "136a3e720c04f2c77bf7a4dc6a3868b14d5a2c145a988114b733cb1a8428be98"
14
+ }
15
+ },
16
+ "resample": {
17
+ "orig": 3,
18
+ "new": 2,
19
+ "width": 10
20
+ },
21
+ "tensors": {
22
+ "resample.kernel": [
23
+ 2,
24
+ 1,
25
+ 23
26
+ ],
27
+ "wavlm.feature_extractor.conv_layers.0.conv.weight": [
28
+ 512,
29
+ 1,
30
+ 10
31
+ ],
32
+ "wavlm.feature_extractor.conv_layers.0.layer_norm.weight": [
33
+ 512
34
+ ],
35
+ "wavlm.feature_extractor.conv_layers.0.layer_norm.bias": [
36
+ 512
37
+ ],
38
+ "wavlm.feature_extractor.conv_layers.1.conv.weight": [
39
+ 512,
40
+ 512,
41
+ 3
42
+ ],
43
+ "wavlm.feature_extractor.conv_layers.2.conv.weight": [
44
+ 512,
45
+ 512,
46
+ 3
47
+ ],
48
+ "wavlm.feature_extractor.conv_layers.3.conv.weight": [
49
+ 512,
50
+ 512,
51
+ 3
52
+ ],
53
+ "wavlm.feature_extractor.conv_layers.4.conv.weight": [
54
+ 512,
55
+ 512,
56
+ 3
57
+ ],
58
+ "wavlm.feature_extractor.conv_layers.5.conv.weight": [
59
+ 512,
60
+ 512,
61
+ 2
62
+ ],
63
+ "wavlm.feature_extractor.conv_layers.6.conv.weight": [
64
+ 512,
65
+ 512,
66
+ 2
67
+ ],
68
+ "wavlm.encoder.feature_projection.layer_norm.weight": [
69
+ 512
70
+ ],
71
+ "wavlm.encoder.feature_projection.layer_norm.bias": [
72
+ 512
73
+ ],
74
+ "wavlm.encoder.feature_projection.projection.weight": [
75
+ 768,
76
+ 512
77
+ ],
78
+ "wavlm.encoder.feature_projection.projection.bias": [
79
+ 768
80
+ ],
81
+ "wavlm.encoder.transformer.pos_conv_embed.conv.weight": [
82
+ 768,
83
+ 48,
84
+ 128
85
+ ],
86
+ "wavlm.encoder.transformer.pos_conv_embed.conv.bias": [
87
+ 768
88
+ ],
89
+ "wavlm.encoder.transformer.layer_norm.weight": [
90
+ 768
91
+ ],
92
+ "wavlm.encoder.transformer.layer_norm.bias": [
93
+ 768
94
+ ],
95
+ "wavlm.encoder.transformer.layers.0.attention.attention.in_proj_weight": [
96
+ 2304,
97
+ 768
98
+ ],
99
+ "wavlm.encoder.transformer.layers.0.attention.attention.in_proj_bias": [
100
+ 2304
101
+ ],
102
+ "wavlm.encoder.transformer.layers.0.attention.attention.out_proj.weight": [
103
+ 768,
104
+ 768
105
+ ],
106
+ "wavlm.encoder.transformer.layers.0.attention.attention.out_proj.bias": [
107
+ 768
108
+ ],
109
+ "wavlm.encoder.transformer.layers.0.attention.gru_rel_pos_linear.weight": [
110
+ 8,
111
+ 64
112
+ ],
113
+ "wavlm.encoder.transformer.layers.0.attention.gru_rel_pos_linear.bias": [
114
+ 8
115
+ ],
116
+ "wavlm.encoder.transformer.layers.0.attention.gru_rel_pos_const": [
117
+ 1,
118
+ 12,
119
+ 1,
120
+ 1
121
+ ],
122
+ "wavlm.encoder.transformer.layers.0.attention.rel_attn_embed.weight": [
123
+ 320,
124
+ 12
125
+ ],
126
+ "wavlm.encoder.transformer.layers.0.layer_norm.weight": [
127
+ 768
128
+ ],
129
+ "wavlm.encoder.transformer.layers.0.layer_norm.bias": [
130
+ 768
131
+ ],
132
+ "wavlm.encoder.transformer.layers.0.final_layer_norm.weight": [
133
+ 768
134
+ ],
135
+ "wavlm.encoder.transformer.layers.0.final_layer_norm.bias": [
136
+ 768
137
+ ],
138
+ "wavlm.encoder.transformer.layers.0.feed_forward.intermediate_dense.weight": [
139
+ 3072,
140
+ 768
141
+ ],
142
+ "wavlm.encoder.transformer.layers.0.feed_forward.intermediate_dense.bias": [
143
+ 3072
144
+ ],
145
+ "wavlm.encoder.transformer.layers.0.feed_forward.output_dense.weight": [
146
+ 768,
147
+ 3072
148
+ ],
149
+ "wavlm.encoder.transformer.layers.0.feed_forward.output_dense.bias": [
150
+ 768
151
+ ],
152
+ "wavlm.encoder.transformer.layers.1.attention.attention.in_proj_weight": [
153
+ 2304,
154
+ 768
155
+ ],
156
+ "wavlm.encoder.transformer.layers.1.attention.attention.in_proj_bias": [
157
+ 2304
158
+ ],
159
+ "wavlm.encoder.transformer.layers.1.attention.attention.out_proj.weight": [
160
+ 768,
161
+ 768
162
+ ],
163
+ "wavlm.encoder.transformer.layers.1.attention.attention.out_proj.bias": [
164
+ 768
165
+ ],
166
+ "wavlm.encoder.transformer.layers.1.attention.gru_rel_pos_linear.weight": [
167
+ 8,
168
+ 64
169
+ ],
170
+ "wavlm.encoder.transformer.layers.1.attention.gru_rel_pos_linear.bias": [
171
+ 8
172
+ ],
173
+ "wavlm.encoder.transformer.layers.1.attention.gru_rel_pos_const": [
174
+ 1,
175
+ 12,
176
+ 1,
177
+ 1
178
+ ],
179
+ "wavlm.encoder.transformer.layers.1.layer_norm.weight": [
180
+ 768
181
+ ],
182
+ "wavlm.encoder.transformer.layers.1.layer_norm.bias": [
183
+ 768
184
+ ],
185
+ "wavlm.encoder.transformer.layers.1.final_layer_norm.weight": [
186
+ 768
187
+ ],
188
+ "wavlm.encoder.transformer.layers.1.final_layer_norm.bias": [
189
+ 768
190
+ ],
191
+ "wavlm.encoder.transformer.layers.1.feed_forward.intermediate_dense.weight": [
192
+ 3072,
193
+ 768
194
+ ],
195
+ "wavlm.encoder.transformer.layers.1.feed_forward.intermediate_dense.bias": [
196
+ 3072
197
+ ],
198
+ "wavlm.encoder.transformer.layers.1.feed_forward.output_dense.weight": [
199
+ 768,
200
+ 3072
201
+ ],
202
+ "wavlm.encoder.transformer.layers.1.feed_forward.output_dense.bias": [
203
+ 768
204
+ ],
205
+ "global_encoder.backbone.embed.weight": [
206
+ 384,
207
+ 768,
208
+ 7
209
+ ],
210
+ "global_encoder.backbone.embed.bias": [
211
+ 384
212
+ ],
213
+ "global_encoder.backbone.norm.weight": [
214
+ 384
215
+ ],
216
+ "global_encoder.backbone.norm.bias": [
217
+ 384
218
+ ],
219
+ "global_encoder.backbone.convnext.0.gamma": [
220
+ 384
221
+ ],
222
+ "global_encoder.backbone.convnext.0.dwconv.weight": [
223
+ 384,
224
+ 1,
225
+ 7
226
+ ],
227
+ "global_encoder.backbone.convnext.0.dwconv.bias": [
228
+ 384
229
+ ],
230
+ "global_encoder.backbone.convnext.0.norm.weight": [
231
+ 384
232
+ ],
233
+ "global_encoder.backbone.convnext.0.norm.bias": [
234
+ 384
235
+ ],
236
+ "global_encoder.backbone.convnext.0.pwconv1.weight": [
237
+ 1152,
238
+ 384
239
+ ],
240
+ "global_encoder.backbone.convnext.0.pwconv1.bias": [
241
+ 1152
242
+ ],
243
+ "global_encoder.backbone.convnext.0.pwconv2.weight": [
244
+ 384,
245
+ 1152
246
+ ],
247
+ "global_encoder.backbone.convnext.0.pwconv2.bias": [
248
+ 384
249
+ ],
250
+ "global_encoder.backbone.convnext.1.gamma": [
251
+ 384
252
+ ],
253
+ "global_encoder.backbone.convnext.1.dwconv.weight": [
254
+ 384,
255
+ 1,
256
+ 7
257
+ ],
258
+ "global_encoder.backbone.convnext.1.dwconv.bias": [
259
+ 384
260
+ ],
261
+ "global_encoder.backbone.convnext.1.norm.weight": [
262
+ 384
263
+ ],
264
+ "global_encoder.backbone.convnext.1.norm.bias": [
265
+ 384
266
+ ],
267
+ "global_encoder.backbone.convnext.1.pwconv1.weight": [
268
+ 1152,
269
+ 384
270
+ ],
271
+ "global_encoder.backbone.convnext.1.pwconv1.bias": [
272
+ 1152
273
+ ],
274
+ "global_encoder.backbone.convnext.1.pwconv2.weight": [
275
+ 384,
276
+ 1152
277
+ ],
278
+ "global_encoder.backbone.convnext.1.pwconv2.bias": [
279
+ 384
280
+ ],
281
+ "global_encoder.backbone.convnext.2.gamma": [
282
+ 384
283
+ ],
284
+ "global_encoder.backbone.convnext.2.dwconv.weight": [
285
+ 384,
286
+ 1,
287
+ 7
288
+ ],
289
+ "global_encoder.backbone.convnext.2.dwconv.bias": [
290
+ 384
291
+ ],
292
+ "global_encoder.backbone.convnext.2.norm.weight": [
293
+ 384
294
+ ],
295
+ "global_encoder.backbone.convnext.2.norm.bias": [
296
+ 384
297
+ ],
298
+ "global_encoder.backbone.convnext.2.pwconv1.weight": [
299
+ 1152,
300
+ 384
301
+ ],
302
+ "global_encoder.backbone.convnext.2.pwconv1.bias": [
303
+ 1152
304
+ ],
305
+ "global_encoder.backbone.convnext.2.pwconv2.weight": [
306
+ 384,
307
+ 1152
308
+ ],
309
+ "global_encoder.backbone.convnext.2.pwconv2.bias": [
310
+ 384
311
+ ],
312
+ "global_encoder.backbone.convnext.3.gamma": [
313
+ 384
314
+ ],
315
+ "global_encoder.backbone.convnext.3.dwconv.weight": [
316
+ 384,
317
+ 1,
318
+ 7
319
+ ],
320
+ "global_encoder.backbone.convnext.3.dwconv.bias": [
321
+ 384
322
+ ],
323
+ "global_encoder.backbone.convnext.3.norm.weight": [
324
+ 384
325
+ ],
326
+ "global_encoder.backbone.convnext.3.norm.bias": [
327
+ 384
328
+ ],
329
+ "global_encoder.backbone.convnext.3.pwconv1.weight": [
330
+ 1152,
331
+ 384
332
+ ],
333
+ "global_encoder.backbone.convnext.3.pwconv1.bias": [
334
+ 1152
335
+ ],
336
+ "global_encoder.backbone.convnext.3.pwconv2.weight": [
337
+ 384,
338
+ 1152
339
+ ],
340
+ "global_encoder.backbone.convnext.3.pwconv2.bias": [
341
+ 384
342
+ ],
343
+ "global_encoder.backbone.final_layer_norm.weight": [
344
+ 384
345
+ ],
346
+ "global_encoder.backbone.final_layer_norm.bias": [
347
+ 384
348
+ ],
349
+ "global_encoder.pooling.attn.0.weight": [
350
+ 128,
351
+ 384,
352
+ 1
353
+ ],
354
+ "global_encoder.pooling.attn.0.bias": [
355
+ 128
356
+ ],
357
+ "global_encoder.pooling.attn.2.weight": [
358
+ 384,
359
+ 128,
360
+ 1
361
+ ],
362
+ "global_encoder.pooling.attn.2.bias": [
363
+ 384
364
+ ],
365
+ "global_encoder.pooling.proj.weight": [
366
+ 128,
367
+ 768
368
+ ],
369
+ "global_encoder.pooling.proj.bias": [
370
+ 128
371
+ ],
372
+ "global_encoder.pooling.norm.weight": [
373
+ 128
374
+ ],
375
+ "global_encoder.pooling.norm.bias": [
376
+ 128
377
+ ]
378
+ },
379
+ "bytes": 117303232,
380
+ "sha256": "a35b4eaec345dde0e9abb2a7aa2c8c66e7a39d4ab53afce584568b5a616a0abd"
381
+ }
encoder-weights.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:a35b4eaec345dde0e9abb2a7aa2c8c66e7a39d4ab53afce584568b5a616a0abd
3
+ size 117303232