Skip to content

perf(runtime): skip TensorRT engine fakification during export by reporting tracing_mode "real" - #4489

Open
Conarnar wants to merge 1 commit into
pytorch:mainfrom
Conarnar:fix/trtengine-tracing-mode-real
Open

perf(runtime): skip TensorRT engine fakification during export by reporting tracing_mode "real"#4489
Conarnar wants to merge 1 commit into
pytorch:mainfrom
Conarnar:fix/trtengine-tracing-mode-real

Conversation

@Conarnar

Copy link
Copy Markdown
Contributor

Description

torch.export fakifies every TorchBind script object it traces through, and for a TensorRT engine that is expensive twice over:

  • maybe_to_fake_obj calls __obj_flatten__, which runs TRTEngine::serialize() — a full cuda_engine->serialize() plus base64 — and FakeTRTEngine.__obj_unflatten__ then base64-decodes it again.
  • FakeScriptObject.__init__ deep-copies the real object, which for a TorchBind class goes through def_pickle: serialize, then a full deserializeCudaEngine of a second copy onto the device.

The fake never reads any of it. FakeTRTEngine assigns the blob to self.serialized_engine and every field it actually uses is metadata. ExecuTorch re-runs decompositions during to_edge_transform_and_lower, so this happens roughly three times per engine, and the cost grows with engine count and size.

torch already provides the opt-out: tracing_with_real() returns True for an object whose tracing_mode() reports "real", and maybe_to_fake_obj then hands the real object to the meta kernel untouched. This adds that method to the TorchBind engine.

Why this is safe

fake_tensorrt_execute_engine already handles being given a real engine: it branches on real_obj and otherwise calls get_serialized_metadata() directly, taking output shapes from the symbolic expressions stored in the engine's metadata. Nothing executes and nothing mutates the engine during tracing.

The Python TRTEngine has reported "real" for exactly this reason since it was added — its docstring cites tracing_with_real. The TorchBind class simply never did the same.

Measurements

The mechanism is torch.export fakification, so any export carrying TensorRT engines benefits; the numbers below come from a two-layer Gemma4-MoE exported through the hybrid TensorRT + CUDA ExecuTorch path (3 engines), fresh Inductor cache, otherwise identical runs:

wall fakification
before 706.3 s 517.9 s
after 180.4 s 0.0 s

The exported program is unchanged: same delegate count, operators and values, and byte-identical delegate payloads.

Testing

Verified by rebuilding and re-running the export above with no patches: fakification drops to zero and the artifact is byte-identical to the baseline. Existing tests/py/dynamo/executorch and tests/py/dynamo/lowering/test_buffer_lifting.py pass (75).

No automated test is included. Nothing in tests/ currently exercises fakification of an engine, and the meaningful property — that export stops serializing the engine per fakify call — is a timing assertion. The cheapest real check would be asserting tracing_mode() == "real" on a built engine, which requires a GPU. Happy to add that if you want it gated.

torch.export fakifies every torchbind script object it traces through. For a
TensorRT engine that is enormously expensive twice over: maybe_to_fake_obj calls
__obj_flatten__, which runs TRTEngine::serialize() (a full
cuda_engine->serialize() plus base64) and then base64-decodes it again in
FakeTRTEngine.__obj_unflatten__, and FakeScriptObject.__init__ deep-copies the
engine through its pickle, which serializes and then fully deserializes another
copy onto the device. The fake stores the resulting blob and never reads it --
every field it uses is metadata. ExecuTorch re-runs decompositions during
to_edge_transform_and_lower, so this happens roughly three times per engine, and
the cost grows with engine count and size.

torch offers an opt-out: tracing_with_real() returns True for objects whose
tracing_mode() reports "real", and maybe_to_fake_obj then hands the real object
to the meta kernel untouched. fake_tensorrt_execute_engine already handles that
case -- it branches on real_obj and otherwise reads get_serialized_metadata(),
taking output shapes from the stored symbolic expressions -- so nothing executes
or mutates the engine during tracing. The Python TRTEngine has reported "real"
for this reason since it was added; the TorchBind class simply never did.

Measured on a 2-layer Gemma4-MoE hybrid TensorRT + CUDA ExecuTorch export
(3 engines): 706s -> 180s wall, with the fakification phase going from 518s to
0.0s. The exported program is unchanged -- identical delegate count, operators,
values, and byte-identical delegate payloads.
@meta-cla meta-cla Bot added the cla signed label Aug 14, 2026
@github-actions github-actions Bot added component: core Issues re: The core compiler component: runtime labels Aug 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant