Shusek00 commited on
Commit
8026061
·
verified ·
1 Parent(s): 0dbae7f

Publish prebuilt Phonemis ONNX frontends v2.1.0

Browse files
README.md CHANGED
@@ -30,7 +30,7 @@ tags:
30
  # Complete Kokoro catalog for ONNX Runtime and Kotlin Multiplatform
31
 
32
  All 157 voices published in the pinned official Kokoro v1.0 and v1.1-zh repositories, plus the
33
- native Polish and German voices, converted for on-device ONNX Runtime use. Version 2.0.0 contains
34
  **159 voices**, **10 languages / 11 locale profiles**, and **4 compatible FP32 models**.
35
 
36
  The catalog is designed for a language picker followed by a voice picker. A client downloads only
@@ -59,7 +59,7 @@ voices introduced with v1.1-zh are included as well and correctly point to that
59
 
60
  ## Download-on-demand client flow
61
 
62
- 1. Fetch [`catalog.json`](catalog.json) from the immutable `v2.0.0` revision.
63
  2. Show `languages`, then the selected language's `voices`.
64
  3. Read the selected voice's `modelId` and resolve it in top-level `models`.
65
  4. Resolve that model's `tokenizerId` in top-level `tokenizers`.
@@ -68,7 +68,7 @@ voices introduced with v1.1-zh are included as well and correctly point to that
68
  6. Verify each file's `sizeBytes` and `sha256` before activating it.
69
  7. Cache by artifact path or SHA-256 so shared models are not downloaded again.
70
 
71
- Resolve every artifact path relative to the catalog URL. Pinning the catalog to `v2.0.0` therefore
72
  pins every dependent file to the same immutable release. The schema is versioned at
73
  [`schema/kokoro-catalog.schema.json`](schema/kokoro-catalog.schema.json).
74
 
@@ -95,10 +95,10 @@ combining marks such as the nasalization mark in `ɔ̃` are separate code points
95
  ## Text frontends
96
 
97
  Phonemis assets are bundled for `en-us`, `en-gb`, `de`, `fr`, `es`, `it`, `pl`, `pt`, and `hi`.
98
- They produce Kokoro-compatible IPA without shipping eSpeak or a GPL component. English packs also
99
- include the full lexicon and part-of-speech tagger required for best results. Phonemis itself is a
100
- small C++20 library; Android/JVM can expose it through a native bridge and Web can use an
101
- Emscripten/Wasm build.
102
 
103
  Japanese and Mandarin model/voice packs are fully included and accept phoneme input. Their
104
  official Python path uses `misaki[ja]` and `misaki[zh]`, but this repository does not pretend those
@@ -110,7 +110,8 @@ distributed here.
110
 
111
  ## Validation
112
 
113
- Version 2.0.0 validation covers:
 
114
 
115
  - JSON Schema and SHA-256 verification for all 183 catalog artifacts;
116
  - ONNX structural validation and Apache-2.0/source metadata checks for all 4 models;
@@ -118,6 +119,8 @@ Version 2.0.0 validation covers:
118
  - 13 natural-language cases covering every profile and both Chinese model generations;
119
  - 1-, 128-, and 510-phoneme boundary cases for each model;
120
  - ONNX Runtime Web 1.29 WebAssembly inference for each model, including the 510-phoneme boundary.
 
 
121
 
122
  Results are recorded in [`validation/package-validation.json`](validation/package-validation.json)
123
  and the `validation/web-*.json` files. Actual frontend outputs are recorded in
@@ -145,7 +148,7 @@ fixed voice-count assertions. Source and converted hashes are recorded in
145
  Maintainers can publish a fully validated folder after authenticating with the Hugging Face CLI:
146
 
147
  ```bash
148
- python scripts/publish_hf.py <namespace>/kokoro-kmp-models --tag v2.0.0
149
  ```
150
 
151
  ## Scope and compatibility
 
30
  # Complete Kokoro catalog for ONNX Runtime and Kotlin Multiplatform
31
 
32
  All 157 voices published in the pinned official Kokoro v1.0 and v1.1-zh repositories, plus the
33
+ native Polish and German voices, converted for on-device ONNX Runtime use. Version 2.1.0 contains
34
  **159 voices**, **10 languages / 11 locale profiles**, and **4 compatible FP32 models**.
35
 
36
  The catalog is designed for a language picker followed by a voice picker. A client downloads only
 
59
 
60
  ## Download-on-demand client flow
61
 
62
+ 1. Fetch [`catalog.json`](catalog.json) from the immutable `v2.1.0` revision.
63
  2. Show `languages`, then the selected language's `voices`.
64
  3. Read the selected voice's `modelId` and resolve it in top-level `models`.
65
  4. Resolve that model's `tokenizerId` in top-level `tokenizers`.
 
68
  6. Verify each file's `sizeBytes` and `sha256` before activating it.
69
  7. Cache by artifact path or SHA-256 so shared models are not downloaded again.
70
 
71
+ Resolve every artifact path relative to the catalog URL. Pinning the catalog to `v2.1.0` therefore
72
  pins every dependent file to the same immutable release. The schema is versioned at
