PipeTuner DsApp score is 0.0 or negative value (dataset issue)

• Hardware Platform (Jetson / GPU)
GPU
• DeepStream Version
7.0
• TensorRT Version
8.6.1.6-1+cuda12.0
• NVIDIA GPU Driver Version (valid for GPU only)
555.85
• Issue Type( questions, new requirements, bugs)
Questions/Bugs
• How to reproduce the issue ? (This is for bugs. Including which sample app is using, the configuration files content, the command line used and other details for reproducing)
Sample files are attached below.

Hello, I’ve been trying to use PipeTuner for a while now, with the intention of tuning the parameters of config files with a custom YOLO11 model and a custom dataset. My current problem is that when launching launch.sh and checking the output CSV, the DsApp score is always returning either 0.0 or large negative values. I’ve already tried all the suggestions posted in these related topics:

For using YOLO11 with PipeTuner, I’m running the scripts as detailed in the documentation with a new Docker image built with the following Dockerfile:

FROM nvcr.io/nvidia/deepstream:7.0-triton-multiarch

RUN apt-get update && apt-get upgrade -y && \
    apt-get install -y git build-essential && \
    rm -rf /var/lib/apt/lists/*

RUN git clone https://github.com/marcoslucianops/DeepStream-Yolo.git \
    /opt/nvidia/deepstream/deepstream-7.0/DeepStream-Yolo
WORKDIR /opt/nvidia/deepstream/deepstream-7.0/DeepStream-Yolo
RUN CUDA_VER=12.2 make -C nvdsinfer_custom_impl_Yolo
RUN chmod -R 777 /opt/nvidia/deepstream/deepstream/DeepStream-Yolo
WORKDIR /opt/nvidia/deepstream/deepstream-7.0/

Here I’m attaching the data and config files I’m using, as well as my output directory with all the logging:
pipe-tuner-road.zip (40.7 MB)
output.zip (4.8 MB)

When I’m using the pipe-tuner-sample data instead of my attached data folder, everything works as expected while using my YOLO11 model, as it also detects people in that synthetic dataset with “person” as class number 1, so I assume that the problem is with how my dataset is formed, but I cannot grasp what error may I have. For commodity I’ve tested with just a 1 video dataset.

Considerations I had while building the dataset:

  • The video is encoded in MP4, in 1920x1080 and 30FPS.
  • The ground truth file starts at frame number 1, with new IDs being shared between all classes (for example, if 2 cars already appeared and the next object is the first truck to appear it will have ID 3).
  • All annotations are marked with 1 for eval, 1 for full visibility, and bounding boxes are in format [x0, y0, width, height] with coord values in range [0:1920, 0:1080].
  • The class of each annotation corresponds with those of the labels.txt loaded in the PGIE config file, starting with value 1.
  • seqinfo.ini of each video is the same as in the sample dataset, replacing name with the video filename (excluding the extension) and seqLength with the number of frames.
  • I made a road_all.txt file similar to SDG_1min_all.txt where I have the ordered sequence of videos.

Notice that when I run the container created with sudo bash launch.sh deepstream-yolo:7.0-triton-multiarch ../configs/config_PipeTuner/road_MOT.yml I can run the deepstream-app with YOLO11 model normally, using the video I provide and it works, hence reassuring my assumption about the problem being in my dataset.

I also noticed that in some iterations of PipeTuner, the detections log file seems empty. For example:

  • output/road_MOT.yml_output/checkpoints/DsAppRun_output_20241124_031638/0/54.txt contains detections.
  • output/road_MOT.yml_output/checkpoints/DsAppRun_output_20241124_031419/0/54.txt does not contain detections.

Overall, I think my dataset is analogous to the sample provided, so I cannot understand why it doesn’t work. Among the considerations listed above, the only thing I’m not sure about is if IDs should be shared between classes or not (mine are not), as the sample dataset only considers one class.

I would greatly appreciate some insight about this issue. Thanks in advance.

Can you share the model and the dataset too?

I cannot share the model trained with our data or the full dataset used in PipeTuner, but I can share a couple of those videos with annotations and the YOLO11s model from the Ultralytics Zoo already exported in the same way to ONNX at same resolution. As this model’s labels are the same for the annotated data, the situation is identical, model still detects objects when running deepstream-app in the container but PipeTuner gives DsApp score 0.0 or negative.

Here I share the data and model files:
data.zip (67.8 MB)
models.zip (31.0 MB)

For ease of testing, I’m sharing as well the project based on pipe-tuner-sample that I’m using after modifying the sample one to prepare and run the tool in the same fashion:
pipe-tuner-road.zip (5.0 MB)

You can just run it in a similar way, this already downloads model, data, and builds the new DeepStream Docker image:

cd pipe-tuner-road/scripts

wget "https://universidadevigo-my.sharepoint.com/:u:/g/personal/david_conde_morales_uvigo_gal/EWUJ9KliKINJpvr4SNBj6awBQCdo_72spxnDsPOe4X14Pg?e=7e63ku&download=1" -O ../data_road.zip
unzip -o ../data_road.zip -d ..
rm ../data_road.zip

sudo bash setup.sh deepstream-yolo
sudo bash launch.sh deepstream-yolo:7.0-triton-multiarch ../configs/config_PipeTuner/road_MOT.yml

Again, I attach the output logs using this modified setup (only first 2 checkpoint due to 100 MB upload limit):
output.zip (85.0 MB)

Can you refer to Pipetuner, DsApp score is 0 - #10 by pshin to check first?

Thanks for the reference. This guideline helped me to identify that the default ranges of NvDCF parameters in SDG_sample_PeopleNet-ResNet34_NvDCF-ResNet50_MOT.yml was not adequate for my dataset since I could not get any output when running deepstream-app from the container using any of the dsAppConfig_0.txt that are in each checkpoint.

By freezing the NvDCF parameters ranges (by commenting them) to just tune the PGIE, I could see bounding boxes when running deepstream-app with each dsAppConfig_0.txt after setting [sink0] type=2 and [osd] enable=1 for visualization. Here are all the config files I’m currently using, for reference:
configs.zip (8.4 KB)

However, the evaluation is still returning 0.0 and negative values using either MOTA or HOTA. This is not happening if with the same modifications I replace the dataset directories to the original sample data instead of my dataset.

Something I noticed is that in every checkpoint, there is a trackeval.txt file that contains weird references like this: CLASSES_TO_EVAL : ['pedestrian'] I guess this makes sense for the sample dataset that just detects people, but in my case I have several classes for vehicles. Here is a full example of one of my trackeval.txt files:

Error importing BURST due to missing underlying dependency: No module named 'pycocotools'

Eval Config:
USE_PARALLEL         : False                         
NUM_PARALLEL_CORES   : 8                             
BREAK_ON_ERROR       : True                          
RETURN_ON_ERROR      : False                         
LOG_ON_ERROR         : /pipe-tuner/3rdparty/TrackEval/error_log.txt
PRINT_RESULTS        : True                          
PRINT_ONLY_COMBINED  : False                         
PRINT_CONFIG         : True                          
TIME_PROGRESS        : True                          
DISPLAY_LESS_PROGRESS : False                         
OUTPUT_SUMMARY       : True                          
OUTPUT_EMPTY_CLASSES : True                          
OUTPUT_DETAILED      : True                          
PLOT_CURVES          : True                          

MotChallenge2DBox Config:
PRINT_CONFIG         : True                          
GT_FOLDER            : /home/david/sources/pipetuner/pipe-tuner-road/data/road_videos
TRACKERS_FOLDER      : /home/david/sources/pipetuner/pipe-tuner-road/output/road_MOT.yml_output/checkpoints/DsAppRun_output_20241201_122949/0
OUTPUT_FOLDER        : None                          
TRACKERS_TO_EVAL     : ['./']                        
CLASSES_TO_EVAL      : ['pedestrian']                
BENCHMARK            :                               
SPLIT_TO_EVAL        :                               
INPUT_AS_ZIP         : False                         
DO_PREPROC           : True                          
TRACKER_SUB_FOLDER   :                               
OUTPUT_SUB_FOLDER    :                               
TRACKER_DISPLAY_NAMES : None                          
SEQMAP_FOLDER        : None                          
SEQMAP_FILE          : /home/david/sources/pipetuner/pipe-tuner-road/data/road_utils/road_all.txt
SEQ_INFO             : None                          
GT_LOC_FORMAT        : {gt_folder}/{seq}/gt/gt.txt   
SKIP_SPLIT_FOL       : False                         

CLEAR Config:
METRICS              : ['Identity', 'CLEAR', 'HOTA'] 
THRESHOLD            : 0.5                           
PRINT_CONFIG         : True                          

Identity Config:
METRICS              : ['Identity', 'CLEAR', 'HOTA'] 
THRESHOLD            : 0.5                           
PRINT_CONFIG         : True                          

Evaluating 1 tracker(s) on 1 sequence(s) for 1 class(es) on MotChallenge2DBox dataset using the following metrics: HOTA, CLEAR, Identity, Count


Evaluating ./

    MotChallenge2DBox.get_raw_seq_data(./, 54)                             0.0161 sec
    MotChallenge2DBox.get_preprocessed_seq_data(pedestrian)                0.0234 sec
    HOTA.eval_sequence()                                                   0.0000 sec
    CLEAR.eval_sequence()                                                  0.0000 sec
    Identity.eval_sequence()                                               0.0000 sec
    Count.eval_sequence()                                                  0.0000 sec
1 eval_sequence(54, ./)                                                  0.0400 sec

All sequences for ./ finished in 0.04 seconds

HOTA: ./-pedestrian                HOTA      DetA      AssA      DetRe     DetPr     AssRe     AssPr     LocA      OWTA      HOTA(0)   LocA(0)   HOTALocA(0)
COMBINED                           0         0         0         0         0         0         0         100       0         0         100       0         
54                                 0         0         0         0         0         0         0         100       0         0         100       0         

CLEAR: ./-pedestrian               MOTA      MOTP      MODA      CLR_Re    CLR_Pr    MTR       PTR       MLR       sMOTA     CLR_TP    CLR_FN    CLR_FP    IDSW      MT        PT        ML        Frag      
COMBINED                           -100      0         -100      0         0         0         0         0         -100      0         0         1         0         0         0         0         0         
54                                 0         0         0         0         0         0         0         100       0         0         0         1         0         0         0         0         0         

Identity: ./-pedestrian            IDF1      IDR       IDP       IDTP      IDFN      IDFP      
COMBINED                           0         0         0         0         0         1         
54                                 0         0         0         0         0         1         

Count: ./-pedestrian               Dets      GT_Dets   IDs       GT_IDs    
COMBINED                           1         0         1         0         
54                                 1         0         1         0         

Timing analysis:
MotChallenge2DBox.get_raw_seq_data                                     0.0161 sec
MotChallenge2DBox.get_preprocessed_seq_data                            0.0234 sec
HOTA.eval_sequence                                                     0.0000 sec
CLEAR.eval_sequence                                                    0.0000 sec
Identity.eval_sequence                                                 0.0000 sec
Count.eval_sequence                                                    0.0000 sec
eval_sequence                                                          0.0400 sec
Evaluator.evaluate                                                     0.6241 sec

I include as well my new output directory with all the logs:
output.zip (4.5 MB)

I also noticed that in the config_GuiTool files, you can select a different EvalDevKitType, and while the comment states that 0 is the default value (MATLAB-based devkit), actually value 2 (TrackEval) is the one in sample files.

If I change that value to 0, I see in the checkpoint’s eval_cmd.txt this:

[ERROR] MOT16 MATLAB Dev-kit configs are missing, so no quant. eval will be performed. 

Since there’s no documentation about these alternatives, I would appreciate any help solving the problem either by using the TrackEval devkit or with more info on the other ones.

Hi PipeTuner user,
By default PipeTuner only optimizes parameters for Person class. If you want to enable car tracking, set USE_CAR=1 in /pipe-tuner/utils/kittiTrack2mot.sh inside container.
You can also change that script to add support for other classes.

Hi, thank you for your quick response, and sorry for my delay while trying to fix the problem given your input.

So as it turns out for my case, I actually need multiple classes to be evaluated, for which I replaced this snippet in /pipe-tuner/utils/kittiTrack2mot.sh:

declare -A IDMAP
if [[ $USE_CAR == 1 ]]
then
IDMAP=(
    [Person]=0
    [Car]=1
    [Bicycle]=0
    [Roadsign]=0
    [Bag]=0
    [person]=0
    [car]=1
    [bicycle]=0
    [roadsign]=0
    [bag]=0
)
else
IDMAP=(
    [Person]=1
    [Car]=0
    [Bicycle]=0
    [Roadsign]=0
    [Bag]=0
    [person]=1
    [car]=0
    [bicycle]=0
    [roadsign]=0
    [bag]=0
)
fi

With this other one:

declare -A IDMAP
IDMAP=(
    [Person]=1
    [Bicycle]=2
    [Car]=3
    [Motorcycle]=4
    [Airplane]=5
    [Bus]=6
    [Train]=7
    [Truck]=8
    [Cone]=9
    [Feeder]=10
    [Paver]=11
    [Other_vehicle]=12
    [person]=1
    [bicycle]=2
    [car]=3
    [motorcycle]=4
    [airplane]=5
    [bus]=6
    [train]=7
    [truck]=8
    [cone]=9
    [feeder]=10
    [paver]=11
    [other_vehicle]=12
)

This matches the labels.txt of my model:

person
bicycle
car
motorcycle
airplane
bus
train
truck
cone
feeder
paver
other_vehicle

Also, I noticed there’s a similar IDMAP in kittiTrack2mot.sh:

declare -A IDMAP
IDMAP=(
    [Person]=1
    [Car]=0
    [Bicycle]=0
    [Roadsign]=0
    [Bag]=0
)

I replaced this one as well with the same snippet of 12 classes I included above.

I performed these changes and committed them to a new PipeTuner Docker image to launch on launch.sh. When running it, once it starts to run the optimization iterations, I’m always getting this error:

2024-12-05 17:07:48,274 root         INFO     progress: 0% (0/200)
2024-12-05 17:07:58,492 root         INFO     progress: 0% (0/200)
Invalid exit code: results not processed.Sending an error result
stdout

DS-App Mode Eval Config File = /home/david/sources/pipetuner/pipe-tuner-road/output/road_MOT.yml_output/results/configs_12-05-2024_17-07-38/config_GuiTool/config_GuiTool.yml


PGIE Config File = /home/david/sources/pipetuner/pipe-tuner-road/output/road_MOT.yml_output/results/configs_12-05-2024_17-07-38/config_PGIE/config_infer_primary_yoloV11.txt


Tracker Config File = /home/david/sources/pipetuner/pipe-tuner-road/output/road_MOT.yml_output/results/configs_12-05-2024_17-07-38/config_Tracker/config_tracker_NvDCF_accuracy_YOLO.yml

stderr
mv: cannot stat 'trackerViz/Stream_0*': No such file or directory
/pipe-tuner/utils/kittiDetect2mot.sh: line 83: kitti_detector/54/00_000_000265.txt: No such file or directory
/pipe-tuner/utils/kittiDetect2mot.sh: line 83: kitti_detector/54/00_000_000267.txt: No such file or directory
/pipe-tuner/utils/kittiDetect2mot.sh: line 83: kitti_detector/54/00_000_000271.txt: No such file or directory
/pipe-tuner/utils/kittiDetect2mot.sh: line 83: kitti_detector/54/00_000_000272.txt: No such file or directory
/pipe-tuner/utils/kittiDetect2mot.sh: line 83: kitti_detector/54/00_000_000273.txt: No such file or directory
/pipe-tuner/utils/kittiDetect2mot.sh: line 83: kitti_detector/54/00_000_000275.txt: No such file or directory
/pipe-tuner/utils/kittiDetect2mot.sh: line 83: kitti_detector/54/00_000_000276.txt: No such file or directory
/pipe-tuner/utils/kittiDetect2mot.sh: line 83: kitti_detector/54/00_000_000277.txt: No such file or directory
/pipe-tuner/utils/kittiDetect2mot.sh: line 83: kitti_detector/54/00_000_000279.txt: No such file or directory
/pipe-tuner/utils/kittiDetect2mot.sh: line 83: kitti_detector/54/00_000_000280.txt: No such file or directory
/pipe-tuner/utils/kittiDetect2mot.sh: line 83: kitti_detector/54/00_000_000282.txt: No such file or directory
/pipe-tuner/utils/kittiDetect2mot.sh: line 83: kitti_detector/54/00_000_000283.txt: No such file or directory
/pipe-tuner/utils/kittiDetect2mot.sh: line 83: kitti_detector/54/00_000_000284.txt: No such file or directory
/pipe-tuner/utils/kittiDetect2mot.sh: line 83: kitti_detector/54/00_000_000287.txt: No such file or directory
/pipe-tuner/utils/kittiDetect2mot.sh: line 83: kitti_detector/54/00_000_000288.txt: No such file or directory
/pipe-tuner/utils/kittiDetect2mot.sh: line 83: kitti_detector/54/00_000_000289.txt: No such file or directory
/pipe-tuner/utils/kittiTrack2mot.sh: line 114: MOT_evaluate/54/00_000_000267.txt: No such file or directory
/pipe-tuner/utils/kittiTrack2mot.sh: line 114: MOT_evaluate/54/00_000_000273.txt: No such file or directory
/pipe-tuner/utils/kittiTrack2mot.sh: line 114: MOT_evaluate/54/00_000_000275.txt: No such file or directory
/pipe-tuner/utils/kittiTrack2mot.sh: line 114: MOT_evaluate/54/00_000_000276.txt: No such file or directory
/pipe-tuner/utils/kittiTrack2mot.sh: line 114: MOT_evaluate/54/00_000_000277.txt: No such file or directory
/pipe-tuner/utils/kittiTrack2mot.sh: line 114: MOT_evaluate/54/00_000_000279.txt: No such file or directory
/pipe-tuner/utils/kittiTrack2mot.sh: line 114: MOT_evaluate/54/00_000_000283.txt: No such file or directory
/pipe-tuner/utils/kittiTrack2mot.sh: line 114: MOT_evaluate/54/00_000_000284.txt: No such file or directory
/pipe-tuner/utils/kittiTrack2mot.sh: line 114: MOT_evaluate/54/00_000_000288.txt: No such file or directory
/pipe-tuner/utils/kittiTrack2mot.sh: line 114: MOT_evaluate/54/00_000_000289.txt: No such file or directory
terminate called after throwing an instance of 'std::out_of_range'
  what():  stof

Invalid exit code: results not processed.Sending an error result
stdout

DS-App Mode Eval Config File = /home/david/sources/pipetuner/pipe-tuner-road/output/road_MOT.yml_output/results/configs_12-05-2024_17-07-38/config_GuiTool/config_GuiTool.yml


PGIE Config File = /home/david/sources/pipetuner/pipe-tuner-road/output/road_MOT.yml_output/results/configs_12-05-2024_17-07-38/config_PGIE/config_infer_primary_yoloV11.txt


Tracker Config File = /home/david/sources/pipetuner/pipe-tuner-road/output/road_MOT.yml_output/results/configs_12-05-2024_17-07-38/config_Tracker/config_tracker_NvDCF_accuracy_YOLO.yml

stderr
mv: cannot stat 'kitti_detector/00_000*': No such file or directory
mv: cannot stat 'MOT_evaluate/00_000*': No such file or directory
mv: cannot stat 'trackerViz/Stream_0*': No such file or directory
terminate called after throwing an instance of 'std::out_of_range'
  what():  stof

2024-12-05 17:08:08,409 root         ERROR    Error while reading results, reschedule job. number of fails 3
2024-12-05 17:08:08,409 root         ERROR    Error while reading results, reschedule job. number of fails 4
2024-12-05 17:08:08,710 root         ERROR    Too many DS app fails. We stop all processes. Please check DS app logs
2024-12-05 17:08:08,710 root         ERROR    OPTIMIZATION not completed!
received /reset call
[server core] resetting
stopping result senders...
done.
stopping workers...
number of workers to stop: 2
number of workers to stop: 0
done.

I’m including again the new output directory:
output.zip (4.0 MB)

I guess there may be other files I need to modify to suit my case, or maybe I didn’t changed all I needed to on kittiTrack2mot.sh and kittiDetect2mot.sh? Also I wasn’t sure if on the IDMAP I actually needed to define the classes numbers starting on 1, or if it was just a binary value, but either case if I just set everything to 1 it fails with same error.