Repository navigation
Export https://github.com/KittenML/KittenTTS to sherpa-onnx #2456
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,132 @@ | ||||||||||||||
| name: export-kitten-to-onnx | ||||||||||||||
|
|
||||||||||||||
| on: | ||||||||||||||
| push: | ||||||||||||||
| branches: | ||||||||||||||
| - kitten-tts | ||||||||||||||
|
|
||||||||||||||
| workflow_dispatch: | ||||||||||||||
|
|
||||||||||||||
| concurrency: | ||||||||||||||
| group: export-kitten-to-onnx-${{ github.ref }} | ||||||||||||||
| cancel-in-progress: true | ||||||||||||||
|
|
||||||||||||||
| jobs: | ||||||||||||||
| export-kitten-to-onnx: | ||||||||||||||
| if: github.repository_owner == 'k2-fsa' || github.repository_owner == 'csukuangfj' | ||||||||||||||
| name: export kitten ${{ matrix.version }} | ||||||||||||||
| runs-on: ${{ matrix.os }} | ||||||||||||||
| strategy: | ||||||||||||||
| fail-fast: false | ||||||||||||||
| matrix: | ||||||||||||||
| os: [ubuntu-latest] | ||||||||||||||
| python-version: ["3.10"] | ||||||||||||||
|
|
||||||||||||||
| steps: | ||||||||||||||
| - uses: actions/checkout@v4 | ||||||||||||||
|
|
||||||||||||||
| - name: Setup Python ${{ matrix.python-version }} | ||||||||||||||
| uses: actions/setup-python@v5 | ||||||||||||||
| with: | ||||||||||||||
| python-version: ${{ matrix.python-version }} | ||||||||||||||
|
|
||||||||||||||
| - name: Install Python dependencies | ||||||||||||||
| shell: bash | ||||||||||||||
| run: | | ||||||||||||||
|
||||||||||||||
| run: | | |
| run: | | |
| # NOTE: The following version constraints are required due to compatibility issues: | |
| # - numpy<=1.26.4: Newer versions may break compatibility with onnxruntime or other dependencies. | |
| # - onnx==1.16.0: This version is known to work with the current export scripts; newer versions may introduce breaking changes. | |
| # - onnxruntime==1.17.1: Required for compatibility with the exported ONNX models and numpy version. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Pin piper_phonemize version for reproducibility.
The workflow installs piper_phonemize without a specific version, which could lead to inconsistent builds if the package is updated.
- pip install "numpy<=1.26.4" onnx==1.16.0 onnxruntime==1.17.1 librosa soundfile piper_phonemize -f https://k2-fsa.github.io/icefall/piper_phonemize.html
+ pip install "numpy<=1.26.4" onnx==1.16.0 onnxruntime==1.17.1 librosa soundfile "piper_phonemize>=1.0.0" -f https://k2-fsa.github.io/icefall/piper_phonemize.html📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| pip install "numpy<=1.26.4" onnx==1.16.0 onnxruntime==1.17.1 librosa soundfile piper_phonemize -f https://k2-fsa.github.io/icefall/piper_phonemize.html | |
| pip install "numpy<=1.26.4" onnx==1.16.0 onnxruntime==1.17.1 librosa soundfile "piper_phonemize>=1.0.0" -f https://k2-fsa.github.io/icefall/piper_phonemize.html |
🤖 Prompt for AI Agents
In .github/workflows/export-kitten.yaml at line 36, the pip install command
includes piper_phonemize without a version specifier, risking inconsistent
builds. Modify the command to pin piper_phonemize to a specific version by
adding '==<version>' after the package name, ensuring reproducible and stable
workflow runs.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -142,3 +142,5 @@ README-DEV.txt | |
| .idea | ||
| sherpa-onnx-dolphin-base-ctc-multi-lang-int8-2025-04-02 | ||
| dict | ||
| *.npz | ||
| voices.bin | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,76 @@ | ||||||||||||||||||||||||||||
| #!/usr/bin/env python3 | ||||||||||||||||||||||||||||
| # Copyright 2025 Xiaomi Corp. (authors: Fangjun Kuang) | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| import argparse | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| import numpy as np | ||||||||||||||||||||||||||||
| import onnx | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| from generate_voices_bin import speaker2id | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| def get_args(): | ||||||||||||||||||||||||||||
| parser = argparse.ArgumentParser() | ||||||||||||||||||||||||||||
| parser.add_argument( | ||||||||||||||||||||||||||||
| "--model", type=str, required=True, help="input and output onnx model" | ||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| return parser.parse_args() | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| def main(): | ||||||||||||||||||||||||||||
| args = get_args() | ||||||||||||||||||||||||||||
| print(args.model) | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| model = onnx.load(args.model) | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| style = np.load("./voices.npz") | ||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||
| style = np.load("./voices.npz") | |
| style = np.load("./voices.npz") | |
| if not style.keys(): | |
| raise ValueError("No styles found in voices.npz. The file may be empty or corrupted.") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Add error handling for file loading operations.
The script loads voices.npz and accesses its keys without error handling, which could fail if the file doesn't exist or has an unexpected structure.
- style = np.load("./voices.npz")
- style_shape = style[list(style.keys())[0]].shape
+ try:
+ style = np.load("./voices.npz")
+ if len(style.keys()) == 0:
+ raise ValueError("voices.npz contains no data")
+ style_shape = style[list(style.keys())[0]].shape
+ except FileNotFoundError:
+ raise FileNotFoundError("voices.npz file not found. Ensure generate_voices_bin.py was run first.")
+ except Exception as e:
+ raise RuntimeError(f"Failed to load voice embeddings: {e}")📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| style = np.load("./voices.npz") | |
| style_shape = style[list(style.keys())[0]].shape | |
| try: | |
| style = np.load("./voices.npz") | |
| if len(style.keys()) == 0: | |
| raise ValueError("voices.npz contains no data") | |
| style_shape = style[list(style.keys())[0]].shape | |
| except FileNotFoundError: | |
| raise FileNotFoundError( | |
| "voices.npz file not found. Ensure generate_voices_bin.py was run first." | |
| ) | |
| except Exception as e: | |
| raise RuntimeError(f"Failed to load voice embeddings: {e}") |
🤖 Prompt for AI Agents
In scripts/kitten-tts/nano_v0_1/add_meta_data.py around lines 28 to 29, add
error handling for loading the voices.npz file and accessing its keys. Wrap the
np.load call and subsequent key access in a try-except block to catch exceptions
like FileNotFoundError or KeyError, and handle them gracefully by logging an
error message or exiting the script with a clear explanation.
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,30 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #!/usr/bin/env python3 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Copyright 2025 Xiaomi Corp. (authors: Fangjun Kuang) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| """ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Change the model so that it can be run in onnxruntime 1.17.1 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| """ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import onnx | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| def main(): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| model = onnx.load("kitten_tts_nano_v0_1.onnx") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Print current opsets | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| for opset in model.opset_import: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| print(f"Domain: '{opset.domain}', Version: {opset.version}") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Modify the opset versions (be careful!) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| for opset in model.opset_import: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if opset.domain == "": # ai.onnx domain | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| opset.version = 19 # change from 20 to 19 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| elif opset.domain == "ai.onnx.ml": | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| opset.version = 4 # change from 5 to 4 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Save the modified model | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| onnx.save(model, "model.fp16.onnx") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+11
to
+27
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Add error handling and make filenames configurable. The script lacks error handling and uses hardcoded filenames, which reduces flexibility and robustness. Consider this improvement: +import sys
+import argparse
+
+def get_args():
+ parser = argparse.ArgumentParser()
+ parser.add_argument("--input", default="kitten_tts_nano_v0_1.onnx")
+ parser.add_argument("--output", default="model.fp16.onnx")
+ return parser.parse_args()
def main():
- model = onnx.load("kitten_tts_nano_v0_1.onnx")
+ args = get_args()
+ try:
+ model = onnx.load(args.input)
+ except Exception as e:
+ print(f"Error loading model {args.input}: {e}")
+ sys.exit(1)
# Print current opsets
for opset in model.opset_import:
print(f"Domain: '{opset.domain}', Version: {opset.version}")
# Modify the opset versions (be careful!)
+ modified = False
for opset in model.opset_import:
if opset.domain == "": # ai.onnx domain
- opset.version = 19 # change from 20 to 19
+ if opset.version == 20:
+ opset.version = 19
+ modified = True
elif opset.domain == "ai.onnx.ml":
- opset.version = 4 # change from 5 to 4
+ if opset.version == 5:
+ opset.version = 4
+ modified = True
+ if not modified:
+ print("Warning: No opset versions were modified")
+
- # Save the modified model
- onnx.save(model, "model.fp16.onnx")
+ try:
+ onnx.save(model, args.output)
+ print(f"Model saved to {args.output}")
+ except Exception as e:
+ print(f"Error saving model: {e}")
+ sys.exit(1)📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if __name__ == "__main__": | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| main() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| #!/usr/bin/env python3 | ||
| # Copyright 2025 Xiaomi Corp. (authors: Fangjun Kuang) | ||
|
|
||
|
|
||
| def get_vocab(): | ||
| # https://github.com/KittenML/KittenTTS/blob/main/kittentts/onnx_model.py#L17 | ||
| _pad = "$" | ||
| _punctuation = ';:,.!?¡¿—…"«»"" ' | ||
| _letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" | ||
| _letters_ipa = "ɑɐɒæɓʙβɔɕçɗɖðʤəɘɚɛɜɝɞɟʄɡɠɢʛɦɧħɥʜɨɪʝɭɬɫɮʟɱɯɰŋɳɲɴøɵɸθœɶʘɹɺɾɻʀʁɽʂʃʈʧʉʊʋⱱʌɣɤʍχʎʏʑʐʒʔʡʕʢǀǁǂǃˈˌːˑʼʴʰʱʲʷˠˤ˞↓↑→↗↘'̩'ᵻ" | ||
|
|
||
| symbols = [_pad] + list(_punctuation) + list(_letters) + list(_letters_ipa) | ||
| dicts = {} | ||
| for i in range(len((symbols))): | ||
| dicts[symbols[i]] = i | ||
| return dicts | ||
|
|
||
|
|
||
| def main(): | ||
| token2id = get_vocab() | ||
| with open("tokens.txt", "w", encoding="utf-8") as f: | ||
| for s, i in token2id.items(): | ||
| f.write(f"{s} {i}\n") | ||
|
|
||
|
|
||
| if __name__ == "__main__": | ||
| main() |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,38 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #!/usr/bin/env python3 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Copyright 2025 Xiaomi Corp. (authors: Fangjun Kuang) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| from pathlib import Path | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import numpy as np | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| speakers = [ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "expr-voice-2-m", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "expr-voice-2-f", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "expr-voice-3-m", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "expr-voice-3-f", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "expr-voice-4-m", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "expr-voice-4-f", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "expr-voice-5-m", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "expr-voice-5-f", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| id2speaker = {idx: speaker for idx, speaker in enumerate(speakers)} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| speaker2id = {speaker: idx for idx, speaker in id2speaker.items()} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+7
to
+21
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Consider making speaker list data-driven and add validation. The hardcoded speaker list could become out of sync with the actual contents of def main():
if Path("./voices.bin").is_file():
print("./voices.bin exists - skip")
return
- voices = np.load("./voices.npz")
+ try:
+ voices = np.load("./voices.npz")
+ except Exception as e:
+ print(f"Error loading voices.npz: {e}")
+ return
+
+ # Validate that all expected speakers exist
+ available_speakers = set(voices.keys())
+ expected_speakers = set(speakers)
+ missing_speakers = expected_speakers - available_speakers
+ if missing_speakers:
+ print(f"Warning: Missing speakers in voices.npz: {missing_speakers}")
+ print(f"Available speakers: {sorted(available_speakers)}")
+ return
with open("voices.bin", "wb") as f:
for speaker in speakers:
v = voices[speaker]
- # v.shape (1, 256)
+ if v.shape != (1, 256):
+ print(f"Warning: Speaker {speaker} has unexpected shape {v.shape}, expected (1, 256)")
f.write(v.tobytes())📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| def main(): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if Path("./voices.bin").is_file(): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| print("./voices.bin exists - skip") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| voices = np.load("./voices.npz") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| with open("voices.bin", "wb") as f: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| for speaker in speakers: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| v = voices[speaker] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # v.shape (1, 256) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| f.write(v.tobytes()) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if __name__ == "__main__": | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| main() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,20 @@ | ||||||||||||||||||||||||||||||||||||||
| #!/usr/bin/env bash | ||||||||||||||||||||||||||||||||||||||
| # Copyright 2025 Xiaomi Corp. (authors: Fangjun Kuang) | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| set -ex | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| if [ ! -f kitten_tts_nano_v0_1.onnx ]; then | ||||||||||||||||||||||||||||||||||||||
| curl -SL -O https://huggingface.co/KittenML/kitten-tts-nano-0.1/resolve/main/kitten_tts_nano_v0_1.onnx | ||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| if [ ! -f voices.npz ]; then | ||||||||||||||||||||||||||||||||||||||
| curl -SL -O https://huggingface.co/KittenML/kitten-tts-nano-0.1/resolve/main/voices.npz | ||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+6
to
+12
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Add integrity verification for downloaded files. Downloading files from external URLs without integrity verification poses security risks. Consider adding checksum validation. if [ ! -f kitten_tts_nano_v0_1.onnx ]; then
curl -SL -O https://huggingface.co/KittenML/kitten-tts-nano-0.1/resolve/main/kitten_tts_nano_v0_1.onnx
+ # Verify file integrity (add expected SHA256 hash)
+ # echo "expected_hash kitten_tts_nano_v0_1.onnx" | sha256sum -c
fi
if [ ! -f voices.npz ]; then
curl -SL -O https://huggingface.co/KittenML/kitten-tts-nano-0.1/resolve/main/voices.npz
+ # Verify file integrity (add expected SHA256 hash)
+ # echo "expected_hash voices.npz" | sha256sum -c
fi📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| ./generate_voices_bin.py | ||||||||||||||||||||||||||||||||||||||
| ./generate_tokens.py | ||||||||||||||||||||||||||||||||||||||
| ./convert_opset.py | ||||||||||||||||||||||||||||||||||||||
| ./show.py | ||||||||||||||||||||||||||||||||||||||
| ./add_meta_data.py --model ./model.fp16.onnx | ||||||||||||||||||||||||||||||||||||||
| # ./test.py --model ./model.fp16.onnx --tokens ./tokens.txt --voice ./voices.bin | ||||||||||||||||||||||||||||||||||||||
| ls -lh | ||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,45 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #!/usr/bin/env python3 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Copyright 2025 Xiaomi Corp. (authors: Fangjun Kuang) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import onnxruntime | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import onnx | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| """ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| [key: "onnx.infer" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| value: "onnxruntime.quant" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| , key: "onnx.quant.pre_process" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| value: "onnxruntime.quant" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| NodeArg(name='input_ids', type='tensor(int64)', shape=[1, 'sequence_length']) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| NodeArg(name='style', type='tensor(float)', shape=[1, 256]) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| NodeArg(name='speed', type='tensor(float)', shape=[1]) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ----- | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| NodeArg(name='waveform', type='tensor(float)', shape=['num_samples']) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| NodeArg(name='duration', type='tensor(int64)', shape=['Castduration_dim_0']) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| """ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| def show(filename): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| model = onnx.load(filename) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| print(model.metadata_props) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| session_opts = onnxruntime.SessionOptions() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| session_opts.log_severity_level = 3 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| sess = onnxruntime.InferenceSession( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| filename, session_opts, providers=["CPUExecutionProvider"] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| for i in sess.get_inputs(): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| print(i) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| print("-----") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| for i in sess.get_outputs(): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| print(i) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| def main(): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| show("./model.fp16.onnx") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+22
to
+41
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Add error handling and make filename configurable. The script should handle potential errors when loading models and allow flexible filename input. +import sys
+import argparse
+def get_args():
+ parser = argparse.ArgumentParser(description="Inspect ONNX model")
+ parser.add_argument("--model", default="./model.fp16.onnx", help="Path to ONNX model file")
+ return parser.parse_args()
def show(filename):
- model = onnx.load(filename)
- print(model.metadata_props)
+ try:
+ model = onnx.load(filename)
+ print(model.metadata_props)
+ except Exception as e:
+ print(f"Error loading model {filename}: {e}")
+ return False
session_opts = onnxruntime.SessionOptions()
session_opts.log_severity_level = 3
- sess = onnxruntime.InferenceSession(
- filename, session_opts, providers=["CPUExecutionProvider"]
- )
- for i in sess.get_inputs():
- print(i)
+ try:
+ sess = onnxruntime.InferenceSession(
+ filename, session_opts, providers=["CPUExecutionProvider"]
+ )
+ for i in sess.get_inputs():
+ print(i)
- print("-----")
+ print("-----")
- for i in sess.get_outputs():
- print(i)
+ for i in sess.get_outputs():
+ print(i)
+ return True
+ except Exception as e:
+ print(f"Error creating inference session: {e}")
+ return False
def main():
- show("./model.fp16.onnx")
+ args = get_args()
+ if not show(args.model):
+ sys.exit(1)📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+41
to
+43
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| show("./model.fp16.onnx") | |
| parser = argparse.ArgumentParser(description="Show ONNX model info") | |
| parser.add_argument("filename", nargs="?", default="./model.fp16.onnx", | |
| help="Path to the ONNX model file (default: ./model.fp16.onnx)") | |
| args = parser.parse_args() | |
| show(args.filename) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove unused matrix.version reference.
The workflow references
${{ matrix.version }}in the job name but doesn't defineversionin the matrix strategy. This creates an undefined variable reference.🧰 Tools
🪛 actionlint (1.7.7)
17-17: property "version" is not defined in object type {os: string; python-version: number}
(expression)
🤖 Prompt for AI Agents