73
  [`schema/kokoro-catalog.schema.json`](schema/kokoro-catalog.schema.json).
74
 
 
95
  ## Text frontends
96
 
97
  Phonemis assets are bundled for `en-us`, `en-gb`, `de`, `fr`, `es`, `it`, `pl`, `pt`, and `hi`.
98
+ Version 2.1.0 publishes each neural frontend as a ready-to-open ONNX graph, so clients no longer
99
+ need to convert the upstream weight container at runtime. They produce Kokoro-compatible IPA
100
+ without shipping eSpeak or a GPL component. English packs also include the full lexicon and
101
+ part-of-speech tagger required for best results.
102
 
103
  Japanese and Mandarin model/voice packs are fully included and accept phoneme input. Their
104
  official Python path uses `misaki[ja]` and `misaki[zh]`, but this repository does not pretend those
 
110
 
111
  ## Validation
112
 
113
+ Version 2.1.0 preserves the complete 2.0.0 validation baseline and additionally validates all nine
114
+ prebuilt Phonemis graphs with ONNX Runtime 1.29 CPU inference. Validation covers:
115
 
116
  - JSON Schema and SHA-256 verification for all 183 catalog artifacts;
117
  - ONNX structural validation and Apache-2.0/source metadata checks for all 4 models;
 
119
  - 13 natural-language cases covering every profile and both Chinese model generations;
120
  - 1-, 128-, and 510-phoneme boundary cases for each model;
121
  - ONNX Runtime Web 1.29 WebAssembly inference for each model, including the 510-phoneme boundary.
122
+ - deterministic prebuilding, size/SHA-256 verification, and a real inference smoke for every
123
+ bundled Phonemis ONNX frontend.
124
 
125
  Results are recorded in [`validation/package-validation.json`](validation/package-validation.json)
126
  and the `validation/web-*.json` files. Actual frontend outputs are recorded in
 
148
  Maintainers can publish a fully validated folder after authenticating with the Hugging Face CLI:
149
 
150
  ```bash
151
+ python scripts/publish_hf.py <namespace>/kokoro-kmp-models --tag v2.1.0
152
  ```
153
 
154
  ## Scope and compatibility
SOURCES.lock.json CHANGED
@@ -38,6 +38,11 @@
38
  "languageProfileCount": 9,
39
  "artifactCount": 13
40
  },
 
 
 
 
 
41
  "upstreamAssetManifest": {
42
  "path": "sources/upstream-assets.json",
43
  "sha256": "3f6df7a5819dbb96b6ab740cdd6f4ba2501ccdee1e633cdd050ef0b4912c009e",
 
38
  "languageProfileCount": 9,
39
  "artifactCount": 13
40
  },
