| |
| """ |
| Generate fp16 and int8 variants of formantnet.onnx. |
| Run in onnxconv env. |
| """ |
| import os, sys |
| import numpy as np |
| import onnx |
| import onnxruntime as ort |
| from onnxconverter_common import float16 |
| from onnxruntime.quantization import quantize_dynamic, QuantType |
|
|
| SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__)) |
| fp32_path = os.path.join(SCRIPT_DIR, 'formantnet.onnx') |
| fp16_path = os.path.join(SCRIPT_DIR, 'formantnet_fp16.onnx') |
| int8_path = os.path.join(SCRIPT_DIR, 'formantnet_int8.onnx') |
|
|
| |
| np.random.seed(42) |
| x = np.random.randn(1, 200, 257).astype(np.float32) |
| ref_sess = ort.InferenceSession(fp32_path, providers=['CPUExecutionProvider']) |
| input_name = ref_sess.get_inputs()[0].name |
| ref_out = ref_sess.run(None, {input_name: x})[0] |
|
|
| def check(path, label, abs_thr, rel_thr): |
| sess = ort.InferenceSession(path, providers=['CPUExecutionProvider']) |
| iname = sess.get_inputs()[0].name |
| out = sess.run(None, {iname: x.astype(np.float32)})[0] |
| max_abs = float(np.abs(ref_out - out).max()) |
| max_rel = float((np.abs(ref_out - out) / (np.abs(ref_out) + 1e-8)).max()) |
| size_mb = os.path.getsize(path) / 1e6 |
| ok = max_abs < abs_thr and max_rel < rel_thr |
| status = "✓" if ok else "✗" |
| print(f" {label:6s} {size_mb:.2f} MB max_abs={max_abs:.2e} max_rel={max_rel:.2e} {status}") |
| return ok |
|
|
| print(f"Source: {fp32_path} ({os.path.getsize(fp32_path)/1e6:.2f} MB)\n") |
|
|
| |
| print("Generating fp16...") |
| model_fp32 = onnx.load(fp32_path) |
| model_fp16 = float16.convert_float_to_float16(model_fp32, keep_io_types=True) |
| onnx.save(model_fp16, fp16_path) |
| print(f" Saved → {fp16_path}") |
| check(fp16_path, 'fp16', abs_thr=0.005, rel_thr=0.05) |
|
|
| |
| print("\nGenerating int8 (dynamic quantization)...") |
| quantize_dynamic(fp32_path, int8_path, weight_type=QuantType.QInt8) |
| print(f" Saved → {int8_path}") |
| check(int8_path, 'int8', abs_thr=0.15, rel_thr=999.0) |
|
|
| print("\nDone.") |
|
|