Skip to content
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

AttributeError: 'float' object has no attribute 'astype' #2096

Closed
ChinChangYang opened this issue Dec 21, 2023 · 4 comments
Closed

AttributeError: 'float' object has no attribute 'astype' #2096

ChinChangYang opened this issue Dec 21, 2023 · 4 comments
Labels
bug Unexpected behaviour that should be corrected (type) tf2.x / tf.keras Issue could be related to tf2.x where coremltools isn't supported (component)

Comments

@ChinChangYang
Copy link
Contributor

🐞Describing the bug

When converting a TensorFlow keras model into a mlprogram, it fails with the an attribute error.
In the pull request LeelaChessZero/lczero-training#222, Test 2: 512x19 (FAILED) shows the full log.

Stack Trace

Traceback (most recent call last):
  File "/Users/chinchangyang/Code/lczero-training-ccy/tf/net_to_coreml.py", line 50, in <module>
    coreml_model = ct.convert(
                   ^^^^^^^^^^^
  File "/Users/chinchangyang/miniconda3/envs/lczero-training-py3.11/lib/python3.11/site-packages/coremltools/converters/_converters_entry.py", line 574, in convert
    mlmodel = mil_convert(
              ^^^^^^^^^^^^
  File "/Users/chinchangyang/miniconda3/envs/lczero-training-py3.11/lib/python3.11/site-packages/coremltools/converters/mil/converter.py", line 188, in mil_convert
    return _mil_convert(model, convert_from, convert_to, ConverterRegistry, MLModel, compute_units, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/chinchangyang/miniconda3/envs/lczero-training-py3.11/lib/python3.11/site-packages/coremltools/converters/mil/converter.py", line 212, in _mil_convert
    proto, mil_program = mil_convert_to_proto(
                         ^^^^^^^^^^^^^^^^^^^^^
  File "/Users/chinchangyang/miniconda3/envs/lczero-training-py3.11/lib/python3.11/site-packages/coremltools/converters/mil/converter.py", line 286, in mil_convert_to_proto
    prog = frontend_converter(model, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/chinchangyang/miniconda3/envs/lczero-training-py3.11/lib/python3.11/site-packages/coremltools/converters/mil/converter.py", line 98, in __call__
    return tf2_loader.load()
           ^^^^^^^^^^^^^^^^^
  File "/Users/chinchangyang/miniconda3/envs/lczero-training-py3.11/lib/python3.11/site-packages/coremltools/converters/mil/frontend/tensorflow/load.py", line 82, in load
    program = self._program_from_tf_ssa()
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/chinchangyang/miniconda3/envs/lczero-training-py3.11/lib/python3.11/site-packages/coremltools/converters/mil/frontend/tensorflow2/load.py", line 210, in _program_from_tf_ssa
    return converter.convert()
           ^^^^^^^^^^^^^^^^^^^
  File "/Users/chinchangyang/miniconda3/envs/lczero-training-py3.11/lib/python3.11/site-packages/coremltools/converters/mil/frontend/tensorflow/converter.py", line 522, in convert
    self.convert_main_graph(prog, graph)
  File "/Users/chinchangyang/miniconda3/envs/lczero-training-py3.11/lib/python3.11/site-packages/coremltools/converters/mil/frontend/tensorflow/converter.py", line 421, in convert_main_graph
    outputs = convert_graph(self.context, graph, self.output_names)
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/chinchangyang/miniconda3/envs/lczero-training-py3.11/lib/python3.11/site-packages/coremltools/converters/mil/frontend/tensorflow/convert_utils.py", line 191, in convert_graph
    add_op(context, node)
  File "/Users/chinchangyang/miniconda3/envs/lczero-training-py3.11/lib/python3.11/site-packages/coremltools/converters/mil/frontend/tensorflow/ops.py", line 1332, in RealDiv
    y = mb.cast(x=context[node.inputs[1]], dtype="fp32")
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/chinchangyang/miniconda3/envs/lczero-training-py3.11/lib/python3.11/site-packages/coremltools/converters/mil/mil/ops/registry.py", line 182, in add_op
    return cls._add_op(op_cls_to_add, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/chinchangyang/miniconda3/envs/lczero-training-py3.11/lib/python3.11/site-packages/coremltools/converters/mil/mil/builder.py", line 184, in _add_op
    new_op.type_value_inference()
  File "/Users/chinchangyang/miniconda3/envs/lczero-training-py3.11/lib/python3.11/site-packages/coremltools/converters/mil/mil/operation.py", line 260, in type_value_inference
    output_vals = self._auto_val(output_types)
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/chinchangyang/miniconda3/envs/lczero-training-py3.11/lib/python3.11/site-packages/coremltools/converters/mil/mil/operation.py", line 377, in _auto_val
    vals = self.value_inference()
           ^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/chinchangyang/miniconda3/envs/lczero-training-py3.11/lib/python3.11/site-packages/coremltools/converters/mil/mil/operation.py", line 111, in wrapper
    return func(self)
           ^^^^^^^^^^
  File "/Users/chinchangyang/miniconda3/envs/lczero-training-py3.11/lib/python3.11/site-packages/coremltools/converters/mil/mil/ops/defs/iOS15/elementwise_unary.py", line 868, in value_inference
    return self.get_cast_value(self.x, self.dtype.val)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/chinchangyang/miniconda3/envs/lczero-training-py3.11/lib/python3.11/site-packages/coremltools/converters/mil/mil/ops/defs/iOS15/elementwise_unary.py", line 894, in get_cast_value
    return input_var.val.astype(dtype=string_to_nptype(dtype_val))
           ^^^^^^^^^^^^^^^^^^^^
AttributeError: 'float' object has no attribute 'astype'

To Reproduce

Not available.

System environment (please complete the following information):

  • coremltools version: 7.1
  • OS (e.g. MacOS version or Linux type): macOS Sonoma 14.2.1
  • Any other relevant version information (e.g. PyTorch or TensorFlow version): TensorFlow 2.15.0

Additional context

Related to this pull request: #2087
Similar issue: #1768

Debug log

I added some log to trace how the float object was created and saw this:

[952/987] Converting StridedSlice op 'model/tf.__operators__.getitem/strided_slice'
x=%model/tf.compat.v1.shape/Shape: (3,int32)*(Tensor) type=<class 'coremltools.converters.mil.mil.var.Var'>
x.val=[  1  64 512] type=<class 'numpy.ndarray'>
x.sym_val=[  1  64 512] type=<class 'numpy.ndarray'>
x.sym_type=<class 'coremltools.converters.mil.mil.types.type_tensor.tensor.<locals>.tensor'> type=<class 'type'>
begin=[-1] type=<class 'list'>
end=[0] type=<class 'list'>
stride=[1] type=<class 'list'>
x(after)=%model/tf.__operators__.getitem/strided_slice: (int32)*(Scalar) type=<class 'coremltools.converters.mil.mil.var.Var'>
x.val=512 type=<class 'numpy.int32'>
x.sym_val=512 type=<class 'numpy.int32'>
x.sym_type=<class 'coremltools.converters.mil.mil.types.type_int.make_int.<locals>.int'> type=<class 'type'>
[954/987] Converting Cast op 'model/tf.cast/Cast'
x(input)=%model/tf.__operators__.getitem/strided_slice: (int32)*(Scalar)
x(output)=%model/tf.cast/Cast: (fp32)*(Scalar)
x.val=512.0
x.sym_val=512.0
x.sym_type=<class 'coremltools.converters.mil.mil.types.type_double.make_float.<locals>.double'>
[957/987] Converting Sqrt op 'model/tf.math.sqrt/Sqrt'
x(input)=%model/tf.cast/Cast: (fp32)*(Scalar)
x(output)=%model/tf.math.sqrt/Sqrt: (fp32)*(Scalar)
x.val=22.627416610717773
x.sym_val=22.627416610717773
x.sym_type=<class 'coremltools.converters.mil.mil.types.type_double.make_float.<locals>.double'>
[961/987] Converting RealDiv op 'model/tf.math.truediv_1/truediv'
node.inputs[0]=model/tf.linalg.matmul/MatMul type=<class 'str'>
x=%model/tf.linalg.matmul/MatMul: (1, 64, 64, fp32)(Tensor) type=<class 'coremltools.converters.mil.mil.var.Var'>
x.val=None type=<class 'NoneType'>
x.sym_val=None type=<class 'NoneType'>
x.sym_type=<class 'coremltools.converters.mil.mil.types.type_tensor.tensor.<locals>.tensor'> type=<class 'type'>
node.inputs[1]=model/tf.math.sqrt/Sqrt type=<class 'str'>
y=%model/tf.math.sqrt/Sqrt: (fp32)*(Scalar) type=<class 'coremltools.converters.mil.mil.var.Var'>
y.val=22.627416610717773 type=<class 'float'>
y.sym_val=22.627416610717773 type=<class 'float'>
y.sym_type=<class 'coremltools.converters.mil.mil.types.type_double.make_float.<locals>.double'> type=<class 'type'>
File "/Users/chinchangyang/miniconda3/envs/lczero-training-py3.11/lib/python3.11/site-packages/coremltools/converters/mil/mil/ops/defs/iOS15/elementwise_unary.py", line 894, in get_cast_value
    return input_var.val.astype(dtype=string_to_nptype(dtype_val))
           ^^^^^^^^^^^^^^^^^^^^
AttributeError: 'float' object has no attribute 'astype'

The float object comes from model/tf.math.sqrt/Sqrt, which comes from the output of model/tf.cast/Cast, which comes from the output of model/tf.__operators__.getitem/strided_slice, which comes from this:

x=%model/tf.compat.v1.shape/Shape: (3,int32)*(Tensor) type=<class 'coremltools.converters.mil.mil.var.Var'>
x.val=[  1  64 512] type=<class 'numpy.ndarray'>
x.sym_val=[  1  64 512] type=<class 'numpy.ndarray'>
x.sym_type=<class 'coremltools.converters.mil.mil.types.type_tensor.tensor.<locals>.tensor'> type=<class 'type'>
begin=[-1] type=<class 'list'>
end=[0] type=<class 'list'>
stride=[1] type=<class 'list'>

Finally, I could see x was a Tensor, and these x, begin, end, and stride variables were input parameters of the following function call:

    x = mb.slice_by_index(
        x=x,
        name=node.name,
        begin=begin,
        end=end,
        stride=stride,
        begin_mask=begin_mask,
        end_mask=end_mask,
        squeeze_mask=squeeze_mask,
    )

The output x became a scalar from now on.

@ChinChangYang ChinChangYang added the bug Unexpected behaviour that should be corrected (type) label Dec 21, 2023
@Suraj209211
Copy link

@ChinChangYang can you further explain the same with your code??

@ChinChangYang
Copy link
Contributor Author

ChinChangYang commented Dec 21, 2023

@ChinChangYang can you further explain the same with your code??

The code that generates the debug log is here: ChinChangYang@baac89b

Basically, I printed the input object of the cast operation which throws the AttributeError. Then, I traced the operation which generated the input object of the cast operation, and printed its input and output objects in that function.

In this case, the input object y of the cast operation which throws the AttributeError has been printed as follows:

y=%model/tf.math.sqrt/Sqrt: (fp32)*(Scalar) type=<class 'coremltools.converters.mil.mil.var.Var'>
y.val=22.627416610717773 type=<class 'float'>
y.sym_val=22.627416610717773 type=<class 'float'>
y.sym_type=<class 'coremltools.converters.mil.mil.types.type_double.make_float.<locals>.double'> type=<class 'type'>
File "/Users/chinchangyang/miniconda3/envs/lczero-training-py3.11/lib/python3.11/site-packages/coremltools/converters/mil/mil/ops/defs/iOS15/elementwise_unary.py", line 894, in get_cast_value
    return input_var.val.astype(dtype=string_to_nptype(dtype_val))
           ^^^^^^^^^^^^^^^^^^^^
AttributeError: 'float' object has no attribute 'astype'

Then, I traced the Sqrt operation, which generated y, and printed its input and output objects:

[957/987] Converting Sqrt op 'model/tf.math.sqrt/Sqrt'
x(input)=%model/tf.cast/Cast: (fp32)*(Scalar)
x(output)=%model/tf.math.sqrt/Sqrt: (fp32)*(Scalar)
x.val=22.627416610717773
x.sym_val=22.627416610717773
x.sym_type=<class 'coremltools.converters.mil.mil.types.type_double.make_float.<locals>.double'>

In the above log, the input object of the Sqrt operation is from Cast. I printed variables in the Cast operation:

[954/987] Converting Cast op 'model/tf.cast/Cast'
x(input)=%model/tf.__operators__.getitem/strided_slice: (int32)*(Scalar)
x(output)=%model/tf.cast/Cast: (fp32)*(Scalar)
x.val=512.0
x.sym_val=512.0
x.sym_type=<class 'coremltools.converters.mil.mil.types.type_double.make_float.<locals>.double'>

The input object of the Cast operation is from strided_slice. I printed variables in the strided_slice operation:

[952/987] Converting StridedSlice op 'model/tf.__operators__.getitem/strided_slice'
x=%model/tf.compat.v1.shape/Shape: (3,int32)*(Tensor) type=<class 'coremltools.converters.mil.mil.var.Var'>
x.val=[  1  64 512] type=<class 'numpy.ndarray'>
x.sym_val=[  1  64 512] type=<class 'numpy.ndarray'>
x.sym_type=<class 'coremltools.converters.mil.mil.types.type_tensor.tensor.<locals>.tensor'> type=<class 'type'>
begin=[-1] type=<class 'list'>
end=[0] type=<class 'list'>
stride=[1] type=<class 'list'>
x(after)=%model/tf.__operators__.getitem/strided_slice: (int32)*(Scalar) type=<class 'coremltools.converters.mil.mil.var.Var'>
x.val=512 type=<class 'numpy.int32'>
x.sym_val=512 type=<class 'numpy.int32'>
x.sym_type=<class 'coremltools.converters.mil.mil.types.type_int.make_int.<locals>.int'> type=<class 'type'>

This is the final node that I traced to debug. In strides_slice operation, I added print statement as follows:

     print(f"x={x} type={type(x)}")
     print(f"x.val={x.val} type={type(x.val)}")
     print(f"x.sym_val={x.sym_val} type={type(x.sym_val)}")
     print(f"x.sym_type={x.sym_type} type={type(x.sym_type)}")
     print(f"begin={begin} type={type(begin)}")
     print(f"end={end} type={type(end)}")
     print(f"stride={stride} type={type(stride)}")

     x = mb.slice_by_index(
         x=x,
         name=node.name,
        begin=begin,
        end=end,
        stride=stride,
        begin_mask=begin_mask,
        end_mask=end_mask,
         squeeze_mask=squeeze_mask,
     )

     print(f"x(after)={x} type={type(x)}")
     print(f"x.val={x.val} type={type(x.val)}")
     print(f"x.sym_val={x.sym_val} type={type(x.sym_val)}")
     print(f"x.sym_type={x.sym_type} type={type(x.sym_type)}")

     context.add(node.name, x)

Then, I saw x is Tensor: x=%model/tf.compat.v1.shape/Shape: (3,int32)*(Tensor) type=<class 'coremltools.converters.mil.mil.var.Var'>, but x(after) is Scalar: x(after)=%model/tf.__operators__.getitem/strided_slice: (int32)*(Scalar) type=<class 'coremltools.converters.mil.mil.var.Var'>.

I am not saying converting a Tensor to a Scalar is a logical bug, but when I try to write a minimum code to reproduce this issue, it is not easy to me to generate a Scalar input. Somehow, the input object is always Tensor in my test code.

@Suraj209211
Copy link

Okay I got your thought on it. Let me work out on the stuff and get back to you

@TobyRoseman TobyRoseman added the tf2.x / tf.keras Issue could be related to tf2.x where coremltools isn't supported (component) label Jan 2, 2024
@ChinChangYang
Copy link
Contributor Author

Fixed by #2087.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Unexpected behaviour that should be corrected (type) tf2.x / tf.keras Issue could be related to tf2.x where coremltools isn't supported (component)
Projects
None yet
Development

No branches or pull requests

3 participants