Download SpeechKit/Scripts/make_asset_bundle.py from Edge0/Audio8-ASR-0.1B-iOS-ANE: direct link, hf CLI and curl.
- Browser
- Download file 3.91 kB
-
https://huggingface.co/Edge0/Audio8-ASR-0.1B-iOS-ANE/resolve/main/SpeechKit/Scripts/make_asset_bundle.py
- Command line
-
hf download hf://Edge0/Audio8-ASR-0.1B-iOS-ANE/SpeechKit/Scripts/make_asset_bundle.py
-
curl -L -o make_asset_bundle.py https://huggingface.co/Edge0/Audio8-ASR-0.1B-iOS-ANE/resolve/main/SpeechKit/Scripts/make_asset_bundle.py
3.91 kB
| #!/usr/bin/env python3 | |
| """Builds ASRModels.bundle for SpeechKit distribution. | |
| Collects models + assets from the iphone-asr workspace, precompiles | |
| mlpackage -> mlmodelc (xcrun coremlcompiler), computes SHA-256 for every | |
| asset, and writes a schema-v2 manifest.json. | |
| Usage: python3 make_asset_bundle.py [output_dir] | |
| """ | |
| import hashlib | |
| import json | |
| import shutil | |
| import subprocess | |
| import sys | |
| from pathlib import Path | |
| WORKSPACE = Path(__file__).resolve().parents[2] # iphone-asr/ | |
| OUT = Path(sys.argv[1]) if len(sys.argv) > 1 else WORKSPACE / "dist/ASRModels.bundle" | |
| BUNDLE_VERSION = "1.0.0" | |
| SOURCES = { | |
| # logical name -> (source path, dest file name) | |
| "tower": (WORKSPACE / "artifacts/audio_tower_multifunction_w8.mlpackage", "tower.mlpackage"), | |
| "lm_prefill": (WORKSPACE / "artifacts/lm_shared/lm_cache_prefill_int4.onnx", "lm_prefill.onnx"), | |
| "lm_decode": (WORKSPACE / "artifacts/lm_shared/lm_cache_decode_int4.onnx", "lm_decode.onnx"), | |
| "lm_shared_data": (WORKSPACE / "artifacts/lm_shared/lm_shared_int4.data", "lm_shared_int4.data"), | |
| "mask_gen": (WORKSPACE / "artifacts/mask_gen.onnx", "mask_gen.onnx"), | |
| "asr_manifest": (WORKSPACE / "ios_assets/manifest.json", "asr_manifest.json"), | |
| "hann_window": (WORKSPACE / "ios_assets/hann_window.bin", "hann_window.bin"), | |
| "mel_filters": (WORKSPACE / "ios_assets/mel_filters.bin", "mel_filters.bin"), | |
| "projector_norm_w": (WORKSPACE / "ios_assets/projector_norm_w.bin", "projector_norm_w.bin"), | |
| "projector_norm_b": (WORKSPACE / "ios_assets/projector_norm_b.bin", "projector_norm_b.bin"), | |
| "projector_lin_w": (WORKSPACE / "ios_assets/projector_lin_w.bin", "projector_lin_w.bin"), | |
| "projector_lin_b": (WORKSPACE / "ios_assets/projector_lin_b.bin", "projector_lin_b.bin"), | |
| "token_embedding": (WORKSPACE / "ios_assets/token_embedding_fp16.bin", "token_embedding_fp16.bin"), | |
| "vocab_bytes": (WORKSPACE / "ios_assets/vocab_bytes.bin", "vocab_bytes.bin"), | |
| "vocab_offsets": (WORKSPACE / "ios_assets/vocab_offsets.bin", "vocab_offsets.bin"), | |
| } | |
| def sha256_path(p: Path) -> str: | |
| h = hashlib.sha256() | |
| if p.is_dir(): | |
| for f in sorted(p.rglob("*")): | |
| if f.is_file(): | |
| h.update(f.relative_to(p).as_posix().encode()) | |
| h.update(f.read_bytes()) | |
| else: | |
| with p.open("rb") as fh: | |
| for chunk in iter(lambda: fh.read(1 << 23), b""): | |
| h.update(chunk) | |
| return h.hexdigest() | |
| def dir_size(p: Path) -> int: | |
| if p.is_file(): | |
| return p.stat().st_size | |
| return sum(f.stat().st_size for f in p.rglob("*") if f.is_file()) | |
| if OUT.exists(): | |
| shutil.rmtree(OUT) | |
| OUT.mkdir(parents=True) | |
| assets = {} | |
| for logical, (src, dest_name) in SOURCES.items(): | |
| assert src.exists(), f"missing source: {src}" | |
| dest = OUT / dest_name | |
| if src.suffix == ".mlpackage": | |
| # precompile so devices never pay the mlpackage->mlmodelc conversion | |
| dest = OUT / (Path(dest_name).stem + ".mlmodelc") | |
| subprocess.run(["xcrun", "coremlcompiler", "compile", str(src), str(OUT)], | |
| check=True, capture_output=True) | |
| compiled = OUT / (src.stem + ".mlmodelc") | |
| if compiled != dest: | |
| compiled.rename(dest) | |
| elif src.is_dir(): | |
| shutil.copytree(src, dest) | |
| else: | |
| shutil.copy2(src, dest) | |
| assets[logical] = { | |
| "file": dest.name, | |
| "sha256": sha256_path(dest), | |
| "sizeBytes": dir_size(dest), | |
| } | |
| print(f" {logical:18s} -> {dest.name} ({dir_size(dest)/1e6:.1f}MB)") | |
| manifest = { | |
| "schemaVersion": 2, | |
| "bundleVersion": BUNDLE_VERSION, | |
| "assets": assets, | |
| "extra": {"model": "minillm-asr-zh", "builtBy": "make_asset_bundle.py"}, | |
| } | |
| (OUT / "manifest.json").write_text(json.dumps(manifest, indent=2)) | |
| total = sum(a["sizeBytes"] for a in assets.values()) | |
| print(f"\nbundle: {OUT} ({total/1e6:.0f}MB, schema v2, version {BUNDLE_VERSION})") | |