"""Tải model/thư viện cho các VAD neural vào apps/gradio-lab/models (gitignore). Cùng phiên bản với packages/vad/scripts/fetch-models.sh của server Node, kiểm tra SHA-256. TEN VAD dùng thư viện native (ctypes) thay vì bản WebAssembly: chỉ có Linux x64 và macOS. uv run python scripts/fetch_models.py """ import hashlib import platform import sys import urllib.request from pathlib import Path MODELS_DIR = Path(__file__).resolve().parent.parent / "models" SILERO_VERSION = "v6.2.3" TEN_VAD_COMMIT = "22a3bcd4509d0faaa8eef4881e8af5f39c178950" TEN = f"https://raw.githubusercontent.com/TEN-framework/ten-vad/{TEN_VAD_COMMIT}" TEN_LIBS = { "Linux": ( "lib/Linux/x64/libten_vad.so", "5abfe6bf6e9a4fcea6b440240f0a9a0f431ab5006e48a4e16465ebe681ffd90f", ), "Darwin": ( "lib/macOS/ten_vad.framework/Versions/A/ten_vad", "81b2de13710670bb94fef315ab50fedc903a21c04c4290c6c2ac28d8b42e715a", ), } def fetch(url: str, dest: Path, sha256: str | None) -> None: if dest.exists() and (sha256 is None or _sha256(dest) == sha256): print(f"✓ {dest.relative_to(MODELS_DIR)} (đã có)") return dest.parent.mkdir(parents=True, exist_ok=True) tmp = dest.with_suffix(dest.suffix + ".tmp") urllib.request.urlretrieve(url, tmp) if sha256 is not None and _sha256(tmp) != sha256: tmp.unlink() sys.exit(f"✗ {dest.name}: sai checksum — file upstream đã đổi?") tmp.rename(dest) print(f"✓ {dest.relative_to(MODELS_DIR)}") def _sha256(path: Path) -> str: return hashlib.sha256(path.read_bytes()).hexdigest() def main() -> None: # Silero VAD — MIT license fetch( f"https://raw.githubusercontent.com/snakers4/silero-vad/{SILERO_VERSION}/src/silero_vad/data/silero_vad.onnx", MODELS_DIR / "silero_vad.onnx", "1a153a22f4509e292a94e67d6f9b85e8deb25b4988682b7e174c65279d8788e3", ) # TEN VAD — Apache 2.0 KÈM ĐIỀU KIỆN của Agora, xem models/ten-vad/LICENSE system = platform.system() if system not in TEN_LIBS or (system == "Linux" and platform.machine() not in ("x86_64", "AMD64")): print(f"! TEN VAD không có bản native cho {system}/{platform.machine()} — bỏ qua") return path, sha = TEN_LIBS[system] fetch(f"{TEN}/{path}", MODELS_DIR / "ten-vad" / Path(path).name, sha) fetch(f"{TEN}/LICENSE", MODELS_DIR / "ten-vad" / "LICENSE", None) if __name__ == "__main__": main()