Skip to content

Releases: PINTO0309/onnx2tf

1.28.3

26 Oct 12:45
4b6aa66

Choose a tag to compare

  -agje, --auto_generate_json_on_error
    Attempts to generate a parameter replacement JSON when accuracy validation finds errors
    greater than 1e-2. Useful for quickly capturing fixes during -cotof runs.
    Disabled by default to avoid unexpected file generation.

What's Changed

Full Changelog: 1.28.2...1.28.3

1.28.2

22 Jul 13:19
2bff6c8

Choose a tag to compare

  • MatMul
    Op MatMul improved resource usage for matrix shape compatibility check.

    1. Content and background
      The MatMul op converter tries to numerically optimize operation M=A*B. To only optimize compatible shapes, a check is present. The current check uses np.matmul on dummy matrices to verify the output shape is compatible with expected shape. For some of the compatible shapes (due to broadcasting), this can consume significant resources both in compute time and memory.

    2. Summary of corrections
      Add a function to compute shape returned via np.matmul without actually running the np.matmul. In case the function fails (incompatible shapes) and returns None, use current implementation with np.matmul to verify the result (based on my internal unit tests it seems np.matmul can be safely removed, but I left it as it no longer poses threat of high resource usage).

What's Changed

  • Op MatMul improved resource usage for matrix shape compatibility check by @radekzc in #780

Full Changelog: 1.28.1...1.28.2

1.28.1

06 Jul 10:46
1ad48ae

Choose a tag to compare

  • Fix boolean parameter replacement

    The replace_parameter function converts parameter values from JSON replacement files into appropriate Python types during ONNX model conversion. A case-sensitivity bug prevented proper conversion of the capitalized boolean string "True", causing it to remain as a string instead of being converted to boolean True, which affects both the parameter replacement feature and the new auto-JSON generation feature.

    The bug occurred because the code called .lower() on the input string (converting "True""true") but then compared against "True" (capital T), so "true" == "True" returned False and conversion failed. The fix was to change the comparison from replace_value.lower() == "True" to replace_value.lower() == "true". Note that "False" was not affected as it correctly compared against "false".

    Use the following program to test it:

    import sys
    from onnx2tf.utils.common_functions import replace_parameter
    
    result = replace_parameter(
        value_before_replacement=False,
        param_target='test',
        param_name='test', 
        op_rep_params=[{'param_target': 'test', 'param_name': 'test', 'values': 'True'}]
    )
    
    print(f'Output: {result} (type: {type(result).__name__})')

What's Changed

Full Changelog: 1.28.0...1.28.1

1.28.0

19 Jun 13:56
5596d54

Choose a tag to compare

  • [Experimental] Added automatic JSON generation function

  • Currently, this is a trial implementation and only supports a very limited number of OPs. If I feel like it, I will expand the OPs that are the target of JSON auto-generation.

  • https://github.com/PINTO0309/onnx2tf/blob/main/AUTO_JSON_FEATURE_SUMMARY.md

    # Automatic JSON generation only
    # Generates an optimal parameter replacement JSON file for model conversion.
    # The JSON file is saved to {model_name}_auto.json when conversion errors occur
    # or accuracy issues are detected.
    onnx2tf -i model.onnx -agj
    
    # Accuracy validation only (no JSON generation)
    # Validates the accuracy between ONNX and TensorFlow outputs without generating
    # any parameter replacement JSON file.
    onnx2tf -i model.onnx -cotof
    
    # Accuracy validation + automatic JSON generation
    # First generates an optimal parameter replacement JSON file, then uses it
    # to validate the model accuracy. This ensures the best possible conversion accuracy.
    onnx2tf -i model.onnx -agj -cotof
    -agj, --auto_generate_json
      Automatically generates a parameter replacement JSON file that achieves minimal error
      when converting the model. This option explores various parameter combinations to find
      the best settings that result in successful conversion and highest accuracy.
      The search stops when the final output OP accuracy check shows "Matches".
      When used together with -cotof, the generated JSON is used to re-evaluate accuracy.
      WARNING: This option performs an exhaustive search to find the optimal conversion patterns,
      which can take a very long time depending on the model complexity.
  • onnx2tf doesn't work after exporting PINTO0309/LightGlue-ONNX #772

What's Changed

  • [Experimental] Added automatic JSON generation function by @PINTO0309 in #773

Full Changelog: 1.27.10...1.28.0

1.27.10

21 May 23:52
349d80e

Choose a tag to compare

What's Changed

  • Fixed handling of dynamic tensors in broadcast_for_gpu_delegate by @PINTO0309 in #769

Full Changelog: 1.27.9...1.27.10

1.27.9

18 May 10:59
06870c1

