onnx2tf

repository·main·Indexed 21 days ago

https://github.com/pinto0309/onnx2tf

A conversion tool for transforming ONNX files into LiteRT, TFLite, TensorFlow, and PyTorch formats. It supports generating PyTorch native code (nn.Module), TorchScript (.pt), state_dict (.pt), Exported Program (.pt2), and Dynamo ONNX, as well as direct conversion from LiteRT to PyTorch. The tool features a high-performance 'flatbuffer_direct' backend for fast conversion and a 'tf_converter' for a wider range of ONNX operator support.

Tokens
159K
Snippets
237
Records
604
Agent score
73%

What's inside onnx2tf

  1. Overview of onnx2tf capabilities

    main

    onnx2tf is a conversion tool designed to transform ONNX files into various formats and codebases, including:

    • LiteRT/TFLite/TensorFlow
    • PyTorch native code (nn.Module)
    • TorchScript (.pt)
    • state_dict (.pt)
    • Exported Program (.pt2)
    • Dynamo ONNX

    It also supports direct conversion from LiteRT to PyTorch.

    Note: For certain use cases, the maintainers recommend using LiteRT Torch or AI Edge Quantizer instead of onnx2tf.

  2. Compatibility and API stability of onnx2tf (v2.6.6)

    main

    The refactoring of the flatbuffer_direct backend in version 2.6.6 maintains full backward compatibility for end-users.

    • Public API: The public CLI and Python API remain unchanged.
    • Default Backend: flatbuffer_direct remains the default backend.
    • Artifacts: Existing artifact names, report formats, and return behaviors are preserved.
    • Dependencies: No new dependencies were added. Normal direct TFLite conversion and the -cotof flag do not require or import TensorFlow.
    • TensorFlow Support: Optional SavedModel/H5/Keras/TFv1 behavior remains behind the existing TensorFlow-optional boundary.
  3. Summary of fb-refactor7 improvements

    main

    The fb-refactor7 update focuses on improving diagnostic bookkeeping efficiency, stabilizing reconciliation and convergence fast paths, and ensuring explicit mutation evidence and result propagation. Key improvements include:

    • Diagnostic Bookkeeping: Many internal processes (like singleton/consecutive-reshape fallbacks, Swish transpose-passthrough, and various Conv1D unary owners) have been refactored to use fixed-key dictionaries for observation-only statistics. These are unconsumed and used for diagnostic purposes without changing core logic.
    • Stability and Convergence: Improvements to stable-reconciliation and convergence fast paths.
    • Result Propagation: Refined orchestration boundaries (e.g., duplicate-fanout/quantized-PReLU and boundary-BatchMatMul/input-unary) now propagate nested evidence instead of None slots, preserving parent arity and child order.
    • Pruning and Reconciliation: A new two-pass-only run_indexed_prune_reconcile_cleanup() owner shares a single ModelIRGraphIndex across dead-op pruning and static-shape reconciliation boundaries.
    • Binary Adapters: An indexed binary-adapter runner has been implemented for exact and singleton rank-four binary-adapter pairs, sharing a ModelIRGraphIndex and using indexed candidate/mutation APIs.
  4. Overview of flatbuffer-direct layout refactor passes

    main

    The flatbuffer-direct execution path in onnx2tf has undergone a significant refactor to improve terminal shape handling and binary layout adaptation. This refactor introduces a series of specialized optimization passes designed to handle complex operator chains (like Concat, Mul, Add, Reshape, Transpose, and Attention) while maintaining strict topology, rank-four metadata, and QDIM (Quantized Dimension) remapping.

    Key improvements across the new passes include:

    • Strict Metadata Preflight: Ensures rank-four metadata and topology are validated before mutation.
    • Ownership-Aware Constant Handling: Implements type-safe handling for INT32 constants used in Slice, Pad, and Shape operations.
    • QDIM Remapping: Ensures dynamic signatures and quantized dimensions are correctly preserved during layout transformations.
    • Provenance-Preserving Clones: Maintains the origin of shared constants and permutations during layout changes.
    • Indexed Setters and Batched Removal: Uses a structured approach to update the ModelIRGraphIndex and remove redundant nodes safely.
  5. Optimization: Attention Gather Cleanup Layout

    main

    The attention_gather_cleanup_layout pass (located in passes/attention_gather_cleanup_layout.py) optimizes the attention tail by rewriting Gather/Transpose/Reshape sequences.

    Key behaviors and constraints:

    • Pattern A: Handles rank-four/rank-three shape algebra and permutation options. It performs rank-lifting on Transpose operations and preserves dynamic axes by remapping per-axis QDIM.
    • Pattern B: Handles singleton-axis removals and ensures quantization equivalence between the original and the rewritten Reshape boundaries.
    • Input Requirements: Index, permutation, and reshape-shape tensors must follow an explicit unquantized INT32 TensorIR/buffer contract.
    • Safety Guarantees: The pass rejects public inputs, variables, runtime producers, and quantized constants to prevent illegal mutations. It ensures that a zero-match invocation results in a complete no-op rather than pruning unrelated tensors.
  6. How ModelIRGraphIndex optimizes graph traversal

    main

    The ModelIRGraphIndex is a central abstraction used to avoid quadratic complexity during graph transformations. Instead of rescanning the operator list for every boundary or consumer, the index provides:

    • Single-pass Discovery: Producer discovery and forward reachability are achieved in one scan.
    • Sorted Consumer Queries: Consumer indices are maintained in sorted graph order. This allows for efficient suffix queries using ModelIRGraphIndex.has_consumer_at_or_after(), which only needs to check the last index rather than iterating through a generator.
    • Dependency-safe Split-point Discovery: Uses one producer scan and one consumer edge scan to identify boundaries, making the runtime proportional to the number of operators and edges rather than boundary_count * edge_count.
  7. How GraphIndex and ModelIRGraphIndex manage differential mutations

    main

    The project uses GraphIndex (for ONNX) and ModelIRGraphIndex (for ModelIR) to provide differential mutation contracts. This allows rewriters to update the graph without rescanning the entire operator list.

    • ONNX Rewriters: Notify the index of node input/output updates and node registration/removal.
    • ModelIR Rewriters: Can replace inputs/outputs or insert/remove operators. The index maintains consistency for producer, consumer, duplicate-producer, operator-position, and operator-type indices.
    • Operator-type Index: Returns graph-order positions. When operators are inserted or removed, this index is shifted alongside edge indices, allowing bounded passes to enumerate only relevant operator families.
    • refresh(): A full refresh is available for compatibility with external mutations that bypass the standard APIs.
  8. Understand the flatbuffer_direct architecture pipeline

    main

    The flatbuffer_direct architecture is a high-performance execution path designed to optimize ONNX to TensorFlow conversion by minimizing redundant graph scans and deep copies. It relies on several key architectural principles:

    • Efficient Graph Indexing: Uses ModelIRGraphIndex to perform producer/consumer discovery and reachability analysis in a single pass, rather than rescanning the entire operator list for every operation.
    • Append-only Rewriting: Structural rewrites (like Group-convolution expansion or BatchMatMul unfolding) use a _ModelIRRewriteBuilder that emits operators directly into a new stream, avoiding the overhead of cloning the entire source graph first.
    • Copy-on-Write (CoW) Semantics: For operations like PyTorch WHILE expansion, the system uses a 'preflight' check. If no changes are needed, it returns a borrowed reference to the input. If expansion is required, it performs a deep clone before mutation.
    • Torch-free Compatibility Passes: Many critical conversion passes (PyTorch layout cleanup, control flow, recurrent ops, and layout validation) are implemented as standalone, Torch-free modules. This allows for deterministic, testable, and efficient transformations without the overhead of a full PyTorch runtime.
  9. Pre-terminal InstanceNorm Layout Composite Cleanup

    main

    Following the optional late-binary layout recovery, the process executes a composite cleanup for InstanceNorm layout repairs. This involves three specific passes executed in a fixed order using the same ModelIR and conversion-local LayoutState:

    1. post-bias
    2. residual-Mul/Concat
    3. dual-stat residual-Add/Resize

    This composite operation is managed by run_pre_terminal_instancenorm_layout_cleanup(shared_model_ir_pass_context). It is designed to perform these repairs without summarizing counters or recording phase evidence into the main phase store.

  10. How Conv1D-shim unary fan-out bypass works

    main

    The Conv1D-shim unary fan-out bypass (in passes/conv1d_unary_layout.py) handles cases where the rank-three unary output is used by both a standard NHWC reconstruction branch AND a side branch (e.g., a public graph output or a later NCHW consumer).

    Optimization Logic

    Instead of leaving the legacy helper's non-topological order, the pass reorders the operators to ensure a topological flow:

    1. The Unary operator is moved to consume the original NHWC source directly.
    2. The Retained Transpose consumes the unary output.
    3. The Retained Squeeze produces the former unary output for the NCHW side consumer.
    4. The ExpandDims and post-Transpose operators are removed.

    This ensures that the NCHW side consumer receives the correct values while maintaining the original unary object's identity and provenance.

  11. Identify Quantized-PReLU cleanup characteristics

    main

    The quantized-PReLU cleanup process follows these rules:

    • Result Format: Produces a fixed four-key result.
    • Priorities: Executes four transactional default passes with priorities ranging from 10 to 40.
    • Orchestration: Includes one direct lowerer call and one nested duplicate-fanout orchestration selection sharing a pass-state scope.
    • Observation Target: _layout_pass_set_1_quantized_prelu_stats.
    • Boundaries: Operates at the attention-gate/dequant-TransposeConv boundary.
  12. Repair recurrent orphan-step aliases

    main

    The recurrent orphan-step alias repair process (managed by passes/recurrent_alias.py::repair_orphan_recurrent_step_tensors) fixes tensor naming issues in recurrent models.

    It works by:

    1. Preflighting tensor names using the *_h_step_N/*_c_step_N grammar.
    2. Using a ModelIRGraphIndex to find the first valid Reshape among indexed consumers of the corresponding *_step_shape_N tensor.
    3. Rewriting indexed alias consumers in place.
    4. Removing non-public orphan tensor metadata while preserving public output metadata.

    This process is shared by both direct lowering and PyTorch export paths.