TensorRT invalid sampling parameters in staging environment

Problem Description

During the staging deployment of a GPU‑accelerated inference service, the TensorRT engine build fails with the following error messages:

[TensorRT] Error: Invalid sampling parameters (code: 3)
Failed to create optimization profile: Invalid sampling parameters for input 'input_0'
tensorrt.tensorrt.BuilderError: Invalid sampling parameters
ASSERT FAILED: validateSamplingParameters() – sampling parameters out of allowed range

The failure occurs at builder->buildEngineWithConfig() when the CI pipeline attempts to generate an engine for a computer‑vision model using dynamic shape profiles.

Root Cause Analysis

TensorRT validates sampling parameters against the constraints defined in the Dynamic Shapes and Optimization Profiles section of the TensorRT Developer Guide. The validation checks that:

  • Each dimension in the min, opt, and max vectors follows the rule min ≤ opt ≤ max.
  • The total number of samples (batch size × spatial dimensions) falls within the TRT_SAMPLE_COUNT limits imposed by the builder configuration.
  • The stride and padding values supplied to IBuilderConfig::setCalibrationProfile match the expectations of the selected CalibrationAlgorithm (see the NVIDIA TensorRT Sampling API documentation).

In the staging environment the following mismatches were observed:

  1. Profile dimension mismatch: The CI pipeline generated a profile with min = {1, 3, 224, 224}, opt = {4, 3, 224, 224}, and max = {2, 3, 224, 224}. The max batch dimension (2) is smaller than the opt batch dimension (4), violating the min ≤ opt ≤ max rule.
  2. Incorrect calibration sample count: The FP16 calibration routine queried the data loader for 500 samples, but the builder configuration implicitly limited TRT_SAMPLE_COUNT to 256 (default for TensorRT 8.5). This triggered the “Invalid sampling parameters” path in validateSamplingParameters() (referenced in the GPU Deployment Guide troubleshooting chapter).
  3. Driver‑runtime version mismatch: The staging node runs CUDA 12.1 with TensorRT 8.5. The GPU Deployment Guide notes that a driver‑to‑runtime mismatch can cause validation failures for sampling stride, which was reproduced in a real incident where “Invalid sampling parameters” appeared after a driver upgrade.

Investigation and Debugging

The following systematic steps were used to pinpoint the failure:

  1. Inspect builder logs – Enable verbose logging to capture the exact validation error.
export TRT_LOGGER_LEVEL=VERBOSE
trtexec --onnx=model.onnx --minShapes=input_0:1x3x224x224 \
        --optShapes=input_0:4x3x224x224 \
        --maxShapes=input_0:2x3x224x224 \
        --fp16 --saveEngine=engine.trt

Sample log excerpt:

[I] ==== TensorRT Runtime Version: 8.5.2.2 ====
[W] validateSamplingParameters(): batch dimension mismatch (opt=4, max=2)
[W] validateSamplingParameters(): sample count 500 exceeds TRT_SAMPLE_COUNT=256
[ERROR] Invalid sampling parameters (code: 3)
  1. Dump the optimization profile using the C++ API to verify the vectors.
auto profile = builder->createOptimizationProfile();
profile->setDimensions("input_0", nvinfer1::OptProfileSelector::kMIN, Dims4{1,3,224,224});
profile->setDimensions("input_0", nvinfer1::OptProfileSelector::kOPT, Dims4{4,3,224,224});
profile->setDimensions("input_0", nvinfer1::OptProfileSelector::kMAX, Dims4{2,3,224,224});

Running the snippet with profile->isValid() returned false and printed the same warnings as the CLI.

  1. Check driver/runtime compatibility – Query driver and TensorRT versions.
nvidia-smi --query-gpu=driver_version --format=csv
cat /usr/local/tensorrt/include/NvInferVersion.h | grep NV_TENSORRT_MAJOR

Result:

Driver Version, 525.85.12
NV_TENSORRT_MAJOR, 8
NV_TENSORRT_MINOR, 5

The driver (525) is compatible with TensorRT 8.5, but the staging node had a leftover CUDA 12.0 runtime library that conflicted with the 12.1 driver, as reported in the GPU Deployment Guide.

  1. Validate calibration data loader – Ensure the loader reports the correct sample count.
python -c "import torch; ds = torch.utils.data.DataLoader(..., batch_size=1); print(len(ds))"

Output showed 500 samples, while the builder default expects 256.

Resolution

Three corrective actions resolved the staging failure:

1. Align optimization profile dimensions