Choose a tag to compare

  • onnx2tf.py, common_functions.py

  • replace_yolov9t_dynamic.json

    • Support for shape_hints.

    • With the addition of this feature, conversion is now possible even when there are multiple dynamic dimensions other than batch size. It can be used mainly for debugging by arbitrarily changing the size of intermediate tensors.

    • You can now specify input tensors of any size for accuracy evaluation using the -cotof and -coto options.

    • The introduction of shape_hints is the first step toward implementing a feature that automatically corrects conversion errors in models with dynamic tensor inputs within the onnx2tf processing.

    • In future versions, I plan to make the --shape_hints option mandatory when specifying models that use dynamic tensors as input.

      • CLI
        -sh SHAPE_HINTS [SHAPE_HINTS ...], \
            --shape_hints SHAPE_HINTS [SHAPE_HINTS ...]
          Shape hints for input tensors containing dynamic dimensions.
          Specify input shapes for test inference with -cotof or -coto.
          Unlike `--overwrite_input_shape`, this operation does not overwrite
          the ONNX input shape with a static shape.
          The format is
          "i1:dim0,...,dimN" "i2:dim0,...,dimN" "i3:dim0,...,dimN"
          When there is only one input, for example,
          "data:1,3,224,224"
          When there are multiple inputs, for example,
          "data1:1,3,224,224" "data2:1,3,112" "data3:5"
          A value of 1 or more must be specified.
          Numerical values other than dynamic dimensions are ignored.
        
      • In-Script
        shape_hints: Optional[List[str]]
          Shape hints for input tensors containing dynamic dimensions.
          Specify input shapes for test inference with -cotof or -coto.
          Unlike `--overwrite_input_shape`, this operation does not overwrite
          the ONNX input shape with a static shape.
          The format is
          ['i1:dim0,...,dimN', 'i2:dim0,...,dimN', 'i3:dim0,...,dimN']
          When there is only one input, for example,
          ['data:1,3,224,224']
          When there are multiple inputs, for example,
          ['data1:1,3,224,224', 'data2:1,3,112', 'data3:5']
          A value of 1 or more must be specified.
          Numerical values other than dynamic dimensions are ignored.
        
    • Example of use with YOLOv9-T [N, 3, H, W]

      JSON replace_yolov9t_dynamic.json
      {
        "format_version": 1,
        "operations": [
          {
            "op_name": "/model.22/Gather",
            "param_target": "inputs",
            "param_name": "/model.22/Constant_output_0",
            "values": 0
          },
      
      
      
          {
            "op_name": "/model.22/Gather_3",
            "param_target": "inputs",
            "param_name": "/model.22/Constant_6_output_0",
            "values": 1
          },
          {
            "op_name": "/model.22/Gather_4",
            "param_target": "inputs",
            "param_name": "/model.22/Constant_7_output_0",
            "values": 2
          },
          {
            "op_name": "/model.22/Gather_5",
            "param_target": "inputs",
            "param_name": "/model.22/Constant_6_output_0",
            "values": 1
          },
          {
            "op_name": "/model.22/Gather_6",
            "param_target": "inputs",
            "param_name": "/model.22/Constant_7_output_0",
            "values": 2
          },
          {
            "op_name": "/model.22/Gather_1",
            "param_target": "inputs",
            "param_name": "/model.22/Constant_6_output_0",
            "values": 1
          },
          {
            "op_name": "/model.22/Gather_2",
            "param_target": "inputs",
            "param_name": "/model.22/Constant_7_output_0",
            "values": 2
          },
      
      
      
          {
            "op_name": "/model.22/Concat_23",
            "param_target": "attributes",
            "param_name": "axis",
            "values": 2
          },
          {
            "op_name": "/model.22/Slice",
            "param_target": "op",
            "begin": [0,0,0],
            "end": [0,64,0],
            "end_mask": 5
          },
          {
            "op_name": "/model.22/dfl/Gather",
            "param_target": "inputs",
            "param_name": "/model.22/Constant_output_0",
            "values": 0
          },
          {
            "op_name": "/model.22/dfl/Gather_1",
            "param_target": "inputs",
            "param_name": "/model.22/Constant_6_output_0",
            "values": 2
          },
      
      
      
          {
            "op_name": "/model.22/dfl/Reshape",
            "param_target": "inputs",
            "param_name": "/model.22/dfl/Concat_output_0",
            "pre_process_transpose_perm": [0,2,1]
          },
          {
            "op_name": "/model.22/dfl/Reshape",
            "param_target": "inputs",
            "param_name": "/model.22/Slice_output_0",
            "pre_process_transpose_perm": [0,2,1]
          },
      
      
          {
            "op_name": "/model.22/dfl/Transpose",
            "param_target": "attributes",
            "param_name": "perm",
            "values": [0,2,1,3]
          },
      
          {
            "op_name": "/model.22/dfl/Softmax",
            "param_target": "attributes",
            "param_name": "axis",
            "values": 1
          },
          {
            "op_name": "/model.22/dfl/Softmax",
            "param_target": "outputs",
            "param_name": "/model.22/dfl/Softmax_output_0",
            "post_process_transpose_perm": [0,2,3,1]
          },
      
      
      
      
          {
            "op_name": "/model.22/Slice_1",
            "param_target": "op",
            "begin": [0,64,0],
            "end": [0,92,0],
            "end_mask": 5
          },
      
      
          {
            "op_name": "/model.22/Slice_2",
            "param_target": "op",
            "begin": [0,0,0],
            "end": [0,2,0],
            "end_mask": 5
          },
          {
            "op_name": "/model.22/Slice_3",
            "param_target": "op",
            "begin": [0,2,0],
            "end": [0,3,0],
            "end_mask": 5
          },
      
      
          {
            "op_name": "/model.22/Mul_3",
            "param_target": "inputs",
            "param_name": "/model.22/Transpose_1_output_0",
            "pre_process_transpose_perm": [1,0]
          },
          {
            "op_name": "/model.22/Concat_24",
            "param_target": "attributes",
            "param_name": "axis",
            "values": 1
          }
        ]
      }
    • convert

      onnx2tf \
      -i yolov9_t_wholebody28_Nx3HxW.onnx \
      -coion \
      -cotof \
      -sh "images:1,3,480,640" \
      -prf replace_yolov9t_dynamic.json \
      
    • results
      yolov9_t_wholebody28_Nx3HxW_float32.tflite.zip

      image

      image

  • FlexConv2d generated due to dynamic input shape? #759

