rf-detr-cpp

infracvApache-2.0活跃维护

基于 C++ 和 TensorRT 的 RF-DETR 推理引擎,支持目标检测与实例分割,可在 NVIDIA GPU 和 Jetson 上以 FP32/FP16/INT8 量化部署。

Production-ready C++/TensorRT inference engine for RF-DETR. Object detection and instance segmentation with FP32/FP16/INT8 support. Optimized for NVIDIA GPUs, Jetson (Orin, AGX Thor).

v0.0.1发布于 2026-06-27 17:01 UTC212star21fork同步于 2026-11-07 07:30 UTC

怎么上手

由 README 提炼,执行前请确认
git clone https://github.com/infracv/rf-detr-cpp.git
cd rf-detr-cpp
cmake -B build -S . -DCMAKE_BUILD_TYPE=Release -DCMAKE_CUDA_ARCHITECTURES=120
cmake --build build -j$(nproc)
硬件要求按 README 说明

需 NVIDIA GPU,计算能力 ≥ 8.0(RTX 30xx/40xx/50xx),并支持 Jetson Orin 与 Thor/GH200;README 未给出最低显存要求,benchmark 中 nano 模型占用约 836–892 MB。

需要 CUDA
下载:源码 zip·GitHub Releases(安装包)本站不镜像安装包

项目说明

由 README 自动翻译提炼

RF-DETR 的 C++/TensorRT 推理引擎,运行时零 Python 依赖,面向生产部署

基于 C++ 和 TensorRT 的 RF-DETR 推理引擎,支持目标检测与实例分割,可在 NVIDIA GPU 和 Jetson 上以 FP32/FP16/INT8 量化部署。

核心能力

  • 用纯 C++ 实现 DETR 式推理管线,无需 NMS、anchor 与 letterbox
  • 预处理走 GPU CUDA kernel,主机到设备异步传输用 pinned memory
  • 支持 FP32/FP16/INT8 三种精度,INT8 走校准缓存或 QDQ ONNX
  • 用 CUDA Graph 重放派发推理,降低每帧调度开销
  • 提供检测与实例分割 API,并支持动态 batch 与 C ABI 供 FFI 调用

容易踩的坑

必须显式传 -DCMAKE_CUDA_ARCHITECTURES,否则环境里的旧值会覆盖导致 CUDA 预处理 kernel 未针对你的 GPU 优化;运行前需先用 Python 一次性导出 ONNX 并用 rfdetr_build 构建 engine,C++ 运行时本身不需要 Python;FP16 引擎可能因注意力数值超出 FP16 范围产生 NaN 而检测为空,需用 test_img 验证,异常时回退 FP32。

内容由模型根据 README 生成,可能不完整或不准确,以官方文档为准。看原文 README

最近发版

