Module furiosa.quantizer.frontend.onnx.transformer.extract_constant_to_initializer
Expand source code
import onnx
import onnxoptimizer as optimizer
from onnx import numpy_helper
from onnx.helper import make_tensor_value_info, make_model, make_tensor
from furiosa_sdk_quantizer.interfaces.transformer import Transformer
from furiosa_sdk_quantizer.frontend.onnx.transformer import utils
class ExtractConstantToInitializer(Transformer):
"""
from: ArgMax -> graph output
to: graph output
"""
def transform(self, model: onnx.ModelProto) -> onnx.ModelProto:
for init in model.graph.initializer:
if init.name not in [inp.name for inp in model.graph.input]:
dims = numpy_helper.to_array(init).shape
model.graph.input.append(make_tensor_value_info(
name=init.name,
elem_type=init.data_type,
shape=dims
))
model = optimizer.optimize(model, passes=['extract_constant_to_initializer'])
# make scalar initializer's dim=0 in Add, Sub, Mul, Div
initializer = {init.name: init for init in model.graph.initializer}
input_vi = {inp.name: inp for inp in model.graph.input}
for node in model.graph.node:
if not any(node.op_type == op for op in ['Add', 'Sub', 'Mul', 'Div']):
continue
for node_input in node.input:
if node_input not in initializer:
continue
init = initializer[node_input]
vi = input_vi[node_input]
arr = numpy_helper.to_array(init)
if arr.size == 1 and arr.shape == (1,):
model.graph.initializer.remove(init)
model.graph.initializer.append(
make_tensor(name=init.name, data_type=init.data_type, dims=(), vals=numpy_helper.to_array(init))
)
model.graph.input.remove(vi)
model.graph.input.append(
make_tensor_value_info(name=init.name, elem_type=vi.type.tensor_type.elem_type, shape=())
)
model = make_model(model.graph)
model = utils.rebuild_model(model, model.graph.node)
return model
Classes
class ExtractConstantToInitializer (*args, **kwds)
-
from: ArgMax -> graph output to: graph output
Expand source code
class ExtractConstantToInitializer(Transformer): """ from: ArgMax -> graph output to: graph output """ def transform(self, model: onnx.ModelProto) -> onnx.ModelProto: for init in model.graph.initializer: if init.name not in [inp.name for inp in model.graph.input]: dims = numpy_helper.to_array(init).shape model.graph.input.append(make_tensor_value_info( name=init.name, elem_type=init.data_type, shape=dims )) model = optimizer.optimize(model, passes=['extract_constant_to_initializer']) # make scalar initializer's dim=0 in Add, Sub, Mul, Div initializer = {init.name: init for init in model.graph.initializer} input_vi = {inp.name: inp for inp in model.graph.input} for node in model.graph.node: if not any(node.op_type == op for op in ['Add', 'Sub', 'Mul', 'Div']): continue for node_input in node.input: if node_input not in initializer: continue init = initializer[node_input] vi = input_vi[node_input] arr = numpy_helper.to_array(init) if arr.size == 1 and arr.shape == (1,): model.graph.initializer.remove(init) model.graph.initializer.append( make_tensor(name=init.name, data_type=init.data_type, dims=(), vals=numpy_helper.to_array(init)) ) model.graph.input.remove(vi) model.graph.input.append( make_tensor_value_info(name=init.name, elem_type=vi.type.tensor_type.elem_type, shape=()) ) model = make_model(model.graph) model = utils.rebuild_model(model, model.graph.node) return model
Ancestors
- furiosa_sdk_quantizer.interfaces.transformer.Transformer
- typing.Generic
Methods
def transform(self, model: onnx.onnx_ml_pb2.ModelProto) ‑> onnx.onnx_ml_pb2.ModelProto
-
Expand source code
def transform(self, model: onnx.ModelProto) -> onnx.ModelProto: for init in model.graph.initializer: if init.name not in [inp.name for inp in model.graph.input]: dims = numpy_helper.to_array(init).shape model.graph.input.append(make_tensor_value_info( name=init.name, elem_type=init.data_type, shape=dims )) model = optimizer.optimize(model, passes=['extract_constant_to_initializer']) # make scalar initializer's dim=0 in Add, Sub, Mul, Div initializer = {init.name: init for init in model.graph.initializer} input_vi = {inp.name: inp for inp in model.graph.input} for node in model.graph.node: if not any(node.op_type == op for op in ['Add', 'Sub', 'Mul', 'Div']): continue for node_input in node.input: if node_input not in initializer: continue init = initializer[node_input] vi = input_vi[node_input] arr = numpy_helper.to_array(init) if arr.size == 1 and arr.shape == (1,): model.graph.initializer.remove(init) model.graph.initializer.append( make_tensor(name=init.name, data_type=init.data_type, dims=(), vals=numpy_helper.to_array(init)) ) model.graph.input.remove(vi) model.graph.input.append( make_tensor_value_info(name=init.name, elem_type=vi.type.tensor_type.elem_type, shape=()) ) model = make_model(model.graph) model = utils.rebuild_model(model, model.graph.node) return model