What's Changed

Full Changelog: 1.27.8...1.27.9

1.27.8

18 May 03:53
a1a29b3

Choose a tag to compare

  • AveragePool

    • [Experimental] Dynamic AveragePool support
      image
      image
  • Tests
    https://github.com/PINTO0309/onnx2tf/releases/download/1.27.1/rec.onnx

    • replace_rec.json
      {
        "model": "https://github.com/PINTO0309/onnx2tf/releases/download/1.27.1/rec.onnx",
        "issue": "https://github.com/PINTO0309/onnx2tf/issues/747",
        "command": "onnx2tf -i rec.onnx -prf replace_rec.json",
        "format_version": 1,
        "operations": [
          {
            "op_name": "p2o.Transpose.2",
            "param_target": "attributes",
            "param_name": "perm",
            "values": [0,1,3,2]
          },
          {
            "op_name": "p2o.Transpose.5",
            "param_target": "attributes",
            "param_name": "perm",
            "values": [0,1,3,2]
          },
          {
            "op_name": "p2o.Transpose.7",
            "param_target": "attributes",
            "param_name": "perm",
            "values": [0,1,2,3]
          }
        ]
      }
    • Run
      onnx2tf -i rec.onnx -prf replace_rec.json -coion
      
      image
  • Results
    rec_float32.tflite.zip
    image
    image
    image

  • paddleocr model conversion to tflite fails #747

What's Changed

Full Changelog: 1.27.7...1.27.8

1.27.7

17 May 12:16
d1e19c7

Choose a tag to compare

  • onnx2tf.py, common_functions.py
    • Improved log display during dummy inference
      1. Remove display of tensorflow output OP names
      2. Add display of onnx and tensorflow tensor shapes when Skipped (Deleted or Shape Unmatched) occurs.
      3. Remove wa/.
    • This is mainly for debugging purposes when converting dynamic tensors.

image

What's Changed

Full Changelog: 1.27.6...1.27.7

1.27.6

16 May 08:48
0794998

Choose a tag to compare

What's Changed

Full Changelog: 1.27.5...1.27.6

1.27.5

16 May 02:23
1d79c6d

Choose a tag to compare

  • Unsqueeze, Slice
    • Supports individual parameter replacement for Unsqueeze and Slice
    • e.g.
      image
      image
      {
        "format_version": 1,
        "operations": [
          {
            "op_name": "Concat_551",
            "param_target": "attributes",
            "param_name": "axis",
            "values": 2
          },
          {
            "op_name": "Gather_560",
            "param_target": "attributes",
            "param_name": "axis",
            "values": 2
          },
          {
            "op_name": "Unsqueeze_655",
            "param_target": "attributes",
            "param_name": "axes",
            "values": [1]
          },
          {
            "op_name": "Slice_657",
            "param_target": "inputs",
            "param_name": "2062",
            "values": [0]
          },
          {
            "op_name": "Slice_657",
            "param_target": "inputs",
            "param_name": "2029",
            "values": [2]
          },
          {
            "op_name": "Slice_657",
            "param_target": "inputs",
            "param_name": "1538",
            "values": [3]
          },
          {
            "op_name": "Slice_657",
            "param_target": "inputs",
            "param_name": "2015",
            "values": [1]
          }
        ]
      }
  • Unable to convert RTMDet-ins to tflite #761

What's Changed

Full Changelog: 1.27.4...1.27.5