| !pip install onnx |
|
|
| import json |
| import os |
| import onnx |
| import urllib.request |
| from urllib.error import URLError, HTTPError |
| from google.colab import files |
|
|
| def download_file(url, save_path): |
| """ |
| Helper function to download a file from a URL. |
| Returns True if successful, False otherwise. |
| """ |
| if not url: |
| return False |
| |
| try: |
| print(f"Downloading from {url} ...") |
| urllib.request.urlretrieve(url, save_path) |
| print(f"Successfully downloaded to Colab: {save_path}") |
| return True |
| except HTTPError as e: |
| print(f"HTTP Error failed to download {url}: {e.code}") |
| return False |
| except URLError as e: |
| print(f"URL Error failed to download {url}: {e.reason}") |
| return False |
| except Exception as e: |
| print(f"An unexpected error occurred during download: {e}") |
| return False |
|
|
| def process_piper_model_from_url(onnx_url, json_url, output_dir): |
| |
| if not onnx_url or not json_url: |
| print("Error: Both ONNX URL and JSON URL must be provided.") |
| return |
|
|
| |
| if not os.path.exists(output_dir): |
| os.makedirs(output_dir) |
|
|
| |
| onnx_filename = onnx_url.split('/')[-1] if '/' in onnx_url else "model.onnx" |
| json_filename = json_url.split('/')[-1] if '/' in json_url else "config.json" |
| |
| |
| onnx_path = os.path.join(output_dir, onnx_filename) |
| json_path = os.path.join(output_dir, json_filename) |
| tokens_path = os.path.join(output_dir, "tokens.txt") |
|
|
| |
| if not download_file(onnx_url, onnx_path): |
| print("Failed to download ONNX file. Aborting process.") |
| return |
| |
| if not download_file(json_url, json_path): |
| print("Failed to download JSON config. Aborting process.") |
| return |
|
|
| print("Files fetched successfully. Starting processing...") |
|
|
| |
| try: |
| with open(json_path, "r", encoding="utf-8") as f: |
| config = json.load(f) |
| except Exception as e: |
| print(f"Error reading JSON file: {e}") |
| return |
|
|
| |
| if "language" not in config or "espeak" not in config or "audio" not in config: |
| print("Error: JSON config is missing required Piper metadata keys.") |
| return |
|
|
| |
| print("Step 1: Adding metadata to the ONNX file...") |
| try: |
| model = onnx.load(onnx_path) |
| except Exception as e: |
| print(f"Error loading ONNX model: {e}") |
| return |
|
|
| meta_data = { |
| "model_type": "vits", |
| "comment": "piper", |
| "language": config["language"]["code"], |
| "voice": config["espeak"]["voice"], |
| "has_espeak": 1, |
| "n_speakers": config["num_speakers"], |
| "sample_rate": config["audio"]["sample_rate"], |
| } |
|
|
| for key, value in meta_data.items(): |
| meta = model.metadata_props.add() |
| meta.key = key |
| meta.value = str(value) |
|
|
| try: |
| onnx.save(model, onnx_path) |
| print(f"-> Metadata successfully saved into '{onnx_filename}'!") |
| except Exception as e: |
| print(f"Error saving modified ONNX model: {e}") |
| return |
|
|
| |
| print("Step 2: Generating tokens.txt file for Sherpa-ONNX...") |
| if "phoneme_id_map" not in config: |
| print("Error: 'phoneme_id_map' not found in JSON config.") |
| return |
| |
| id_map = config["phoneme_id_map"] |
|
|
| try: |
| with open(tokens_path, "w", encoding="utf-8") as f_tokens: |
| for s, i in id_map.items(): |
| f_tokens.write(f"{s} {i[0]}\n") |
| |
| print(f"-> tokens.txt successfully generated! Total tokens: {len(id_map)}") |
| except Exception as e: |
| print(f"Error writing tokens.txt: {e}") |
| return |
|
|
| |
| print("\n[SUCCESS] Conversion complete! Starting automatic browser downloads...") |
| try: |
| print(f"Downloading {onnx_filename} to your device...") |
| files.download(onnx_path) |
| |
| print("Downloading tokens.txt to your device...") |
| files.download(tokens_path) |
| except Exception as e: |
| print(f"Browser download failed or not running in Colab environment: {e}") |
|
|
| |
| |
| |
|
|
| ONNX_FILE_URL = "YOUR_ONNX_FILE_URL_HERE" |
| JSON_FILE_URL = "YOUR_JSON_FILE_URL_HERE" |
| OUTPUT_DIRECTORY = "./sherpa_piper_model" |
|
|
| |
| process_piper_model_from_url(ONNX_FILE_URL, JSON_FILE_URL, OUTPUT_DIRECTORY) |
|
|