41
+ "phonemisOnnx": {
42
+ "manifestPath": "sources/phonemis-onnx-v2.1.0.json",
43
+ "manifestSha256": "6462bbecbad96b69446aca7cf594c67a6435ba06f2e199d2249285abf273a283",
44
+ "artifactCount": 9
45
+ },
46
  "upstreamAssetManifest": {
47
  "path": "sources/upstream-assets.json",
48
  "sha256": "3f6df7a5819dbb96b6ab740cdd6f4ba2501ccdee1e633cdd050ef0b4912c009e",
THIRD_PARTY_NOTICES.md CHANGED
@@ -28,6 +28,10 @@ plus the English full lexicons and tagger models, come from
28
  [`IgorSwat/Phonemis`](https://github.com/IgorSwat/Phonemis), revision
29
  `71eb1ce33bd586d38cbac037843b8539d7829c3b`.
30
 
 
 
 
 
31
  Phonemis is distributed under the MIT License. Its unchanged license text is available in
32
  [`third-party/phonemis/LICENSE`](third-party/phonemis/LICENSE). This separate MIT license applies
33
  to the Phonemis files and does not alter Kokoro's Apache-2.0 license.
 
28
  [`IgorSwat/Phonemis`](https://github.com/IgorSwat/Phonemis), revision
29
  `71eb1ce33bd586d38cbac037843b8539d7829c3b`.
30
 
31
+ For release `v2.1.0`, the nine neural weight containers are deterministically wrapped as ONNX
32
+ graphs ahead of distribution. Exact source and output hashes, sizes, and converter provenance are
33
+ recorded in [`sources/phonemis-onnx-v2.1.0.json`](sources/phonemis-onnx-v2.1.0.json).
34
+
35
  Phonemis is distributed under the MIT License. Its unchanged license text is available in
36
  [`third-party/phonemis/LICENSE`](third-party/phonemis/LICENSE). This separate MIT license applies
37
  to the Phonemis files and does not alter Kokoro's Apache-2.0 license.
catalog.json CHANGED
@@ -1,7 +1,7 @@
1
  {
2
  "$schema": "schema/kokoro-catalog.schema.json",
3
  "schemaVersion": 2,
4
- "catalogVersion": "2.0.0",
5
  "distribution": {
6
  "provider": "huggingface",
7
  "repository": "Shusek00/kokoro-kmp-models",
@@ -219,10 +219,10 @@
219
  {
220
  "role": "neural-model",
221
  "artifact": {
222
- "path": "phonemizers/en-us/phonemizer_en_us.bin",
223
- "mediaType": "application/octet-stream",
224
- "sizeBytes": 7094120,
225
- "sha256": "e059561fb8d51eadfd2000965be30e31f0152e7e8c8b4fcf7859dbcce8557576"
226
  }
227
  },
228
  {
@@ -529,10 +529,10 @@
529
  {
530
  "role": "neural-model",
531
  "artifact": {
532
- "path": "phonemizers/en-gb/phonemizer_en_gb.bin",
533
- "mediaType": "application/octet-stream",
534
- "sizeBytes": 7094120,
535
- "sha256": "3d4fe5a541c02de30879a5b84b88f5229f5b31f8fb2dcf7e89a1ce3a6c330334"
536
  }
537
  },
538
  {
@@ -683,10 +683,10 @@
683
  {
684
  "role": "neural-model",
685
  "artifact": {
686
- "path": "phonemizers/es/phonemizer_es.bin",
687
- "mediaType": "application/octet-stream",
688
- "sizeBytes": 7094120,
689
- "sha256": "8dc68946e12c1a233ac9153fd369f6418b930a3d731587ff64dc789f44d75a52"
690
  }
691
  }
692
  ]
@@ -747,10 +747,10 @@
747
  {
748
  "role": "neural-model",
749
  "artifact": {
750
- "path": "phonemizers/fr/phonemizer_fr.bin",
751
- "mediaType": "application/octet-stream",
752
- "sizeBytes": 7094120,
753
- "sha256": "fa0018b750a3670328026107b44e02eafe3223b6878585ca0927786b7812d96a"
754
  }
755
  }
756
  ]
@@ -787,10 +787,10 @@
787
  {
788
  "role": "neural-model",
789
  "artifact": {
790
- "path": "phonemizers/hi/phonemizer_hi.bin",
791
- "mediaType": "application/octet-stream",
792
- "sizeBytes": 9194344,
793
- "sha256": "dcee3272f96d7f1b7cc40c5df23060b502a5b9066f7cb20092413dff82a487f5"
794
  }
795
  }
796
  ]
@@ -863,10 +863,10 @@
863
  {
864
  "role": "neural-model",
865
  "artifact": {
866
- "path": "phonemizers/it/phonemizer_it.bin",
867
- "mediaType": "application/octet-stream",
868
- "sizeBytes": 7094120,
869
- "sha256": "dca8d068d76134a40856cd874ea6e5e05c988914369ab643f52ab77a512067e3"
870
  }
871
  }
872
  ]
@@ -991,10 +991,10 @@
991
  {
992
  "role": "neural-model",
993
  "artifact": {
994
- "path": "phonemizers/pt-br/phonemizer_pt.bin",
995
- "mediaType": "application/octet-stream",
996
- "sizeBytes": 7094120,
997
- "sha256": "89049ea03c52ffa7233a343d44a35059aae3b1231d772c8c498fbc4427756ecf"
998
  }
999
  }
1000
  ]
@@ -2367,10 +2367,10 @@
2367
  {
2368
  "role": "neural-model",
2369
  "artifact": {
2370
- "path": "phonemizers/pl/phonemizer_pl.bin",
2371
- "mediaType": "application/octet-stream",
2372
- "sizeBytes": 7094120,
2373
- "sha256": "ec85f4dc2c4ac7a72ff88b98b0664a4ed887bd15c0d5add2eb1d6a6ee05b73f2"
2374
  }
2375
  }
2376
  ]
@@ -2407,10 +2407,10 @@
2407
  {
2408
  "role": "neural-model",
2409
  "artifact": {
2410
- "path": "phonemizers/de/phonemizer_de.bin",
2411
- "mediaType": "application/octet-stream",
2412
- "sizeBytes": 7094120,
2413
- "sha256": "4888dc7e54dc66098551555096562063364091fc246da0d057b629587bedaa0b"
2414
  }
2415
  }
2416
  ]
 
