ZipVoice.AXERA / scripts /zipvoice_decoder4_runtime_part3_onnx.py
HY-2012's picture
Upload the AX630C inference workflow.
e405f21 verified
Raw
History Blame Contribute Delete
3.37 kB
#!/usr/bin/env python3
from __future__ import annotations
import logging
from pathlib import Path
from typing import Dict, List
import numpy as np
import onnxruntime as ort
from scripts.zipvoice_decoder4_runtime import Decoder4ZipVoiceBoardRuntime
from scripts.zipvoice_runtime import AxeSession
class _OrtSession:
"""ONNX Runtime wrapper with the AxeSession interface used by split runtime."""
_TYPE_TO_DTYPE = {
"tensor(float)": np.float32,
"tensor(float32)": np.float32,
"tensor(double)": np.float64,
"tensor(int32)": np.int32,
"tensor(int64)": np.int64,
"tensor(uint8)": np.uint8,
"tensor(bool)": np.bool_,
}
def __init__(self, model_path: str | Path):
self.path = Path(model_path)
if not self.path.exists():
raise FileNotFoundError(f"ONNX model not found: {self.path}")
self._session = ort.InferenceSession(
str(self.path),
providers=["CPUExecutionProvider"],
)
self._inputs = self._session.get_inputs()
self._outputs = self._session.get_outputs()
@property
def input_names(self) -> List[str]:
return [item.name for item in self._inputs]
@property
def output_names(self) -> List[str]:
return [item.name for item in self._outputs]
def _coerce_one(self, name: str, value: np.ndarray) -> np.ndarray:
info = next((item for item in self._inputs if item.name == name), None)
array = np.asarray(value)
if info is None:
return np.ascontiguousarray(array)
dtype = self._TYPE_TO_DTYPE.get(str(info.type).lower())
if dtype is not None:
array = array.astype(dtype, copy=False)
if list(info.shape) == [] and array.shape == (1,):
array = array.reshape(())
return np.ascontiguousarray(array)
def run(self, feed_dict: Dict[str, np.ndarray]) -> Dict[str, np.ndarray]:
feed = {name: self._coerce_one(name, value) for name, value in feed_dict.items()}
outputs = self._session.run(None, feed)
return {name: value for name, value in zip(self.output_names, outputs)}
class Decoder4ZipVoiceBoardRuntimePart3Onnx(Decoder4ZipVoiceBoardRuntime):
"""Runs decoder part3 with ONNX Runtime, encoder and part0-2 with axmodel."""
def _load_models(self) -> None:
self.sessions = {}
encoder_name = self.encoder_info["name"]
encoder_path = self.models_dir / self.encoder_info["file"]
logging.debug("Loading %s from %s", encoder_name, encoder_path)
self.sessions[encoder_name] = AxeSession(encoder_path)
last_index = len(self.decoder_parts) - 1
for index, info in enumerate(self.decoder_parts):
name = info["name"]
if index == last_index:
path = self.models_dir / "fm_decoder_part3.onnx"
logging.info("part3 使用 ONNX Runtime: %s", path)
self.sessions[name] = _OrtSession(path)
else:
path = self.models_dir / info["file"]
logging.debug("Loading %s from %s", name, path)
self.sessions[name] = AxeSession(path)
self.decoder_label = "decoder4(part0-2_axmodel+part3_onnx)"
logging.debug("Loaded encoder axmodel + %d decoder axmodels + part3 ONNX", last_index)