| import argparse |
| import shutil |
| import subprocess |
| from pathlib import Path |
|
|
| import coremltools as ct |
| import coremltools.optimize as cto |
| from coremltools.converters.mil.mil import types |
|
|
|
|
| def parse_args(): |
| parser = argparse.ArgumentParser() |
| parser.add_argument("--src", required=True) |
| parser.add_argument("--out-dir", required=True) |
| parser.add_argument("--bits", choices=("4", "8"), default="8") |
| parser.add_argument("--name", default=None) |
| return parser.parse_args() |
|
|
|
|
| def main(): |
| args = parse_args() |
| src = Path(args.src) |
| out_dir = Path(args.out_dir) |
| out_name = args.name or f"model_{args.bits}bit" |
| package = out_dir / f"{out_name}.mlpackage" |
| compiled = out_dir / f"{out_name}.mlmodelc" |
| dtype = types.int4 if args.bits == "4" else types.int8 |
|
|
| out_dir.mkdir(parents=True, exist_ok=True) |
| shutil.rmtree(package, ignore_errors=True) |
| shutil.rmtree(compiled, ignore_errors=True) |
|
|
| model = ct.models.MLModel(str(src)) |
| config = cto.coreml.OptimizationConfig( |
| global_config=cto.coreml.OpLinearQuantizerConfig(mode="linear_symmetric", dtype=dtype) |
| ) |
| compressed = cto.coreml.linear_quantize_weights(model, config) |
| compressed.save(str(package)) |
|
|
| compile_dir = out_dir / ".compiled" |
| shutil.rmtree(compile_dir, ignore_errors=True) |
| compile_dir.mkdir(parents=True, exist_ok=True) |
| subprocess.run(["xcrun", "coremlcompiler", "compile", str(package), str(compile_dir)], check=True) |
| generated = compile_dir / f"{package.stem}.mlmodelc" |
| shutil.move(str(generated), str(compiled)) |
| shutil.rmtree(compile_dir) |
|
|
| print(package) |
| print(compiled) |
|
|
|
|
| if __name__ == "__main__": |
| main() |
|
|