1
  {
2
  "$schema": "schema/kokoro-catalog.schema.json",
3
  "schemaVersion": 2,
4
+ "catalogVersion": "2.1.0",
5
  "distribution": {
6
  "provider": "huggingface",
7
  "repository": "Shusek00/kokoro-kmp-models",
 
219
  {
220
  "role": "neural-model",
221
  "artifact": {
222
+ "path": "phonemizers/en-us/phonemizer_en_us.onnx",
223
+ "mediaType": "application/onnx",
224
+ "sizeBytes": 7105527,
225
+ "sha256": "479cd9d89819a60c4f8609dbb116ae5b362d46c0c592b97605968cbaef1e7bc6"
226
  }
227
  },
228
  {
 
529
  {
530
  "role": "neural-model",
531
  "artifact": {
532
+ "path": "phonemizers/en-gb/phonemizer_en_gb.onnx",
533
+ "mediaType": "application/onnx",
534
+ "sizeBytes": 7105527,
535
+ "sha256": "065baba624db8391905e53c78706a12c5f4cba12a77e62a90900b2113bdb17e7"
536
  }
537
  },
538
  {
 
683
  {
684
  "role": "neural-model",
685
  "artifact": {
686
+ "path": "phonemizers/es/phonemizer_es.onnx",
687
+ "mediaType": "application/onnx",
688
+ "sizeBytes": 7105527,
689
+ "sha256": "0437232bb50cffdefc51995dc8195c14992b185655e3bc0f0005b97a7f162240"
690
  }
691
  }
692
  ]
 
747
  {
748
  "role": "neural-model",
749
  "artifact": {
750
+ "path": "phonemizers/fr/phonemizer_fr.onnx",
751
+ "mediaType": "application/onnx",
752
+ "sizeBytes": 7105527,
753
+ "sha256": "d0ca22d75569827f86d73bd8f071a128e478d4f6f107e94035236ba080658485"
754
  }
755
  }
756
  ]
 
787
  {
788
  "role": "neural-model",
789
  "artifact": {
790
+ "path": "phonemizers/hi/phonemizer_hi.onnx",
791
+ "mediaType": "application/onnx",
792
+ "sizeBytes": 9205753,
793
+ "sha256": "7e046cd695d2615bad723b24e7fbe0339594526f6953df4c5d20aa53862a9678"
794
  }
795
  }
796
  ]
 
863
  {
864
  "role": "neural-model",
865
  "artifact": {
866
+ "path": "phonemizers/it/phonemizer_it.onnx",
867
+ "mediaType": "application/onnx",
868
+ "sizeBytes": 7105527,
869
+ "sha256": "30c115355c28c1c8657eba91a1557d89b9bb69b373202399546719cf2991f9f8"
870
  }
871
  }
872
  ]
 
991
  {
992
  "role": "neural-model",
993
  "artifact": {
994
+ "path": "phonemizers/pt-br/phonemizer_pt.onnx",
995
+ "mediaType": "application/onnx",
996
+ "sizeBytes": 7105527,
997
+ "sha256": "fb30ed5fbdf2465b5f3d8a08903d2cc50dfa77b4c4c24518ac0ba26640393f52"
998
  }
999
  }
1000
  ]
 
2367
  {
2368
  "role": "neural-model",
2369
  "artifact": {
2370
+ "path": "phonemizers/pl/phonemizer_pl.onnx",
2371
+ "mediaType": "application/onnx",
2372
+ "sizeBytes": 7105527,
2373
+ "sha256": "4cdbafd810ed3cad701c24380894115f848cfa39602d731e7a8e085adee62233"
2374
  }
2375
  }
2376
  ]
 
2407
  {
2408
  "role": "neural-model",
2409
  "artifact": {
2410
+ "path": "phonemizers/de/phonemizer_de.onnx",
2411
+ "mediaType": "application/onnx",
2412
+ "sizeBytes": 7105527,
2413
+ "sha256": "aef1d8a6163b426733059f35f406c540ccd08a3f7855eebe6a09ab4908d5dac7"
2414
  }
2415
  }
2416
  ]
catalog.template.json CHANGED
@@ -1,7 +1,7 @@
1
  {
2
  "$schema": "schema/kokoro-catalog.schema.json",
3
  "schemaVersion": 2,
4
- "catalogVersion": "2.0.0",
5
  "distribution": {
6
  "provider": "huggingface",
7
  "repository": "Shusek00/kokoro-kmp-models",
@@ -183,7 +183,7 @@
183
  "artifacts": [
184
  {
185
  "role": "neural-model",
186
- "artifact": { "$artifact": { "path": "phonemizers/en-us/phonemizer_en_us.bin", "mediaType": "application/octet-stream" } }
187
  },
188
  {
189
  "role": "lexicon",
@@ -214,7 +214,7 @@
214
  "artifacts": [
215
  {
216
  "role": "neural-model",
217
- "artifact": { "$artifact": { "path": "phonemizers/en-gb/phonemizer_en_gb.bin", "mediaType": "application/octet-stream" } }
218
  },
219
  {
220
  "role": "lexicon",
@@ -245,7 +245,7 @@
245
  "artifacts": [
246
  {
247
  "role": "neural-model",
248
- "artifact": { "$artifact": { "path": "phonemizers/es/phonemizer_es.bin", "mediaType": "application/octet-stream" } }
249
  }
250
  ]
251
  },
@@ -268,7 +268,7 @@
268
  "artifacts": [
269
  {
270
  "role": "neural-model",
271
- "artifact": { "$artifact": { "path": "phonemizers/fr/phonemizer_fr.bin", "mediaType": "application/octet-stream" } }
272
  }
273
  ]
274
  },
@@ -291,7 +291,7 @@
291
  "artifacts": [
292
  {
293
  "role": "neural-model",
294
- "artifact": { "$artifact": { "path": "phonemizers/hi/phonemizer_hi.bin", "mediaType": "application/octet-stream" } }
295
  }
296
  ]
297
  },
@@ -314,7 +314,7 @@
314
  "artifacts": [
315
  {
316
  "role": "neural-model",
317
- "artifact": { "$artifact": { "path": "phonemizers/it/phonemizer_it.bin", "mediaType": "application/octet-stream" } }
318
  }
319
  ]
320
  },
@@ -353,7 +353,7 @@
353
  "artifacts": [
354
  {
355
  "role": "neural-model",
356
- "artifact": { "$artifact": { "path": "phonemizers/pt-br/phonemizer_pt.bin", "mediaType": "application/octet-stream" } }
357
  }
358
  ]
359
  },
@@ -392,7 +392,7 @@
392
  "artifacts": [
393
  {
394
  "role": "neural-model",
395
- "artifact": { "$artifact": { "path": "phonemizers/pl/phonemizer_pl.bin", "mediaType": "application/octet-stream" } }
396
  }
397
  ]
398
  },