1 个版本v0.0.1
  1. v0.0.1v0.0.1 - initial release最新正式版2026-06-27 · 2026-06-27 17:01 UTC

    We are excited to announce the initial public release of RF-DETR C++, a production-grade TensorRT inference library for RF-DETR, Roboflow's transformer-based real-time object detection model built on a DINOv2 backbone.

    RF-DETR C++ brings zero-Python, GPU-accelerated inference to C++ applications. The entire pipeline — preprocessing, inference, and postprocessing — runs in C++ with CUDA, delivering sub-3ms latency on modern NVIDIA GPUs.


    Features

    Object Detection

    • RFDetrDetector with detect() and detect_batch() APIs
    • Fused resize and normalize CUDA preprocessing kernel with async H2D transfers via pinned memory
    • CUDA Graph capture for minimal dispatch overhead on repeated inference calls
    • Supports all RF-DETR variants: nano, small, medium, base, large

    Instance Segmentation

    • RFDetrSegmenter with segment() and segment_batch() APIs
    • GPU mask decode kernel — bilinear upsample and threshold parallelized across all detections simultaneously
    • Per-detection CV_8UC1 masks at original image resolution
    • Supports segmentation variants: seg-nano, seg-small, seg-medium, seg-large, seg-xlarge, seg-2xlarge

    Precision Support

    • FP32 — full precision, default
    • FP16 — ~25% faster than FP32, pre-converted ONNX weights for TRT 11
    • INT8 — lowest memory footprint, QDQ ONNX path for TRT 11+, calibration cache for TRT < 11

    Memory and Resource Management

    • RAII CUDA wrappers replacing raw pointer management throughout the library
    • All CUDA handles owned and destroyed automatically

    C ABI

    • Full C API (librfdetr_c.so) for FFI bindings from Python, Rust, Go, or any language with a C FFI

    CLI Tools

    • rfdetr_build — convert ONNX to TensorRT engine (FP32, FP16, INT8, dynamic batch)
    • rfdetr_detect — run detection on a single image
    • rfdetr_seg — run instance segmentation on a single image
    • rfdetr_video — run detection on a video file or live camera stream
    • rfdetr_batch — run detection on multiple images in a single engine call
    • rfdetr_bench — full latency and throughput benchmark with JSON output
    • rfdetr_inspect — print engine I/O bindings, shapes, and sidecar metadata
    • rfdetr_smoke — load an engine, run a zero-input forward pass, verify outputs

    Benchmark

    NVIDIA RTX 5070 Ti, Batch 1, 500 iterations.

    TaskVariantPrecisionFPSAvg LatencyGPU Memory
    DetectionnanoFP165002.001 ms768 MB
    DetectionnanoINT84822.073 ms684 MB
    Segmentationseg-nanoFP161666.014 ms735 MB
    Segmentationseg-nanoINT81267.895 ms687 MB

    Requirements

    DependencyVersion
    NVIDIA GPUCC >= 8.0
    CUDA Toolkit>= 12.0
    TensorRT>= 10.0
    OpenCV>= 4.5
    CMake>= 3.20
    C++ compilerC++17

    Getting Started

    git clone https://github.com/infracv/rf-detr-cpp.git
    cd rf-detr-cpp
    cmake -B build -S . -DCMAKE_BUILD_TYPE=Release -DCMAKE_CUDA_ARCHITECTURES=120
    cmake --build build -j$(nproc)
    

    See the README for the full setup guide including ONNX export and engine conversion.

用户点评

