trtllm-build fails because an optimization profile has a minimum dimension above its optimum
TensorRT requires min to be less than or equal to opt, and opt less than or equal to max, for every dynamic dimension in an optimization profile. The engine build aborts when TensorRT-LLM derives a profile in which some dimension violates that ordering, usually because build flags imply a minimum larger than the optimum that was set.
Rebuild with TLLM_LOG_LEVEL=TRACE to print the per-tensor minimum, optimum and maximum table, find the row where minimum exceeds optimum, and correct the flag that set it. Removing an explicit --opt_num_tokens fixes most cases.
What this failure is
A build-time failure in which TensorRT-LLM rejects an optimization profile because some dynamic dimension was assigned a minimum larger than its optimum, violating the min less than or equal to opt less than or equal to max ordering TensorRT requires.
Why it happens (the mechanism)
TensorRT requires every dynamic dimension to satisfy min less than or equal to opt less than or equal to max, and validates it when a profile is evaluated. TensorRT-LLM runs the same check earlier so the message is legible. The ordering is violated when build flags are set independently: opt_num_tokens defaults to max_batch_size times max_beam_width, so pinning it by hand while other flags raise the derived minimum places opt underneath min for a batched dimension such as input_ids.
What you'll observe
- trtllm-build aborts before an engine file is produced
- The same flags built successfully against an earlier TensorRT-LLM version
- The failing dimension is not named in the default build output, so there is nothing to correct
- Removing one flag makes the build succeed without explaining which value was inconsistent
Common symptoms and what they mean
| Symptom | Why it happens |
|---|---|
| [TRT-LLM] [E] Error building engine: optimization profile is invalid. | TensorRT validates each optimization profile by checking that the maximum dimensions are at least the optimum, and the optimum at least the minimum. TensorRT-LLM runs the same check earlier, during its own pre-build pass, so that the message names the failure rather than surfacing a raw TensorRT assertion. |
| min dimension is greater than opt dimension for input_ids | The usual trigger is opt_num_tokens sitting below the minimum implied by other flags. It defaults to max_batch_size multiplied by max_beam_width, so setting it by hand while leaving those flags to grow can place opt underneath the derived min for a batched dimension such as input_ids. |
| Build aborts during profile validation, before any TensorRT kernel timing begins | With --multiple_profiles the profile-splitting logic generates several min, opt and max tuples rather than one. A value that is consistent in the first profile can be inconsistent in another, which is why the build can fail while the flags look reasonable. |
Which systems are affected
- trtllm-build invocations that set --opt_num_tokens explicitly
- Builds using --multiple_profiles, where a later profile can be invalid while profile 0 is fine
- Configurations where max_seq_len is deduced from the model config and conflicts with an explicit max_input_len
- Cross-version builds where a flag's default changed between TensorRT-LLM releases
How to confirm this is the problem
Apply the following checklist to a small reproduction: each box below is a positive signal that you are looking at this exact failure rather than a sibling in the same taxonomy.
- ✓Export TLLM_LOG_LEVEL=TRACE and re-run the build; the tensor shape table printed before compilation shows the minimum, optimum and maximum for each named dimension.
- ✓Compare the explicit values passed for opt_num_tokens, max_batch_size and max_beam_width; opt_num_tokens below max_batch_size multiplied by max_beam_width is the common inconsistency.
- ✓Rebuild with --multiple_profiles removed. A build that then succeeds confirms the invalid tuple was produced by profile splitting rather than by a single flag.
Example training logs (fingerprint)
[TRT-LLM] [E] Error building engine: optimization profile is invalid.
[TRT-LLM] [E] min dimension is greater than opt dimension for input_ids
[TRT-LLM] [I] input_ids | Min (1) | Opt (8) | Max (8192)Timestamps and exact values vary across runs, but the pattern. An info-level start, an early WARN, an ERROR carrying the symptom. Is the actual fingerprint you should alert on. The Denpex platform flags this combination automatically.
Root cause, fix & prevention, signed in
Sign up free to see why this failure really happens, the exact remediation steps, and the production-grade prevention pattern. You also get 3 free full diagnoses for your own training logs.
Sign up free. Unlock the full analysisNo credit card · 3 free diagnoses · Instant access
Why the recommended fix works
Letting opt_num_tokens return to its default restores the relationship it has with max_batch_size and max_beam_width, which is what the derived minimum is computed from. Printing the profile table replaces guesswork with the specific dimension name, so the flag that needs changing is identified rather than found by removing flags one at a time.
Code examples
// Typical pattern:
import torch.optim as optim
optimizer = optim.AdamW(model.parameters(), lr=3e-4)
scheduler = optim.lr_scheduler.CosineAnnealingLR(optimizer, T_max=num_training_steps)
for step in range(num_training_steps):
optimizer.zero_grad()
loss = model(batch)
loss.backward()
optimizer.step()
scheduler.step()Adapt the snippet to your framework. The same pattern holds for PyTorch Lightning, Hugging Face Trainer, DeepSpeed, Megatron-LM, and vLLM training wrappers. Where the wrapper exposes a config flag (for examplelr_scheduler_type in Trainer), prefer the flag over the imperative API to keep the schedule declarative and reproducible.
Best practices by model family
| Model / Stack | Recommendation | Notes |
|---|---|---|
| First failure of this kind | TLLM_LOG_LEVEL=TRACE and read the shape table | Names the offending tensor and dimension instead of leaving you to bisect flags. |
| Explicit --opt_num_tokens set | Remove it and let it default | Defaults to max_batch_size times max_beam_width; the documentation notes the flag may be removed. |
| --multiple_profiles enabled | Disable it to isolate the invalid tuple | A later profile can be invalid while profile 0 is fine. |
| max_seq_len left unspecified | Set it explicitly alongside max_input_len | It is deduced from the model config and the deduced value can contradict an explicit max_input_len. |
With the fix vs without the fix
| Dimension | With the fix | Without the fix |
|---|---|---|
| Where the failure is caught | TensorRT-LLM's pre-build pass, with a readable message | A raw TensorRT profile assertion |
| Identifying the bad dimension | TRACE-level shape table naming each tensor | Removing build flags one at a time |
| Source of the inconsistency | Usually opt_num_tokens set below the derived minimum | Assumed to be a TensorRT bug |
Real engineering notes
“With --multiple_profiles the splitting logic emits several min, opt and max tuples instead of one, and a value that is consistent in profile 0 can be inconsistent in a later profile. That is why a build can fail while every flag looks individually reasonable. Disable the option to find out whether profile generation is the source before changing any shape flag.”
Visual fingerprint
valid input_ids min 1 <= opt 8 <= max 8192 invalid input_ids min 16 > opt 8 max 8192 <-- build aborts
Related failures to investigate next
Root cause, fix & prevention
Frequently asked questions
Twelve targeted questions that engineers and on-call staff most commonly ask about this failure.
Which dimension is actually wrong?
The same command worked on an earlier version.
Should I set --opt_num_tokens?
Why does disabling --multiple_profiles help?
Don't just read the fix, diagnose your run
The encyclopedia tells you what went wrong. Denpex tells you what went wrong in YOUR training run. With your logs, your config, and your stack.