Adjust the max batch size to be ≥ opt batch size, or reduce opt accordingly.

# Before (invalid)
profile->setDimensions("input_0", nvinfer1::OptProfileSelector::kMAX, Dims4{2,3,224,224});

# After (valid)
profile->setDimensions("input_0", nvinfer1::OptProfileSelector::kMAX, Dims4{8,3,224,224});

2. Explicitly set a sufficient calibration sample count

Use IBuilderConfig::setFlag(BuilderFlag::kFP16) together with setCalibrationProfile() and override the default sample limit.

auto config = builder->createBuilderConfig();
config->setFlag(nvinfer1::BuilderFlag::kFP16);
config->setCalibrationProfile(calibProfile);
config->setInt8Calibrator(calibrator); // if using INT8
config->setMaxWorkspaceSize(1 << 30); // 1 GiB

// Override default sample count (available from TensorRT 8.6)
config->setInt8CalibratorSampleCount(500);

3. Synchronize CUDA driver, runtime, and TensorRT versions

Reinstall the matching CUDA runtime (12.1) and ensure the environment variable LD_LIBRARY_PATH points only to the correct libraries.

# Remove stale CUDA 12.0 libs
sudo apt-get purge cuda-12-0

# Install matching runtime
sudo apt-get install cuda-12-1

# Verify paths
echo $LD_LIBRARY_PATH
# Should contain /usr/local/cuda-12.1/lib64 and /usr/local/tensorrt/lib

After applying these changes, the CI pipeline succeeded in building the engine without the “Invalid sampling parameters” error.

Verification

Confirm the fix with the following checks:

  1. Engine build success – Re‑run the build command.
trtexec --onnx=model.onnx \
        --minShapes=input_0:1x3x224x224 \
        --optShapes=input_0:4x3x224x224 \
        --maxShapes=input_0:8x3x224x224 \
        --fp16 --saveEngine=engine.trt

Expected output snippet:

[I] ==== TensorRT Runtime Version: 8.5.2.2 ====
[I] Building engine...
[I] Engine built successfully. Saved to engine.trt
  1. Runtime inference test – Load the engine and run a single inference.
python run_inference.py --engine engine.trt --batch 4

Look for a clean log line such as:

[INFO] Inference completed in 12.3 ms (batch=4)
  1. Metrics validation – Verify that the calibration sample count metric reflects the intended value.
tensorboard --logdir=logs
# In the “CalibrationSamples” chart, value should be 500

Prevention and Best Practices

  • Validate profiles programmatically before invoking buildEngineWithConfig:
    if (!profile->isValid()) {
        std::cerr << "Optimization profile validation failed" << std::endl;
        return;
    }
    
  • Pin driver, CUDA, and TensorRT versions in the staging environment using a container image that includes matching nvidia/cuda:12.1-runtime-ubuntu22.04 and the corresponding TensorRT wheel.
  • Expose calibration sample count as a CI parameter and enforce a sanity check that the data loader’s length does not exceed TRT_SAMPLE_COUNT.
  • Enable verbose TensorRT logging in CI pipelines to surface validation warnings early.
  • Document profile dimension constraints in the repository’s README, referencing the “Dynamic Shapes and Optimization Profiles” section of the official developer guide.

Related Topic Hub: Model Serving Troubleshooting Hub

FAQ

  1. Why does the error appear only after upgrading to TensorRT 8.6?

    TensorRT 8.6 introduced stricter validation of the opt vs. max dimensions and added a default TRT_SAMPLE_COUNT of 256. Older versions silently accepted the mismatched profile, but the new validator now aborts with “Invalid sampling parameters”.

  2. How can I discover the current TRT_SAMPLE_COUNT limit?

    Use the C++ API:

    int64_t limit = config->getInt8CalibratorSampleCount(); // returns default 256 if not set
    

    Or query the environment variable TRT_SAMPLE_COUNT if set.

  3. Can setting TRT_LOGGER_LEVEL=VERBOSE impact performance?

    No. The flag only controls the verbosity of the logger; it does not affect the runtime execution path of the built engine.

  4. What should I do if the driver‑runtime mismatch persists after reinstalling CUDA?

    Ensure that no stale libraries remain in /usr/local/cuda or in the container image. Run ldd on libnvinfer.so to verify that it links against the expected libcudart.so version.

  5. Is it safe to set max batch size much larger than the typical production batch?

    Yes, as long as the GPU memory budget can accommodate the worst‑case shape. Oversizing max without sufficient memory will cause out‑of‑memory errors during engine creation, not sampling‑parameter errors.