@@ -427,7 +427,7 @@
427
  "artifacts": [
428
  {
429
  "role": "neural-model",
430
- "artifact": { "$artifact": { "path": "phonemizers/de/phonemizer_de.bin", "mediaType": "application/octet-stream" } }
431
  }
432
  ]
433
  },
 
1
  {
2
  "$schema": "schema/kokoro-catalog.schema.json",
3
  "schemaVersion": 2,
4
+ "catalogVersion": "2.1.0",
5
  "distribution": {
6
  "provider": "huggingface",
7
  "repository": "Shusek00/kokoro-kmp-models",
 
183
  "artifacts": [
184
  {
185
  "role": "neural-model",
186
+ "artifact": { "$artifact": { "path": "phonemizers/en-us/phonemizer_en_us.onnx", "mediaType": "application/onnx" } }
187
  },
188
  {
189
  "role": "lexicon",
 
214
  "artifacts": [
215
  {
216
  "role": "neural-model",
217
+ "artifact": { "$artifact": { "path": "phonemizers/en-gb/phonemizer_en_gb.onnx", "mediaType": "application/onnx" } }
218
  },
219
  {
220
  "role": "lexicon",
 
245
  "artifacts": [
246
  {
247
  "role": "neural-model",
248
+ "artifact": { "$artifact": { "path": "phonemizers/es/phonemizer_es.onnx", "mediaType": "application/onnx" } }
249
  }
250
  ]
251
  },
 
268
  "artifacts": [
269
  {
270
  "role": "neural-model",
271
+ "artifact": { "$artifact": { "path": "phonemizers/fr/phonemizer_fr.onnx", "mediaType": "application/onnx" } }
272
  }
273
  ]
274
  },
 
291
  "artifacts": [
292
  {
293
  "role": "neural-model",
294
+ "artifact": { "$artifact": { "path": "phonemizers/hi/phonemizer_hi.onnx", "mediaType": "application/onnx" } }
295
  }
296
  ]
297
  },
 
314
  "artifacts": [
315
  {
316
  "role": "neural-model",
317
+ "artifact": { "$artifact": { "path": "phonemizers/it/phonemizer_it.onnx", "mediaType": "application/onnx" } }
318
  }
319
  ]
320
  },
 
353
  "artifacts": [
354
  {
355
  "role": "neural-model",
356
+ "artifact": { "$artifact": { "path": "phonemizers/pt-br/phonemizer_pt.onnx", "mediaType": "application/onnx" } }
357
  }
358
  ]
359
  },
 
392
  "artifacts": [
393
  {
394
  "role": "neural-model",
395
+ "artifact": { "$artifact": { "path": "phonemizers/pl/phonemizer_pl.onnx", "mediaType": "application/onnx" } }
396
  }
397
  ]
398
  },
 
427
  "artifacts": [
428
  {
429
  "role": "neural-model",
430
+ "artifact": { "$artifact": { "path": "phonemizers/de/phonemizer_de.onnx", "mediaType": "application/onnx" } }
431
  }
432
  ]
433
  },
phonemizers/de/phonemizer_de.onnx ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:aef1d8a6163b426733059f35f406c540ccd08a3f7855eebe6a09ab4908d5dac7
3
+ size 7105527
phonemizers/en-gb/phonemizer_en_gb.onnx ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:065baba624db8391905e53c78706a12c5f4cba12a77e62a90900b2113bdb17e7
3
+ size 7105527
phonemizers/en-us/phonemizer_en_us.onnx ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:479cd9d89819a60c4f8609dbb116ae5b362d46c0c592b97605968cbaef1e7bc6
3
+ size 7105527
phonemizers/es/phonemizer_es.onnx ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:0437232bb50cffdefc51995dc8195c14992b185655e3bc0f0005b97a7f162240
3
+ size 7105527
phonemizers/fr/phonemizer_fr.onnx ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:d0ca22d75569827f86d73bd8f071a128e478d4f6f107e94035236ba080658485
3
+ size 7105527
phonemizers/hi/phonemizer_hi.onnx ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:7e046cd695d2615bad723b24e7fbe0339594526f6953df4c5d20aa53862a9678
3
+ size 9205753
phonemizers/it/phonemizer_it.onnx ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:30c115355c28c1c8657eba91a1557d89b9bb69b373202399546719cf2991f9f8
3
+ size 7105527
phonemizers/pl/phonemizer_pl.onnx ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:4cdbafd810ed3cad701c24380894115f848cfa39602d731e7a8e085adee62233
3
+ size 7105527
phonemizers/pt-br/phonemizer_pt.onnx ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:fb30ed5fbdf2465b5f3d8a08903d2cc50dfa77b4c4c24518ac0ba26640393f52
3
+ size 7105527
scripts/publish_hf.py CHANGED
@@ -25,7 +25,7 @@ def run_validation(skip_web: bool) -> None:
25
  def parse_args() -> argparse.Namespace:
