torch#
This page answers common “how do I…” questions for converting
torch models to ONNX with yobx.torch.interpreter.to_onnx().
How to choose how the FX graph is produced#
ExportOptions exposes three practical
ways to obtain the FX graph before ONNX conversion.
1) torch.export.export path (default)
Use strategy="nostrict" (default) or strategy="strict":
from yobx.torch.export_options import ExportOptions
from yobx.torch.interpreter import to_onnx
artifact = to_onnx(model, (x,), export_options=ExportOptions(strategy="nostrict"))
2) Symbolic FX tracing (CustomTracer)
Use strategy="tracing":
artifact = to_onnx(model, (x,), export_options=ExportOptions(strategy="tracing"))
3) Dispatch-based tracing (new-tracing)
Use strategy="new-tracing":
artifact = to_onnx(model, (x,), export_options=ExportOptions(strategy="new-tracing"))
Quick summary#
The table below summarizes not only capture/backend routing, but also how decomposition is handled and when each option is usually the most practical.
Option |
FX graph capture |
ONNX conversion backend |
Decomposition behavior |
Typical use |
|---|---|---|---|---|
|
yobx converter |
no explicit decomposition table by default; may still decompose only if inplace nodes cannot be removed directly |
preferred default when you want yobx ATen-level conversion coverage |
|
|
symbolic |
yobx converter |
no explicit decomposition table by default; tracing normalizes many inplace patterns up front |
useful when |
|
dispatch-based tracing |
yobx converter |
no explicit decomposition table by default; relies on new-tracing rewrites/patches for operator coverage |
useful for models/operators better captured through dispatch-level tracing |
|
handled by |
official exporter |
decomposition behavior follows the official exporter pipeline |
use when you want direct parity with |
How to trigger the official exporter#
The official exporter path is torch.onnx.export(). You can trigger it
through ExportOptions:
from yobx.torch.export_options import ExportOptions
from yobx.torch.interpreter import to_onnx
# direct torch.onnx.export(..., dynamo=True)
artifact = to_onnx(model, (x,), export_options=ExportOptions(strategy="onnxscript"))
How to read export and optimization statistics#
The returned ExportArtifact carries an
ExportReport in artifact.report.
<<<
import torch
from yobx.torch.interpreter import to_onnx
model = torch.nn.Sequential(
torch.nn.Linear(4, 8),
torch.nn.ReLU(),
torch.nn.Linear(8, 2),
).eval()
x = torch.randn(3, 4)
artifact = to_onnx(model, (x,), return_optimize_report=True)
print(artifact.report)
print(artifact.report.stats[:2]) # per-pattern optimization rows
print(artifact.report.extra.keys()) # timings, selected export options, counters
artifact.compute_node_stats()
print(artifact.report.node_stats[:2]) # per-op-type counts and estimated FLOPs
>>>
ExportReport(n_stats=669, extra=['builder', 'optimization', 'stat_time_export_and_post_processing', 'stat_time_post_process_exported_program', 'stat_time_torch_export_export_oblivious', 'time_export_builder_process', 'time_export_graph_module', 'time_export_to_onnx'], has_build_stats=False, n_node_stats=0, n_symbolic_flops=0, n_discrepancies=0)
[{'pattern': 'dynamic_dimension_naming', 'removed': 0, 'added': 0, 'time_in': 2.6520000005803013e-05}, {'pattern': 'check_A-dynamic_dimension_naming', 'time_in': 2.476700001352583e-05}]
dict_keys(['builder', 'time_export_graph_module', 'stat_time_export_and_post_processing', 'stat_time_post_process_exported_program', 'stat_time_torch_export_export_oblivious', 'time_export_builder_process', 'optimization', 'time_export_to_onnx'])
[{'op_type': 'Gemm', 'count': 2, 'flops': 318}, {'op_type': 'Relu', 'count': 1, 'flops': 24}]
The extra dictionary typically includes timing keys such as
time_export_graph_module and flags describing which export options won
the strategy fallback (for example onnx_export_options_strict or
onnx_export_options_decomp).
If filename="model.onnx" is passed, the converter also writes
model.xlsx with sheets such as extra, stats, stats_agg,
node_stats, and symbolic_flops.
How this differs from torch.onnx.export#
By default, yobx.torch.interpreter.to_onnx() does not apply an
explicit decomposition table, so ATen operators stay close to the original
graph and are translated directly by yobx converters. A decomposition pass may
still run if needed to eliminate inplace operations that could not be removed
directly.