Spaces:
Sleeping
Sleeping
| """ | |
| Model storage module: persist voice reference files to HuggingFace Dataset repo. | |
| """ | |
| import os | |
| import logging | |
| from datetime import datetime | |
| logger = logging.getLogger(__name__) | |
| MODELS_REPO_ID = None | |
| LOCAL_MODELS_DIR = "/tmp/rvc_models" | |
| def init_storage(repo_id): | |
| """Initialize storage with the HF dataset repo ID.""" | |
| global MODELS_REPO_ID | |
| MODELS_REPO_ID = repo_id | |
| os.makedirs(LOCAL_MODELS_DIR, exist_ok=True) | |
| logger.info("Storage initialized with repo: {}".format(repo_id)) | |
| def upload_model(model_name, pth_path, index_path=None, big_npy_path=None, reference_path=None): | |
| """Upload model files to HF dataset repo.""" | |
| if not MODELS_REPO_ID: | |
| logger.warning("No HF repo configured. Model saved locally only.") | |
| return False | |
| try: | |
| from huggingface_hub import HfApi | |
| api = HfApi() | |
| # Upload .pth marker | |
| if pth_path and os.path.exists(pth_path): | |
| api.upload_file( | |
| path_or_fileobj=pth_path, | |
| path_in_repo="models/{}/{}.pth".format(model_name, model_name), | |
| repo_id=MODELS_REPO_ID, | |
| repo_type="dataset", | |
| ) | |
| logger.info("Uploaded {}.pth to HF".format(model_name)) | |
| # Upload reference audio | |
| if reference_path and os.path.exists(reference_path): | |
| ref_filename = os.path.basename(reference_path) | |
| api.upload_file( | |
| path_or_fileobj=reference_path, | |
| path_in_repo="models/{}/{}".format(model_name, ref_filename), | |
| repo_id=MODELS_REPO_ID, | |
| repo_type="dataset", | |
| ) | |
| logger.info("Uploaded {} to HF".format(ref_filename)) | |
| # Upload .index file if exists (backward compat) | |
| if index_path and os.path.exists(index_path): | |
| api.upload_file( | |
| path_or_fileobj=index_path, | |
| path_in_repo="models/{}/{}.index".format(model_name, model_name), | |
| repo_id=MODELS_REPO_ID, | |
| repo_type="dataset", | |
| ) | |
| # Upload metadata | |
| metadata = { | |
| "name": model_name, | |
| "created": datetime.now().isoformat(), | |
| "engine": "seed-vc", | |
| } | |
| import json | |
| import tempfile | |
| with tempfile.NamedTemporaryFile(mode="w", suffix=".json", delete=False) as f: | |
| json.dump(metadata, f) | |
| meta_path = f.name | |
| try: | |
| api.upload_file( | |
| path_or_fileobj=meta_path, | |
| path_in_repo="models/{}/metadata.json".format(model_name), | |
| repo_id=MODELS_REPO_ID, | |
| repo_type="dataset", | |
| ) | |
| finally: | |
| os.unlink(meta_path) | |
| return True | |
| except Exception as e: | |
| logger.error("Failed to upload model: {}".format(e)) | |
| return False | |
| def download_model(model_name): | |
| """Download model from HF dataset repo. Returns (pth_path, reference_path).""" | |
| if not MODELS_REPO_ID: | |
| return _get_local_model(model_name) | |
| try: | |
| from huggingface_hub import hf_hub_download | |
| local_dir = os.path.join(LOCAL_MODELS_DIR, model_name) | |
| os.makedirs(local_dir, exist_ok=True) | |
| pth_path = hf_hub_download( | |
| repo_id=MODELS_REPO_ID, | |
| repo_type="dataset", | |
| filename="models/{}/{}.pth".format(model_name, model_name), | |
| local_dir=local_dir, | |
| ) | |
| # Try to download reference audio | |
| ref_path = None | |
| try: | |
| ref_path = hf_hub_download( | |
| repo_id=MODELS_REPO_ID, | |
| repo_type="dataset", | |
| filename="models/{}/{}_ref.wav".format(model_name, model_name), | |
| local_dir=local_dir, | |
| ) | |
| except Exception: | |
| # Try .index for backward compat with old RVC models | |
| try: | |
| ref_path = hf_hub_download( | |
| repo_id=MODELS_REPO_ID, | |
| repo_type="dataset", | |
| filename="models/{}/{}.index".format(model_name, model_name), | |
| local_dir=local_dir, | |
| ) | |
| except Exception: | |
| pass | |
| return pth_path, ref_path | |
| except Exception as e: | |
| logger.error("Failed to download model from HF: {}".format(e)) | |
| return _get_local_model(model_name) | |
| def _get_local_model(model_name): | |
| """Get model from local storage.""" | |
| local_dir = os.path.join(LOCAL_MODELS_DIR, model_name) | |
| pth_path = os.path.join(local_dir, "{}.pth".format(model_name)) | |
| ref_path = os.path.join(local_dir, "{}_ref.wav".format(model_name)) | |
| if os.path.exists(pth_path): | |
| return pth_path, ref_path if os.path.exists(ref_path) else None | |
| return None, None | |
| def get_reference_path(model_name): | |
| """Get the reference audio path for a model.""" | |
| local_dir = os.path.join(LOCAL_MODELS_DIR, model_name) | |
| ref_path = os.path.join(local_dir, "{}_ref.wav".format(model_name)) | |
| if os.path.exists(ref_path): | |
| return ref_path | |
| # Search in subdirectories (HF download structure) | |
| for root, dirs, files in os.walk(local_dir): | |
| for f in files: | |
| if f.endswith("_ref.wav"): | |
| return os.path.join(root, f) | |
| return None | |
| def list_models(): | |
| """List all available models.""" | |
| models = set() | |
| if MODELS_REPO_ID: | |
| try: | |
| from huggingface_hub import HfApi | |
| api = HfApi() | |
| files = api.list_repo_files(MODELS_REPO_ID, repo_type="dataset") | |
| for f in files: | |
| if f.startswith("models/") and f.endswith(".pth"): | |
| parts = f.split("/") | |
| if len(parts) >= 3: | |
| models.add(parts[1]) | |
| except Exception as e: | |
| logger.error("Failed to list models from HF: {}".format(e)) | |
| if os.path.exists(LOCAL_MODELS_DIR): | |
| for name in os.listdir(LOCAL_MODELS_DIR): | |
| model_dir = os.path.join(LOCAL_MODELS_DIR, name) | |
| if os.path.isdir(model_dir): | |
| pth = os.path.join(model_dir, "{}.pth".format(name)) | |
| if os.path.exists(pth): | |
| models.add(name) | |
| return sorted(models) | |
| def delete_model(model_name): | |
| """Delete a model from HF repo and local storage.""" | |
| if MODELS_REPO_ID: | |
| try: | |
| from huggingface_hub import HfApi | |
| api = HfApi() | |
| files = api.list_repo_files(MODELS_REPO_ID, repo_type="dataset") | |
| for f in files: | |
| if f.startswith("models/{}/".format(model_name)): | |
| api.delete_file(f, MODELS_REPO_ID, repo_type="dataset") | |
| logger.info("Deleted {} from HF repo".format(model_name)) | |
| except Exception as e: | |
| logger.error("Failed to delete from HF: {}".format(e)) | |
| import shutil | |
| local_dir = os.path.join(LOCAL_MODELS_DIR, model_name) | |
| if os.path.exists(local_dir): | |
| shutil.rmtree(local_dir) | |
| logger.info("Deleted {} from local storage".format(model_name)) | |
| return True | |