Skip to main content

trt-strong-typing-migration

Migrate a TensorRT build from weak typing (deprecated 10.12, removed 11.0) to strong typing — across Python INetworkDefinition builders, the trtexec CLI, and C++ builder code. Use when a TRT 11 upgrade breaks a weakly-typed build. Triggers: weakly typed to strongly typed, kSTRONGLY_TYPED, weak typing deprecated, kFP16/kINT8 removed, setPrecision rejected, setComputePrecision deprecated, do I still need --stronglyTyped, how to add the kSTRONGLY_TYPED flag, ModelOpt autocast, INT8 on TRT 11. NOT for ONNX import (`trt-onnx-quickstart`), Torch-TRT (`trt-torch-quickstart`), or C++ deploy (`trt-cpp-runtime-quickstart`).

Informations de source

Dépôt
NVIDIA/TensorRT
Dernière activité de la source
24 juin 2026 à 21:24
Langue détectée de SKILL.md
anglais
Étoiles
13 405
Forks
2 414

Options d'installation

Le prompt qui vérifie d'abord la source est sélectionné par défaut. Vous pouvez passer à une commande directe ou télécharger une copie locale.

Vérifiez les fichiers source

Lisez SKILL.md et les fichiers associés affichés par SkillsMP avant de décider de l'installer.

Explorateur de fichiers
4 fichiers

Affichage de SKILL.md