登录用户的真实使用记录,可按版本和硬件筛选
共 0 条

    还没有人点评。第一个说出真实体验的人最有价值。

    README 原文

    未翻译

    Overview

    RF-DETR C++ is a production-grade TensorRT inference engine for RF-DETR, Roboflow's transformer-based real-time object detection model built on a DINOv2 backbone.

    #include "rfdetr/tasks/detector.hpp"
    
    rfdetr::RFDetrDetector detector("rf-detr-nano-fp32.engine");
    rfdetr::Detections dets = detector.detect(cv::imread("image.jpg"), 0.5f);
    

    Unlike YOLO models, RF-DETR uses a DETR-style architecture with no NMS, no anchor grids, no letterboxing. This requires a different inference pipeline, which this library implements entirely in C++ with zero Python at runtime.

    Most RF-DETR deployments run Python at inference time. This library eliminates that dependency:

    RF-DETR C++Python (PyTorch)
    Runtime dependencyC++ onlyPython + PyTorch + CUDA
    PreprocessingGPU CUDA kernelCPU / torchvision
    Host-to-device transferAsync (pinned memory)Synchronous
    PrecisionFP32 / FP16 / INT8FP32 / FP16
    Inference dispatchCUDA Graph replayPer-frame forward pass
    Latency (RTX 5070 Ti)2.0 ms (FP16)~15–30 ms

    Quick Start

    # 1. Clone & build
    git clone https://github.com/infracv/rf-detr-cpp.git
    cd rf-detr-cpp
    cmake -B build -S . -DCMAKE_BUILD_TYPE=Release -DCMAKE_CUDA_ARCHITECTURES=120
    cmake --build build -j$(nproc)
    # Replace 120 with your GPU arch: RTX 30xx=86, RTX 40xx=89, RTX 50xx=120
    # Tarball TensorRT: add -DTENSORRT_DIR=/path/to/TensorRT
    
    # 2. Export ONNX and build TRT engine (one-time, Python)
    pip install -r requirements.txt
    python trt-files/scripts/export_onnx.py --variant nano --out-dir trt-files/onnx
    
    # FP32 engine
    ./build/rfdetr_build --onnx trt-files/onnx/rf-detr-nano.onnx --precision fp32
    
    # FP16 engine
    ./build/rfdetr_build --onnx trt-files/onnx/rf-detr-nano.onnx --precision fp16
    
    # 3. Run inference
    ./build/rfdetr_detect \
        --engine trt-files/onnx/rf-detr-nano-fp16.engine \
        --image  asset/test_img.jpg --out out/result.jpg
    

    Supported Models & Tasks

    TaskVariants
    Object Detectionnano, small, medium, base, large
    Instance Segmentationseg-nano, seg-small, seg-medium, seg-large, seg-xlarge, seg-2xlarge

    Precision support

    PrecisionTRT < 11TRT 11+Notes
    FP32✅✅Default
    FP16✅ (kFP16 flag)✅ (convert_fp16.py → pre-converted ONNX)~25% faster than FP32
    INT8✅ (calibration cache)✅ (QDQ ONNX via convert_int8.py)Lowest memory

    FP16 NaN sanity check. RF-DETR's transformer attention can produce values that exceed the FP16 range (±65,504), causing NaNs to propagate through the network and yield zero detections. After building an FP16 engine, run a single detection on asset/test_img.jpg. If you get zero detections on an image where FP32 finds objects, your FP16 engine is hitting overflow. Fall back to FP32 (rfdetr_build --precision fp32) or rebuild with mixed-precision settings.


    Installation

    Prerequisites

    DependencyVersionNotes
    NVIDIA GPUCC ≥ 8.0RTX 30xx / 40xx / 50xx
    CUDA Toolkit≥ 12.0
    TensorRT≥ 10.0TRT 11 supported (strongly-typed networks)
    OpenCV≥ 4.5core, imgproc, imgcodecs, videoio, highgui
    CMake≥ 3.20
    C++ compilerC++17GCC 9+, Clang 10+

    Build from Source

    git clone https://github.com/infracv/rf-detr-cpp.git
    cd rf-detr-cpp
    cmake -B build -S . -DCMAKE_BUILD_TYPE=Release -DCMAKE_CUDA_ARCHITECTURES=120
    cmake --build build -j$(nproc)
    # Tarball TensorRT: add -DTENSORRT_DIR=/path/to/TensorRT
    

    Replace 120 with your GPU's compute capability:

    GPU familyCMAKE_CUDA_ARCHITECTURES
    RTX 30xx (Ampere)86
    RTX 40xx (Ada Lovelace)89
    RTX 50xx (Blackwell)120
    Jetson Orin87
    Thor / GH200101

    The default build (no -DCMAKE_CUDA_ARCHITECTURES) compiles for all five (86 87 89 101 120). Pass a single value to keep build times short.

    Note: Always pass -DCMAKE_CUDA_ARCHITECTURES explicitly. If your environment has a stale value set (e.g. from a conda env), CMake will use that instead and the CUDA preprocessing kernel won't be optimized for your GPU.

    Model Conversion

    Python is only needed for this one-time conversion step. The C++ runtime requires no Python.

    # Python deps (uv recommended)
    uv venv --python 3.12 .venv && source .venv/bin/activate
    uv pip install -r requirements.txt
    
    # Export RF-DETR PyTorch → ONNX
    python trt-files/scripts/export_onnx.py --variant nano --out-dir trt-files/onnx
    
    # FP32 engine
    ./build/rfdetr_build --onnx trt-files/onnx/rf-detr-nano.onnx --precision fp32
    
    # FP16 engine
    ./build/rfdetr_build --onnx trt-files/onnx/rf-detr-nano.onnx --precision fp16
    

    For INT8 see trt-files/INT8_QUANTIZATION.md.


    API Reference

    Object Detection

    #include "rfdetr/tasks/detector.hpp"
    
    rfdetr::RFDetrDetector detector("rf-detr-nano-fp32.engine");
    
    cv::Mat image = cv::imread("image.jpg");
    rfdetr::Detections dets = detector.detect(image, /*threshold=*/0.5f);
    
    for (const auto& d : dets)
        std::printf("class=%d  score=%.2f  box=[%.1f %.1f %.1f %.1f]\n",
                    d.class_id, d.score, d.box.x1, d.box.y1, d.box.x2, d.box.y2);
    
    rfdetr::draw_detections(image, dets);
    cv::imwrite("out.jpg", image);
    
    // Check whether CUDA Graph was captured at construction:
    if (detector.cuda_graph_active())
        std::puts("CUDA Graph active: lowest dispatch latency");
    

    Instance Segmentation

    #include "rfdetr/tasks/segmenter.hpp"
    
    rfdetr::RFDetrSegmenter segmenter("rf-detr-seg-nano-fp16.engine");
    
    cv::Mat image = cv::imread("image.jpg");
    rfdetr::Detections dets = segmenter.segment(image, /*threshold=*/0.5f);
    
    for (const auto& d : dets)
        std::printf("class=%d  score=%.2f  mask=%dx%d (CV_8UC1)\n",
                    d.class_id, d.score, d.mask.cols, d.mask.rows);
    
    rfdetr::draw_segmentations(image, dets);
    rfdetr::draw_detections(image, dets);
    cv::imwrite("out.jpg", image);
    

    Each Detection.mask is a CV_8UC1 cv::Mat of the original image size, with values 0 or 255.

    Batch Inference

    Batching requires a dynamic-batch engine. Export the ONNX with --dynamic-batch, then build with a profile:

    python trt-files/scripts/export_onnx.py --variant nano --dynamic-batch \
        --out-dir trt-files/onnx --name rf-detr-nano-dyn
    ./build/rfdetr_build --onnx trt-files/onnx/rf-detr-nano-dyn.onnx --precision fp16 \
        --min-batch 1 --opt-batch 4 --max-batch 4
    
    std::vector<cv::Mat> frames = { img0, img1, img2, img3 };
    
    rfdetr::RFDetrDetector detector("rf-detr-nano-dyn-fp16.engine");
    auto batch = detector.detect_batch(frames, 0.5f);
    
    for (std::size_t i = 0; i < batch.size(); ++i)
        std::printf("frame %zu: %zu detections\n", i, batch[i].size());
    

    RFDetrSegmenter::segment_batch() works the same way. Note that batching speeds up inference only — segmentation postprocessing scales with output resolution and runs per image, so at high resolutions the end-to-end gain is small.

    Batching raises throughput at the cost of per-image latency: nothing completes until the whole batch does. Prefer single-image inference for live feeds.

    C ABI (Python / Rust / Go FFI)

    Build with -DRFDETR_BUILD_C_API=ON to produce librfdetr_c.so:

    #include "rfdetr/c_api.h"
    
    rfdetr_detector_t* det = rfdetr_detector_create("model.engine", NULL);
    rfdetr_detections_t* res = rfdetr_detector_detect(det, bgr_data, w, h, w*3, 0.5f);
    
    for (int i = 0; i < res->count; ++i)
        printf("cls=%d  score=%.2f\n", res->detections[i].class_id, res->detections[i].score);
    
    rfdetr_detections_free(res);
    rfdetr_detector_destroy(det);
    
    # Python via ctypes
    import ctypes
    lib = ctypes.CDLL("librfdetr_c.so")
    # See include/rfdetr/c_api.h for the full binding
    

    Benchmarks

    NVIDIA RTX 5070 Ti, 500 iters, 50-iter warm-up, Batch 1.

    TaskPrecisionFPSAvg LatencyP50P99GPU Memory
    Detection (nano)FP324062.462 ms2.444 ms2.778 ms859 MB
    Detection (nano)FP165141.944 ms1.911 ms2.508 ms836 MB
    Segmentation (seg-nano)FP321128.906 ms8.817 ms10.243 ms892 MB
    Segmentation (seg-nano)FP161576.364 ms6.314 ms7.211 ms886 MB

    Numbers include the full pipeline: preprocessing, inference, and postprocessing. Segmentation mask decoding runs entirely on the GPU via a dedicated CUDA kernel.

    500 iters, 50-iter warm-up, Batch 1.

    TaskPrecisionFPSAvg LatencyP50P99
    Detection (nano)FP161208.302 ms7.766 ms12.829 ms
    Detection (nano)FP325019.984 ms18.858 ms33.003 ms
    Segmentation (seg-nano)FP165518.093 ms17.008 ms23.871 ms
    Segmentation (seg-nano)FP322442.292 ms42.047 ms45.436 ms

    GPU Memory column is omitted — Jetson uses unified CPU/GPU memory, so cudaMemGetInfo reports system memory rather than dedicated VRAM and the delta reads as zero. See the Benchmarking Guide for details.

    See benchmarks/BENCHMARKING.md to reproduce these numbers or run your own benchmarks on any GPU.


    License

    Apache-2.0. See LICENSE.


    Acknowledgments


    Contributing

    We welcome and appreciate all contributions. If you notice any issues or bugs, have questions, or would like to suggest new features, please open an issue or pull request. By sharing your ideas and improvements, you help make RF-DETR C++ better for everyone.

    See CONTRIBUTING.md for guidelines on setting up the dev environment, coding standards, and the PR process.