26
  parser = argparse.ArgumentParser()
27
  parser.add_argument("repo_id", help="Hugging Face repo, e.g. username/kokoro-kmp-models")
28
- parser.add_argument("--tag", default="v2.0.0")
29
  parser.add_argument("--skip-web-validation", action="store_true")
30
  return parser.parse_args()
31
 
 
25
  def parse_args() -> argparse.Namespace:
26
  parser = argparse.ArgumentParser()
27
  parser.add_argument("repo_id", help="Hugging Face repo, e.g. username/kokoro-kmp-models")
28
+ parser.add_argument("--tag", default="v2.1.0")
29
  parser.add_argument("--skip-web-validation", action="store_true")
30
  return parser.parse_args()
31
 
scripts/validate_package.py CHANGED
@@ -138,6 +138,33 @@ if (
138
  raise RuntimeError("SOURCES.lock.json does not match the upstream asset manifest")
139
  if source_inventory["voiceCount"] != 157 or source_inventory["catalogVoiceCount"] != 159:
140
  raise RuntimeError("Pinned upstream inventory must contain exactly 157 voices")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
141
  for source_voice in source_inventory["voices"]:
142
  key = (source_voice["languageId"], source_voice["id"])
143
  if key not in voices:
@@ -176,6 +203,38 @@ bundled_languages = {
176
  for language in languages.values()
177
  if language["textFrontend"]["status"] == "bundled"
178
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
179
  phonemis_languages = {
180
  case["language"] for case in frontend_validation["phonemis"]["cases"]
181
  }
@@ -327,6 +386,8 @@ report = {
327
  "languageProfilesValidated": len(languages),
328
  "voicesValidated": len(voice_results),
329
  "frontendCasesValidated": len(frontend_cases),
 
 
330
  "cases": case_results,
331
  "voiceSmokeTests": voice_results,
332
  "boundaryCases": boundary_results,
@@ -344,6 +405,7 @@ print(
344
  "languageProfilesValidated": report["languageProfilesValidated"],
345
  "voicesValidated": report["voicesValidated"],
346
  "frontendCasesValidated": report["frontendCasesValidated"],
 
347
  "naturalCasesValidated": len(case_results),
348
  "boundaryCasesValidated": len(boundary_results),
349
  },
 
138
  raise RuntimeError("SOURCES.lock.json does not match the upstream asset manifest")
139
  if source_inventory["voiceCount"] != 157 or source_inventory["catalogVoiceCount"] != 159:
140
  raise RuntimeError("Pinned upstream inventory must contain exactly 157 voices")
141
+
142
+ phonemis_onnx_lock = source_lock["phonemisOnnx"]
143
+ phonemis_onnx_manifest_path = ROOT / phonemis_onnx_lock["manifestPath"]
144
+ if phonemis_onnx_lock["manifestSha256"] != sha256(phonemis_onnx_manifest_path):
145
+ raise RuntimeError("SOURCES.lock.json does not match the Phonemis ONNX manifest")
146
+ phonemis_onnx_manifest = json.loads(
147
+ phonemis_onnx_manifest_path.read_text(encoding="utf-8")
148
+ )
149
+ if len(phonemis_onnx_manifest["artifacts"]) != phonemis_onnx_lock["artifactCount"]:
150
+ raise RuntimeError("Phonemis ONNX manifest artifact count mismatch")
151
+ phonemis_sources = {
152
+ item["artifactPath"]: item for item in source_inventory["phonemis"]
153
+ }
154
+ for converted in phonemis_onnx_manifest["artifacts"]:
155
+ source = phonemis_sources.get(converted["sourcePath"])
156
+ if source is None or source["sourceSha256"] != converted["sourceSha256"]:
157
+ raise RuntimeError(
158
+ f"Phonemis ONNX source mismatch for {converted['sourcePath']}"
159
+ )
160
+ artifact = artifact_by_path.get(converted["path"])
161
+ if artifact is None or any(
162
+ artifact[field] != converted[field]
163
+ for field in ("path", "sizeBytes", "sha256")
164
+ ):
165
+ raise RuntimeError(
166
+ f"Phonemis ONNX catalog mismatch for {converted['path']}"
167
+ )
168
  for source_voice in source_inventory["voices"]:
169
  key = (source_voice["languageId"], source_voice["id"])
170
  if key not in voices:
 
203
  for language in languages.values()
204
  if language["textFrontend"]["status"] == "bundled"
205
  }
206
+ frontend_onnx_results = []
207
+ frontend_session_options = ort.SessionOptions()
208
+ frontend_session_options.graph_optimization_level = ort.GraphOptimizationLevel.ORT_ENABLE_ALL
209
+ for language_id, language in bundled_languages.items():
210
+ neural_model = next(
211
+ item["artifact"]
212
+ for item in language["textFrontend"]["artifacts"]
213
+ if item["role"] == "neural-model"
214
+ )
215
+ if neural_model.get("mediaType") != "application/onnx":
216
+ raise RuntimeError(f"{language_id}: neural frontend is not a prebuilt ONNX model")
217
+ frontend_session = ort.InferenceSession(
218
+ str(ROOT / neural_model["path"]),
219
+ sess_options=frontend_session_options,
220
+ providers=["CPUExecutionProvider"],
221
+ )
222
+ logits = frontend_session.run(
223
+ ["logits"],
224
+ {"input_ids": np.asarray([[2]], dtype=np.int64)},
225
+ )[0]
226
+ if logits.ndim != 3 or logits.shape[0] != 1 or logits.shape[2] != 116:
227
+ raise RuntimeError(f"{language_id}: unexpected frontend logits shape {logits.shape}")
228
+ if not np.isfinite(logits).all():
229
+ raise RuntimeError(f"{language_id}: non-finite frontend logits")
230
+ frontend_onnx_results.append(
231
+ {
232
+ "language": language_id,
233
+ "path": neural_model["path"],
234
+ "sha256": neural_model["sha256"],
235
+ "logitsShape": list(logits.shape),
236
+ }
237
+ )
238
  phonemis_languages = {
239
  case["language"] for case in frontend_validation["phonemis"]["cases"]
240
  }
 
386
  "languageProfilesValidated": len(languages),
387
  "voicesValidated": len(voice_results),
388
  "frontendCasesValidated": len(frontend_cases),
389
+ "frontendOnnxModelsValidated": len(frontend_onnx_results),
390
+ "frontendOnnxSmokeTests": frontend_onnx_results,
391
  "cases": case_results,
392
  "voiceSmokeTests": voice_results,
393
  "boundaryCases": boundary_results,
 
405
  "languageProfilesValidated": report["languageProfilesValidated"],
406
  "voicesValidated": report["voicesValidated"],
407
  "frontendCasesValidated": report["frontendCasesValidated"],
408
+ "frontendOnnxModelsValidated": report["frontendOnnxModelsValidated"],
409
  "naturalCasesValidated": len(case_results),
410
  "boundaryCasesValidated": len(boundary_results),
411
  },
sources/phonemis-onnx-v2.1.0.json ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "schemaVersion": 1,
3
+ "converter": {
4
+ "repository": "ShinudaCommunity/kokoro-narrator-suvio-plugin",
5
+ "revision": "d16c577a516feac9ce0459bd615fd3a847a4334e",
6
+ "sourcePath": "src/commonMain/kotlin/PhonemisOnnx.kt",
7
+ "converterVersion": "1",
8
+ "producer": "Suvio Kokoro Narrator 0.1.0"
9
+ },
10
+ "artifacts": [
11
+ {"language": "en-us", "sourcePath": "phonemizers/en-us/phonemizer_en_us.bin", "sourceSha256": "e059561fb8d51eadfd2000965be30e31f0152e7e8c8b4fcf7859dbcce8557576", "path": "phonemizers/en-us/phonemizer_en_us.onnx", "sizeBytes": 7105527, "sha256": "479cd9d89819a60c4f8609dbb116ae5b362d46c0c592b97605968cbaef1e7bc6"},
12
+ {"language": "en-gb", "sourcePath": "phonemizers/en-gb/phonemizer_en_gb.bin", "sourceSha256": "3d4fe5a541c02de30879a5b84b88f5229f5b31f8fb2dcf7e89a1ce3a6c330334", "path": "phonemizers/en-gb/phonemizer_en_gb.onnx", "sizeBytes": 7105527, "sha256": "065baba624db8391905e53c78706a12c5f4cba12a77e62a90900b2113bdb17e7"},
13
+ {"language": "es", "sourcePath": "phonemizers/es/phonemizer_es.bin", "sourceSha256": "8dc68946e12c1a233ac9153fd369f6418b930a3d731587ff64dc789f44d75a52", "path": "phonemizers/es/phonemizer_es.onnx", "sizeBytes": 7105527, "sha256": "0437232bb50cffdefc51995dc8195c14992b185655e3bc0f0005b97a7f162240"},
14
+ {"language": "fr", "sourcePath": "phonemizers/fr/phonemizer_fr.bin", "sourceSha256": "fa0018b750a3670328026107b44e02eafe3223b6878585ca0927786b7812d96a", "path": "phonemizers/fr/phonemizer_fr.onnx", "sizeBytes": 7105527, "sha256": "d0ca22d75569827f86d73bd8f071a128e478d4f6f107e94035236ba080658485"},
15
+ {"language": "hi", "sourcePath": "phonemizers/hi/phonemizer_hi.bin", "sourceSha256": "dcee3272f96d7f1b7cc40c5df23060b502a5b9066f7cb20092413dff82a487f5", "path": "phonemizers/hi/phonemizer_hi.onnx", "sizeBytes": 9205753, "sha256": "7e046cd695d2615bad723b24e7fbe0339594526f6953df4c5d20aa53862a9678"},
16
+ {"language": "it", "sourcePath": "phonemizers/it/phonemizer_it.bin", "sourceSha256": "dca8d068d76134a40856cd874ea6e5e05c988914369ab643f52ab77a512067e3", "path": "phonemizers/it/phonemizer_it.onnx", "sizeBytes": 7105527, "sha256": "30c115355c28c1c8657eba91a1557d89b9bb69b373202399546719cf2991f9f8"},
17
+ {"language": "pt", "sourcePath": "phonemizers/pt-br/phonemizer_pt.bin", "sourceSha256": "89049ea03c52ffa7233a343d44a35059aae3b1231d772c8c498fbc4427756ecf", "path": "phonemizers/pt-br/phonemizer_pt.onnx", "sizeBytes": 7105527, "sha256": "fb30ed5fbdf2465b5f3d8a08903d2cc50dfa77b4c4c24518ac0ba26640393f52"},
18
+ {"language": "pl", "sourcePath": "phonemizers/pl/phonemizer_pl.bin", "sourceSha256": "ec85f4dc2c4ac7a72ff88b98b0664a4ed887bd15c0d5add2eb1d6a6ee05b73f2", "path": "phonemizers/pl/phonemizer_pl.onnx", "sizeBytes": 7105527, "sha256": "4cdbafd810ed3cad701c24380894115f848cfa39602d731e7a8e085adee62233"},
19
+ {"language": "de", "sourcePath": "phonemizers/de/phonemizer_de.bin", "sourceSha256": "4888dc7e54dc66098551555096562063364091fc246da0d057b629587bedaa0b", "path": "phonemizers/de/phonemizer_de.onnx", "sizeBytes": 7105527, "sha256": "aef1d8a6163b426733059f35f406c540ccd08a3f7855eebe6a09ab4908d5dac7"}
20
+ ]
21
+ }
validation/package-validation.json CHANGED
@@ -1,5 +1,5 @@
1
  {
2
- "catalogVersion": "2.0.0",
3
  "catalogSchemaValidated": true,
4
  "onnxRuntimeVersion": "1.29.0",
5
  "artifactsVerified": 183,
@@ -7,6 +7,18 @@
7
  "languageProfilesValidated": 11,
8
  "voicesValidated": 159,
9
  "frontendCasesValidated": 12,
 
 
 
 
 
 
 
 
 
 
 
 
10
  "cases": [
11
  {
12
  "id": "en-us-af-heart",
 
1
  {
2
+ "catalogVersion": "2.1.0",
3
  "catalogSchemaValidated": true,
4
  "onnxRuntimeVersion": "1.29.0",
5
  "artifactsVerified": 183,
 
7
  "languageProfilesValidated": 11,
8
  "voicesValidated": 159,
9
  "frontendCasesValidated": 12,
10
+ "frontendOnnxModelsValidated": 9,
11
+ "frontendOnnxSmokeTests": [
12
+ {"language": "en-us", "path": "phonemizers/en-us/phonemizer_en_us.onnx", "sha256": "479cd9d89819a60c4f8609dbb116ae5b362d46c0c592b97605968cbaef1e7bc6", "logitsShape": [1, 2, 116]},
13
+ {"language": "en-gb", "path": "phonemizers/en-gb/phonemizer_en_gb.onnx", "sha256": "065baba624db8391905e53c78706a12c5f4cba12a77e62a90900b2113bdb17e7", "logitsShape": [1, 2, 116]},
14
+ {"language": "es", "path": "phonemizers/es/phonemizer_es.onnx", "sha256": "0437232bb50cffdefc51995dc8195c14992b185655e3bc0f0005b97a7f162240", "logitsShape": [1, 2, 116]},
15
+ {"language": "fr", "path": "phonemizers/fr/phonemizer_fr.onnx", "sha256": "d0ca22d75569827f86d73bd8f071a128e478d4f6f107e94035236ba080658485", "logitsShape": [1, 2, 116]},
16
+ {"language": "hi", "path": "phonemizers/hi/phonemizer_hi.onnx", "sha256": "7e046cd695d2615bad723b24e7fbe0339594526f6953df4c5d20aa53862a9678", "logitsShape": [1, 2, 116]},
17
+ {"language": "it", "path": "phonemizers/it/phonemizer_it.onnx", "sha256": "30c115355c28c1c8657eba91a1557d89b9bb69b373202399546719cf2991f9f8", "logitsShape": [1, 2, 116]},
18
+ {"language": "pt", "path": "phonemizers/pt-br/phonemizer_pt.onnx", "sha256": "fb30ed5fbdf2465b5f3d8a08903d2cc50dfa77b4c4c24518ac0ba26640393f52", "logitsShape": [1, 2, 116]},
19
+ {"language": "pl", "path": "phonemizers/pl/phonemizer_pl.onnx", "sha256": "4cdbafd810ed3cad701c24380894115f848cfa39602d731e7a8e085adee62233", "logitsShape": [1, 2, 116]},
20
+ {"language": "de", "path": "phonemizers/de/phonemizer_de.onnx", "sha256": "aef1d8a6163b426733059f35f406c540ccd08a3f7855eebe6a09ab4908d5dac7", "logitsShape": [1, 2, 116]}
21
+ ],
22
  "cases": [
23
  {
24
  "id": "en-us-af-heart",