SKILL.md
Instructions source · Aperçu en lecture seule
name
trt-strong-typing-migration
description
Migrate a TensorRT build from weak typing (deprecated 10.12, removed 11.0) to strong typing — across Python INetworkDefinition builders, the trtexec CLI, and C++ builder code. Use when a TRT 11 upgrade breaks a weakly-typed build. Triggers: weakly typed to strongly typed, kSTRONGLY_TYPED, weak typing deprecated, kFP16/kINT8 removed, setPrecision rejected, setComputePrecision deprecated, do I still need --stronglyTyped, how to add the kSTRONGLY_TYPED flag, ModelOpt autocast, INT8 on TRT 11. NOT for ONNX import (`trt-onnx-quickstart`), Torch-TRT (`trt-torch-quickstart`), or C++ deploy (`trt-cpp-runtime-quickstart`).
license
Apache-2.0
metadata
{"author":"NVIDIA Corporation","version":"1.0","tags":["migration","strong-typing","autocast","modelopt","builder"]}
# Migrate Weakly-Typed to Strongly-Typed TensorRT Build Strong typing is the recommended build mode for TensorRT 11.x; weak typing was deprecated in 10.12 and is scheduled for removal. This skill migrates a weakly-typed build flow to a strongly-typed equivalent, one path per entry point (Python network, `trtexec`, C++ builder), plus the ModelOpt AutoCast pre-step needed when the source is an ONNX file that must run in mixed precision. **Version behavior.** On **TensorRT 11.x strong typing is unconditional** — every network is strongly typed, the `kSTRONGLY_TYPED` creation flag is accepted but ignored, and `trtexec --stronglyTyped` is a no-op (default-on). On **10.12–10.x** you opt in explicitly via that flag / `--stronglyTyped`. Setting it is therefore always safe: required on 10.x, harmless on 11.x. Either way the migration is the same — remove the precision *hints* (gone in 11.x) and move precision into the graph. ## When to Use | Scenario | Use this skill? | |----------|-----------------| | Existing Python build calls `config.set_flag(trt.BuilderFlag.FP16 / INT8 / TF32)` | Yes | | Existing C++ build calls `config->setFlag(BuilderFlag::kFP16 / kINT8 / kTF32)` | Yes | | Existing `trtexec` line uses `--fp16`, `--int8`, `--best`, `--bf16` and the developer wants strong typing | Yes | | Build emits "weak typing is deprecated, use STRONGLY_TYPED" warning at runtime | Yes | | Build fails with "flag X is incompatible with strongly typed networks" | Yes | | Developer has a FP32 ONNX file and wants a strongly-typed mixed FP16 engine | Yes — start at Step 1 (AutoCast) | | Developer is importing a brand-new ONNX file with no existing build flow | No — use `trt-onnx-quickstart` first; come back here to switch the flag | | Developer's engine produces wrong outputs *after* migration | No — use `trt-quantization-accuracy` | | Developer is on TensorRT 10.11 or earlier | No — strong typing is fully available from 10.12 onward; upgrade before migrating | ## Prerequisites 1. **TensorRT 10.12 or later (11.x recommended).** Check: ```bash python3 -c "import tensorrt; print(tensorrt.__version__)" trtexec --help 2>&1 | grep -i stronglyTyped ``` The version check is the determinant — strong typing is available from 10.12 on. The `trtexec` probe just confirms the CLI flag for the trtexec path; a missing `--stronglyTyped` means a pre-10.12 install. 2. **ModelOpt installed when the source is an ONNX file requiring mixed precision.** ```bash pip install nvidia-modelopt onnx onnxruntime ``` If the ONNX file is already strongly typed (contains explicit `Cast` nodes and FP16 initializers), AutoCast is not needed — skip directly to Step 2. 3. **A working baseline.** Capture the weakly-typed engine's outputs on a known input set before migrating. Strong typing is stricter, and any silent precision substitutions weak typing was making will become observable. 4. **The verifier script.** `scripts/verify.sh` runs `migrate.py` against a committed sample and asserts the rewrite is well-formed. Run it before editing anything to confirm the helper works. ## Migration paths There are three migration paths — Python builder, `trtexec`, C++ builder. **Infer the path from the query when signals are clear; ask only if genuinely uncertain.** Match the strongest signal: | Signal in the request | Path | Entry point | |------------------------|------|-------------| | Python tokens: `trt.BuilderFlag`, `set_flag(`, `create_network(`, `.py` | **A** | Python `INetworkDefinition` builder | | Standalone `trtexec --fp16` / `--int8` / `--best` / `--bf16` | **B** | `trtexec` CLI | | C++ tokens: `BuilderFlag::`, `createNetworkV2`, `->setFlag`, `.cpp` / `.h` | **C** | C++ builder | | Multiple signals | — | do each, most-specific first | | No usable signal (generic "how do I migrate") | — | ask which entry point, or proceed with Python and say you assumed it | The migration preserves existing precisions (kFP16 → FP16 cast, kINT8 → Q/DQ) and is identical whether the network came from a parser or was hand-built — only Step 1 (AutoCast) is ONNX-specific, so source and precision goal rarely need a question. Inferring the path is a low-stakes default — it does **not** extend to destructive operations, which always need confirmation. `migrate.py` defaults to dry-run (prints a diff); the `--write` flag is the human-in-the-loop confirmation. Treat any other destructive step (overwriting a `.plan`, replacing an ONNX) the same way: show, confirm, then act. For a strongly-typed INT8 model straight from an ONNX file (not a migration of existing builder code), jump to Step 1's ModelOpt quantization recipe. ## Step 1 — (ONNX source only) AutoCast the model to mixed precision Skip if the source is not ONNX, or if the ONNX file is already strongly typed. A FP32 ONNX file built for a weakly-typed `--fp16` flow carries no precision information — TensorRT was free to pick FP16 or FP32 per layer. Strong typing requires the graph itself to declare precision via `Cast` operators and typed initializers. ModelOpt's AutoCast inserts these. Use the ModelOpt CLI — it's the supported entry point and takes `.npz` calibration directly. Use `--calibration_data` for both tools (autocast's canonical flag; quantization's abbreviation of `--calibration_data_path`): ```bash # FP16 / BF16 mixed-precision AutoCast python -m modelopt.onnx.autocast \ --onnx_path model.fp32.onnx \ --output_path model.mixed.onnx \ --low_precision_type fp16 \ --calibration_data calib.npz # INT8 / FP8 strongly-typed quantization (produces ONNX with explicit Q/DQ) python -m modelopt.onnx.quantization \ --onnx_path model.fp32.onnx \ --output_path model.int8.onnx \ --quantize_mode int8 \ --high_precision_dtype fp16 \ --calibration_data calib.npz ``` Keep accuracy-sensitive ops in FP32 via AutoCast's node/op-type exclusion lists (e.g. exclude `MatMul`/`LayerNormalization` on transformer-heavy networks), and keep FP32 graph I/O when downstream stages expect it. See the [Model Optimizer docs](https://nvidia.github.io/Model-Optimizer) for the exact module and flags for your ModelOpt version. Verify the converted model in ONNX Runtime before passing it to TRT: ```python import onnxruntime, numpy as np sess = onnxruntime.InferenceSession("model.mixed.onnx", providers=["CPUExecutionProvider"]) # Compare a few outputs against the FP32 model with np.allclose(..., rtol=5e-3, atol=5e-3). ``` If parity fails here, **stop** — the conversion is wrong and no amount of TRT engine work will recover it. Re-run with tighter exclusion lists. **Next step — build the strongly-typed plan from the converted ONNX:** ```bash # For the INT8 case (modelopt.onnx.quantization output) trtexec --onnx=model.int8.onnx --stronglyTyped --saveEngine=model.int8.plan # For the mixed-precision case (modelopt.onnx.autocast output) trtexec --onnx=model.mixed.onnx --stronglyTyped --saveEngine=model.fp16.plan ``` **Critical**: do NOT pass `--int8` or `--fp16` alongside `--stronglyTyped`. Those flags are removed in TRT 11, and on TRT 10.12+ they conflict with strong typing. The precision is already encoded in the ONNX (via explicit Cast / Q / DQ nodes); the builder honors it. The reference recipe for the end-to-end INT8 flow is `samples/python/strongly_type_autocast/sample.py` in `tensorrt-oss`. ## Step 2A — Migrate a Python `INetworkDefinition` builder Mechanical replacements: | Weakly typed | Strongly typed | |--------------|----------------| | `builder.create_network(0)` or `builder.create_network(1 << int(NetworkDefinitionCreationFlag.EXPLICIT_BATCH))` | `builder.create_network(1 << int(NetworkDefinitionCreationFlag.STRONGLY_TYPED))` | | `config.set_flag(trt.BuilderFlag.FP16)` | **Remove.** Types come from the network. | | `config.set_flag(trt.BuilderFlag.BF16)` | **Remove.** | | `config.set_flag(trt.BuilderFlag.INT8)` | **Remove.** Quantization expressed via Q/DQ nodes in the graph. | | `config.set_flag(trt.BuilderFlag.TF32)` | **Keep.** `kTF32` is retained in 11.x — it allows (not requires) TF32 for FP32 tensors and is orthogonal to typing. | | `layer.precision = trt.float16` | **Remove.** Cast the input tensor instead (`network.add_cast`). | | `layer.set_output_type(0, trt.float16)` | **Remove.** Output type follows the network; for cast/quantize/dequantize/fill layers use `set_to_type` instead. | | `builder.platform_has_fast_int8 / has_fast_fp16` checks gating the above | **Remove the gating logic** along with the flag. | Worked rewrite (the MNIST builder from `samples/python/network_api_pytorch_mnist/sample.py` already uses the strongly-typed form — note `NetworkDefinitionCreationFlag.STRONGLY_TYPED` and the absence of any `BuilderFlag.FP16` call): ```python builder = trt.Builder(TRT_LOGGER) network = builder.create_network(1 << int(trt.NetworkDefinitionCreationFlag.STRONGLY_TYPED)) config = builder.create_builder_config() config.set_memory_pool_limit(trt.MemoryPoolType.WORKSPACE, common.GiB(1)) # ... populate network ... plan = builder.build_serialized_network(network, config) ``` If the network is built via the ONNX parser, the parser respects strong typing automatically — no code change is needed beyond the flag. Where a removed `precision` / `set_output_type` hint actually mattered, encode it in the graph: cast a tensor's dtype with `add_cast`, or insert an explicit Quantize/Dequantize pair for INT8 (the scale is a build-time constant; ModelOpt derives it from calibration, or supply it by hand): ```python # kFP16 hint -> explicit cast on the tensor: cast = network.add_cast(some_tensor, trt.float16) # kINT8 hint -> explicit Q/DQ pair (per-tensor scalar scale). NOTE: trt.Weights does # not copy the numpy buffer, so q_scale must stay alive until the engine is built. q_scale = np.array(1.0 / 127.0, dtype=np.float32).reshape(()) # rank-0 scalar scale = network.add_constant(shape=(), weights=trt.Weights(q_scale)).get_output(0) q = network.add_quantize(some_tensor, scale, trt.int8).get_output(0) dq = network.add_dequantize(q, scale, trt.float32).get_output(0) # Feed dq into the consumer; TensorRT fuses the Q/DQ into it so it runs in INT8. ``` Drive the rewrite from `scripts/migrate.py`: ```bash python3 scripts/migrate.py path/to/build.py # dry-run diff python3 scripts/migrate.py path/to/build.py --write # rewrite in place ``` The script edits AST nodes (not regexes) — it understands `create_network` and `set_flag` call shapes, so it is safe on files that mix conventions. ## Step 2B — Migrate a `trtexec` command line Replacements: | Weakly typed flag | Strongly typed equivalent | |-------------------|---------------------------| | `--fp16` | **Remove.** Precision comes from the ONNX. See the `--stronglyTyped` note below. | | `--bf16` | **Remove.** Same as `--fp16`. | | `--int8` | **Remove.** Q/DQ must be present in the ONNX. | | `--best` | **Remove.** Not allowed with `--stronglyTyped` on 10.12–10.x (see Common Errors). | | `--stronglyTyped` | **Version-gated.** Required on 10.12–10.x to opt into strong typing; a no-op (default-on) on 11.x — drop it or leave it, your choice. | | `--noTF32` | **Keep.** `kTF32` is retained in 11.x; `--noTF32` still disables TF32 and is orthogonal to typing. | | `--precisionConstraints=obey` / `prefer` | **Remove.** Constraints are expressed in the graph. | | `--layerPrecisions=...` | **Remove.** Use ONNX `Cast` nodes / AutoCast. | | `--layerOutputTypes=...` | **Remove.** | Worked rewrite: ```bash # Before (weakly typed) trtexec --onnx=model.onnx --fp16 --saveEngine=model.fp16.plan \ --minShapes=input:1x3x224x224 --optShapes=input:8x3x224x224 \ --maxShapes=input:16x3x224x224 # After (strongly typed; ONNX has been AutoCast'd to mixed FP16) # On 11.x --stronglyTyped is the default and a no-op — the line below is equivalent # with or without it. On 10.12–10.x it is REQUIRED, or the build stays weakly typed. trtexec --onnx=model.mixed.onnx --stronglyTyped --saveEngine=model.fp16.plan \ --minShapes=input:1x3x224x224 --optShapes=input:8x3x224x224 \ --maxShapes=input:16x3x224x224 ``` The `trtexec` README's [Example 6](https://github.com/NVIDIA/TensorRT/blob/main/samples/trtexec/README.md#example-6-create-a-strongly-typed-plan-file) is the canonical reference. ## Step 2C — Migrate a C++ builder Replacements mirror the Python path: | Weakly typed (C++) | Strongly typed (C++) | |---|---| | `builder->createNetworkV2(0)` | `builder->createNetworkV2(1U << static_cast<uint32_t>(NetworkDefinitionCreationFlag::kSTRONGLY_TYPED))` | | `config->setFlag(BuilderFlag::kFP16)` | **Remove.** | | `config->setFlag(BuilderFlag::kBF16)` | **Remove.** | | `config->setFlag(BuilderFlag::kINT8)` | **Remove.** | | `config->setFlag(BuilderFlag::kTF32)` | **Keep.** `kTF32` is retained in 11.x — orthogonal to typing. | | `config->setFlag(BuilderFlag::kOBEY_PRECISION_CONSTRAINTS / kPREFER_PRECISION_CONSTRAINTS)` | **Remove.** No per-layer precision exists to constrain. | | `layer->setPrecision(DataType::kHALF)` | **Remove.** Cast the input tensor instead (`addCast`). | | `layer->setComputePrecision(...)` | **Remove.** Deprecated 10.16, removed; compute precision follows input dtypes. |
Voir sur GitHub
Ce SKILL.md est tres volumineux, SkillsMP affiche donc ici seulement la premiere section. Voir sur GitHub