-
Notifications
You must be signed in to change notification settings - Fork 72
[IR][fix] Save value info for initializers #1552
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 17 commits
5e6d729
3533a65
ee38b6d
05dd283
feea637
5156668
ae831e6
6388d95
64e740a
30401da
5c0865b
a554517
a984584
c934e52
a4c35fb
75ea900
fcc460f
1d4c1bc
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -627,32 +627,43 @@ def _deserialize_graph( | |
|
||
# Initialize the values dictionary for this graph scope with the inputs and initializers | ||
values: dict[str, _core.Value] = {v.name: v for v in inputs} # type: ignore[misc] | ||
|
||
# Enter the graph scope by pushing the values for this scope to the stack | ||
scoped_values.append(values) | ||
|
||
initializer_values = [] | ||
for tensor in initializer_tensors: | ||
if tensor.name in values: | ||
for i, tensor in enumerate(initializer_tensors): | ||
initializer_name = tensor.name | ||
if not initializer_name: | ||
logger.warning( | ||
"Initializer tensor must have a name but the %s-th initializer does not. Skipping this initializer.", | ||
i, | ||
) | ||
continue | ||
if initializer_name in values: | ||
# The initializer is for an input | ||
initializer_value = values[tensor.name] | ||
initializer_value = values[initializer_name] | ||
initializer_value.const_value = tensor | ||
else: | ||
# The initializer is for some other value. Create this value first | ||
initializer_value = _core.Value( | ||
None, | ||
index=None, | ||
name=tensor.name, | ||
# TODO(justinchuby): Fix type hinting for shape and dtype | ||
shape=tensor.shape, # type: ignore | ||
name=initializer_name, | ||
# Include shape and type even if the shape or type is not provided as ValueInfoProto. | ||
# Users expect initialized values to have shape and type information. | ||
type=_core.TensorType(tensor.dtype), | ||
shape=tensor.shape, # type: ignore[arg-type] | ||
const_value=tensor, | ||
) | ||
if initializer_value.name in quantization_annotations: | ||
_deserialize_quantization_annotation( | ||
quantization_annotations[initializer_value.name], initializer_value | ||
) | ||
values[tensor.name] = initializer_value # type: ignore[index] | ||
values[initializer_name] = initializer_value | ||
initializer_values.append(initializer_value) | ||
|
||
justinchuby marked this conversation as resolved.
Show resolved
Hide resolved
|
||
# Add ValueInfos for this graph scope | ||
# Build the value info dictionary to allow for quick lookup for this graph scope | ||
value_info = {info.name: info for info in proto.value_info} | ||
justinchuby marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
# Deserialize nodes with all known values | ||
|
@@ -663,7 +674,10 @@ def _deserialize_graph( | |
|
||
# Fill in values for graph outputs | ||
outputs = [deserialize_value_info_proto(info, values[info.name]) for info in proto.output] | ||
|
||
# Exit the graph scope by popping the values for this scope from the stack | ||
scoped_values.pop() | ||
|
||
return _core.Graph( | ||
inputs, | ||
outputs, | ||
|
@@ -1284,18 +1298,21 @@ def serialize_graph_into( | |
# TODO(justinchuby): We should add a method is_initializer() on Value when | ||
# the initializer list is tracked | ||
_maybe_add_quantization_annotation(graph_proto, input_) | ||
input_names = {input_.name for input_ in from_.inputs} | ||
# TODO(justinchuby): Support sparse_initializer | ||
for initializer in from_.initializers.values(): | ||
_maybe_add_quantization_annotation(graph_proto, initializer) | ||
if initializer.const_value is None: | ||
for value in from_.initializers.values(): | ||
_maybe_add_quantization_annotation(graph_proto, value) | ||
if _should_create_value_info_for_value(value) and value.name not in input_names: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What are the cases that initializers are model inputs? Does that mean the inputs are constants? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's like a parameter having a default value. Any input can be initialized if an initializer of the same name is in the graph. Users can choose to overwrite the initializer by providing their own input. |
||
# Serialize information about all initializers into value_info, | ||
# except for those that are also graph inputs | ||
serialize_value_into(graph_proto.value_info.add(), value) | ||
if value.const_value is None: | ||
# Skip initializers without constant values | ||
logger.warning( | ||
"Initializer '%s' does not have a constant value set.", initializer.name | ||
) | ||
logger.warning("Initializer '%s' does not have a constant value set.", value.name) | ||
continue | ||
# Make sure the tensor's name is the same as the value's name | ||
justinchuby marked this conversation as resolved.
Show resolved
Hide resolved
|
||
initializer.const_value.name = initializer.name | ||
serialize_tensor_into(graph_proto.initializer.add(), from_=initializer.const_value) | ||
value.const_value.name = value.name | ||
justinchuby marked this conversation as resolved.
Show resolved
Hide resolved
|
||
serialize_tensor_into(graph_proto.initializer.add(), from_=value.const_value) | ||
for node in from_: | ||
serialize_node_into(graph_proto.node.add(), from_=node) | ||
for node_output in node.outputs: | ||
|
Uh oh!
There was an error while loading. Please reload this page.