Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Benchmark multiple different pipelines running in parallel #18

Merged
merged 6 commits into from
Nov 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 17 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,12 @@
MKDOCS_IMAGE ?= asc-mkdocs
PIPELINE_COUNT ?= 1
TARGET_FPS ?= 14.95
CONTAINER_NAMES ?= gst0
DOCKER_COMPOSE ?= docker-compose.yml
RESULTS_DIR ?= $(PWD)/results
RETAIL_USE_CASE_ROOT ?= $(PWD)
BENCHMARK_DURATION ?= 45
DENSITY_INCREMENT ?= 1

download-models: download-yolov8s
./download_models/downloadModels.sh
Expand Down Expand Up @@ -90,16 +92,28 @@ build-benchmark:
cd performance-tools && $(MAKE) build-benchmark-docker

benchmark: build-benchmark download-models
cd performance-tools/benchmark-scripts && python benchmark.py --compose_file ../../src/docker-compose.yml \
cd performance-tools/benchmark-scripts && python benchmark.py --compose_file ../../src/$(DOCKER_COMPOSE) \
--pipeline $(PIPELINE_COUNT) --duration $(BENCHMARK_DURATION) --results_dir $(RESULTS_DIR)
# consolidate to show the summary csv
@cd performance-tools/benchmark-scripts && ROOT_DIRECTORY=$(RESULTS_DIR) $(MAKE) --no-print-directory consolidate && \
echo "Loss Prevention benchmark results are saved in $(RESULTS_DIR)/summary.csv file" && \
echo "====== Loss prevention benchmark results summary: " && cat $(RESULTS_DIR)/summary.csv

benchmark-stream-density: build-benchmark download-models
cd performance-tools/benchmark-scripts && python benchmark.py --compose_file ../../src/docker-compose.yml \
--target_fps $(TARGET_FPS) --density_increment 1 --results_dir $(RESULTS_DIR)
# example commands:
# 1. for single container pipeline stream density
# ```console
# make PIPELINE_SCRIPT=yolov8s_roi.sh benchmark-stream-density
# ```
# 2. for multiple container pipelines stream density:
# ```console
# make DOCKER_COMPOSE=docker-compose-2-clients.yml BENCHMARK_DURATION=90 TARGET_FPS="10.95 2.95" CONTAINER_NAMES="gst1 gst2" \
# benchmark-stream-density
# ```
#
cd performance-tools/benchmark-scripts && python benchmark.py --compose_file ../../src/$(DOCKER_COMPOSE) \
--target_fps $(TARGET_FPS) --container_names $(CONTAINER_NAMES) \
--density_increment $(DENSITY_INCREMENT) --results_dir $(RESULTS_DIR)

clean-benchmark-results:
cd performance-tools/benchmark-scripts && rm -rf $(RESULTS_DIR)/* || true
Expand Down
45 changes: 43 additions & 2 deletions benchmark.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ make benchmark
!!! Note
For more details on how this works, you can check the documentation of performance-tools in [Benchmark a CV Pipeline](https://github.com/intel-retail/documentation/blob/main/docs_src/performance-tools/benchmark.md#benchmark-a-cv-pipeline) section.

1. Benchmarking the stream density of the loss-prevention pipelines:
2. Benchmarking the stream density of the loss-prevention pipelines:

```bash
make benchmark-stream-density
Expand All @@ -38,6 +38,45 @@ make benchmark-stream-density
!!! Note
For more details on how this works, you can check the documentation of performance-tools in [Benchmark Stream Density for CV Pipelines](https://github.com/intel-retail/documentation/blob/main/docs_src/performance-tools/benchmark.md#benchmark-stream-density-for-cv-pipelines) section.

### Benchmark for multiple pipelines in parallel

There is an example docker-compose file under src/ directory, named `docker-compose-2-clients.yml` that can be used to show case both of benchmarks of parallel running pipelines and stream density benchmarks of running pipelines. This docker-compose file contains two different running pipelines: one is running yolov5s pipeline and the other one is yolov8 region of interests pipeline. Use the following command examples to do the benchmarks:

```bash
make update-submodules
```

and then re-build the whole benchmark tools:

```bash
make build-benchmark
```

then clean up the previous results to have a fresh start:

```bash
make clean-benchmark-results
```

and then you can benchmark multiple different running pipelines in that compose file via:

```bash
make DOCKER_COMPOSE=docker-compose-2-clients.yml BENCHMARK_DURATION=90 benchmark
```

!!! Note
BENCHMARK_DURATION is proveded to have longer time for pipelines as more pipelines running in parallel in the docker-compose tend to slow down the system and need more time for all pipelines to be stabilized. Adjust this input accordingly for your hardware system.

and then you can also do the stream density of both running pipelines in this docker-compose file via the following command:

```bash
make DOCKER_COMPOSE=docker-compose-2-clients.yml BENCHMARK_DURATION=90 TARGET_FPS="10.95 2.95" CONTAINER_NAMES="gst1 gst2" benchmark-stream-density
```

!!! Note
The stream density benchmarks can take long time depending on your hardware system. Please allow it to run until to the end to see the benchmark result.


## Tuning Benchmark Parameters

You can tune some benchmark parameters when you benchmark loss-prevention pipelines:
Expand All @@ -46,7 +85,9 @@ You can tune some benchmark parameters when you benchmark loss-prevention pipeli
| -----------------------|-----------------|----------------------------------------------------------------------|
| PIPELINE_COUNT | 1 | number of loss-prevention pipelines to launch for benchmarking |
| BENCHMARK_DURATION | 45 | the time period of benchmarking will be run in second |
| TARGET_FPS | 14.95 | used for stream density maintaining that target frames per second (fps) while having maximum number of pipelines running |
| TARGET_FPS | 14.95 | used for stream density maintaining that target frames per second (fps) while having maximum number of pipelines running and this can be multiple values with whitespace delimited for multiple running pipelines |
| CONTAINER_NAMES | gst0 | used for stream density to have target container name list for multiple running pipelines and paired with TARGET_FPS to have 1-to-1 mapping with the pipeline |
| DENSITY_INCREMENT | 1 | used for stream density to set the pipeline increment number for each iteration |
| RESULTS_DIR | ./results | the directory of the outputs for running pipeline logs and fps info |
| PIPELINE_SCRIPT | yolov5s.sh | the script to run the pipeline, for yolov8, you can use yolov8s_roi.sh for running region of interest pipeline |
| RENDER_MODE | 0 | when it is set to 1, another popup winodw will display the input source video and some of inferencing results like bounding boxes and/or region of interests |
Expand Down
125 changes: 125 additions & 0 deletions src/docker-compose-2-clients.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
#
# Copyright (C) 2024 Intel Corporation.
#
# SPDX-License-Identifier: Apache-2.0
#


## Current Developer Toolbox doesn't support environment files, make sure to remove any files or environment variables starting with $
version: '3.7'
services:
camera-simulator:
container_name: camera-simulator
image: aler9/rtsp-simple-server
ports:
- "127.0.0.1:8554:8554"
camera-simulator0:
image: jrottenberg/ffmpeg:4.1-alpine
container_name: camera-simulator0
network_mode: "host"
entrypoint: ["/bin/sh","-c"]
command:
- |
if [ ! -f /home/pipeline-server/sample-media/coca-cola-4465029-1920-15-bench.mp4 ]; then
mkdir -p /home/pipeline-server/sample-media
wget -O /home/pipeline-server/sample-media/coca-cola-4465029-1920-15-bench.mp4 https://www.pexels.com/download/video/4465029
fi
ffmpeg -nostdin -re -stream_loop -1 -i /home/pipeline-server/sample-media/coca-cola-4465029-1920-15-bench.mp4 -c copy -f rtsp -rtsp_transport tcp rtsp://localhost:8554/camera_0
depends_on:
- camera-simulator
volumes:
- ${RETAIL_USE_CASE_ROOT:-..}/performance-tools/sample-media:/home/pipeline-server/sample-media

GstClient1:
image: dlstreamer:dev
deploy:
mode: replicated
replicas: ${PIPELINE_COUNT:-1}
network_mode: "host"
entrypoint: /script/entrypoint.sh --pipeline_script_choice ${PIPELINE_SCRIPT:-yolov5s.sh}
privileged: true
ipc: "host"
env_file:
- ./res/gst.env
- ${DEVICE_ENV:-res/all-cpu.env}
environment:
- CONTAINER_NAME=gst1
- INPUTSRC=${INPUTSRC:-rtsp://localhost:8554/camera_0}
- RENDER_MODE=${RENDER_MODE:-0} #RENDER_MODE=1 will work only after running xhost +local:docker
- DISPLAY=$DISPLAY
- HTTP_PROXY
- HTTPS_PROXY
- NO_PROXY
volumes:
- ${RESULTS_DIR:-../results}:/tmp/results
- ~/.Xauthority:/home/dlstreamer/.Xauthority
- /tmp/.X11-unix
- ~/.cl-cache:/home/pipeline-server/.cl-cache
- ./res/:/home/pipeline-server/envs
- ${RETAIL_USE_CASE_ROOT:-..}/models:/home/pipeline-server/models
- ./pipelines/:/home/pipeline-server/pipelines
- ./extensions/:/home/pipeline-server/extensions

GstClient2:
image: dlstreamer:dev
deploy:
mode: replicated
replicas: ${PIPELINE_COUNT:-1}
network_mode: "host"
entrypoint: /script/entrypoint.sh --pipeline_script_choice ${PIPELINE_SCRIPT:-yolov8s_roi.sh}
privileged: true
ipc: "host"
env_file:
- ./res/gst.env
- ${DEVICE_ENV:-res/all-cpu.env}
environment:
- CONTAINER_NAME=gst2
- INPUTSRC=${INPUTSRC:-https://github.com/openvinotoolkit/openvino_notebooks/raw/refs/heads/recipes/recipes/automated_self_checkout/data/example.mp4}
- RENDER_MODE=${RENDER_MODE:-0} #RENDER_MODE=1 will work only after running xhost +local:docker
- DISPLAY=$DISPLAY
- HTTP_PROXY
- HTTPS_PROXY
- NO_PROXY
volumes:
- ${RESULTS_DIR:-../results}:/tmp/results
- ~/.Xauthority:/home/dlstreamer/.Xauthority
- /tmp/.X11-unix
- ~/.cl-cache:/home/pipeline-server/.cl-cache
- ./res/:/home/pipeline-server/envs
- ${RETAIL_USE_CASE_ROOT:-..}/models:/home/pipeline-server/models
- ./pipelines/:/home/pipeline-server/pipelines
- ./extensions/:/home/pipeline-server/extensions

mosquitto:
image: eclipse-mosquitto:2.0
container_name: mosquitto
network_mode: "host"
ports:
- "127.0.0.1:1883:1883"
depends_on:
- GstClient1
- GstClient2

mqtt_tracker:
image: loss-prevention:dev
network_mode: "host"
environment:
- MQTT_URL=127.0.0.1
- MQTT_PORT=1883
- MQTT_TOPIC=event/detection
- ROI_NAME=BASKET
restart: always
depends_on:
- mosquitto

loss-prevention:
image: loss-prevention:dev
network_mode: "host"
environment:
- MQTT_URL=127.0.0.1
- MQTT_PORT=1883
- MQTT_TOPIC=event/detection
- ROI_NAME=BASKET,BAGGING
restart: always
depends_on:
- mosquitto
16 changes: 10 additions & 6 deletions src/entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ checkBatchSize() {
}

cid_count="${cid_count:=0}"
CONTAINER_NAME="${CONTAINER_NAME:=gst}"
cameras="${cameras:=}"
stream_density_mount="${stream_density_mount:=}"
stream_density_params="${stream_density_params:=}"
Expand Down Expand Up @@ -125,14 +126,17 @@ fi

# generate unique container id based on the date with the precision upto nano-seconds
cid=$(date +%Y%m%d%H%M%S%N)
CONTAINER_NAME="${CONTAINER_NAME//\"/}" # Ensure to remove all double quotes from CONTAINER_NAME
cid="${cid}"_${CONTAINER_NAME}
echo "CONTAINER_NAME: ${CONTAINER_NAME}"
echo "cid: $cid"

touch /tmp/results/r"$cid"_gst.jsonl
chown 1000:1000 /tmp/results/r"$cid"_gst.jsonl
touch /tmp/results/gst-launch_"$cid"_gst.log
chown 1000:1000 /tmp/results/gst-launch_"$cid"_gst.log
touch /tmp/results/pipeline"$cid"_gst.log
chown 1000:1000 /tmp/results/pipeline"$cid"_gst.log
touch /tmp/results/r"$cid".jsonl
chown 1000:1000 /tmp/results/r"$cid".jsonl
touch /tmp/results/gst-launch_"$cid".log
chown 1000:1000 /tmp/results/gst-launch_"$cid".log
touch /tmp/results/pipeline"$cid".log
chown 1000:1000 /tmp/results/pipeline"$cid".log

cl_cache_dir="/home/pipeline-server/.cl-cache" \
DISPLAY="$DISPLAY" \
Expand Down
4 changes: 2 additions & 2 deletions src/pipelines/age_recognition.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

PRE_PROCESS="${PRE_PROCESS:=""}" #""|pre-process-backend=vaapi-surface-sharing|pre-process-backend=vaapi-surface-sharing pre-process-config=VAAPI_FAST_SCALE_LOAD_FACTOR=1
AGGREGATE="${AGGREGATE:="gvametaaggregate name=aggregate !"}" # Aggregate function at the end of the pipeline ex. "" | gvametaaggregate name=aggregate
PUBLISH="${PUBLISH:="name=destination file-format=2 file-path=/tmp/results/r$cid\"_gst\".jsonl"}" # address=localhost:1883 topic=inferenceEvent method=mqtt
PUBLISH="${PUBLISH:="name=destination file-format=2 file-path=/tmp/results/r$cid.jsonl"}" # address=localhost:1883 topic=inferenceEvent method=mqtt

CLASSIFICATION_OPTIONS="${CLASSIFICATION_OPTIONS:="reclassify-interval=1 $DETECTION_OPTIONS"}" # Extra Classification model parameters ex. "" | reclassify-interval=1 batch-size=1 nireq=4 gpu-throughput-streams=4

Expand All @@ -29,7 +29,7 @@ gstLaunchCmd="gst-launch-1.0 $inputsrc ! $DECODE ! \
gvadetect batch-size=$BATCH_SIZE model-instance-id=odmodel name=detection model=$DETECT_MODEL_PATH threshold=.8 device=$DEVICE ! \
gvaclassify batch-size=$BATCH_SIZE model-instance-id=classifier name=recognition model-proc=$CLASS_MODEL_PROC_PATH model=$CLASS_MODEL_PATH device=$DEVICE $CLASSIFICATION_OPTIONS ! \
$AGGREGATE gvametaconvert name=metaconvert add-empty-results=true ! \
gvametapublish name=destination file-format=2 file-path=/tmp/results/r$cid\"_gst\".jsonl $OUTPUT 2>&1 | tee >/tmp/results/gst-launch_$cid\"_gst\".log >(stdbuf -oL sed -n -e 's/^.*current: //p' | stdbuf -oL cut -d , -f 1 > /tmp/results/pipeline$cid\"_gst\".log)"
gvametapublish name=destination file-format=2 file-path=/tmp/results/r$cid.jsonl $OUTPUT 2>&1 | tee >/tmp/results/gst-launch_$cid.log >(stdbuf -oL sed -n -e 's/^.*current: //p' | stdbuf -oL cut -d , -f 1 > /tmp/results/pipeline$cid.log)"

echo "$gstLaunchCmd"

Expand Down
4 changes: 2 additions & 2 deletions src/pipelines/people_detection.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

PRE_PROCESS="${PRE_PROCESS:=""}" #""|pre-process-backend=vaapi-surface-sharing|pre-process-backend=vaapi-surface-sharing pre-process-config=VAAPI_FAST_SCALE_LOAD_FACTOR=1
AGGREGATE="${AGGREGATE:="gvametaaggregate name=aggregate !"}" # Aggregate function at the end of the pipeline ex. "" | gvametaaggregate name=aggregate
PUBLISH="${PUBLISH:="name=destination file-format=2 file-path=/tmp/results/r$cid\"_gst\".jsonl"}" # address=localhost:1883 topic=inferenceEvent method=mqtt
PUBLISH="${PUBLISH:="name=destination file-format=2 file-path=/tmp/results/r$cid.jsonl"}" # address=localhost:1883 topic=inferenceEvent method=mqtt

ROI="${ROI:="0,0,400,400"}"

Expand All @@ -20,7 +20,7 @@ fi
echo "decode type $DECODE"
echo "Run person-detection pipeline on $DEVICE with batch size = $BATCH_SIZE"

gstLaunchCmd="GST_DEBUG=\"GST_TRACER:7\" GST_TRACERS=\"latency_tracer(flags=pipeline,interval=100)\" gst-launch-1.0 $inputsrc ! $DECODE ! gvaattachroi roi=$ROI ! gvadetect batch-size=$BATCH_SIZE model-instance-id=odmodel name=detection model=models/object_detection/person-detection-0200/FP16-INT8/person-detection-0200.xml threshold=.5 device=$DEVICE $PRE_PROCESS inference-region=1 ! $AGGREGATE gvametaconvert name=metaconvert add-empty-results=true ! gvametapublish name=destination file-format=2 file-path=/tmp/results/r$cid\"_gst\".jsonl $OUTPUT 2>&1 | tee >/tmp/results/gst-launch_$cid\"_gst\".log >(stdbuf -oL sed -n -e 's/^.*current: //p' | stdbuf -oL cut -d , -f 1 > /tmp/results/pipeline$cid\"_gst\".log)"
gstLaunchCmd="GST_DEBUG=\"GST_TRACER:7\" GST_TRACERS=\"latency_tracer(flags=pipeline,interval=100)\" gst-launch-1.0 $inputsrc ! $DECODE ! gvaattachroi roi=$ROI ! gvadetect batch-size=$BATCH_SIZE model-instance-id=odmodel name=detection model=models/object_detection/person-detection-0200/FP16-INT8/person-detection-0200.xml threshold=.5 device=$DEVICE $PRE_PROCESS inference-region=1 ! $AGGREGATE gvametaconvert name=metaconvert add-empty-results=true ! gvametapublish name=destination file-format=2 file-path=/tmp/results/r$cid.jsonl $OUTPUT 2>&1 | tee >/tmp/results/gst-launch_$cid\"_gst\".log >(stdbuf -oL sed -n -e 's/^.*current: //p' | stdbuf -oL cut -d , -f 1 > /tmp/results/pipeline$cid.log)"

echo "$gstLaunchCmd"

Expand Down
4 changes: 2 additions & 2 deletions src/pipelines/yolov5s.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

PRE_PROCESS="${PRE_PROCESS:=""}" #""|pre-process-backend=vaapi-surface-sharing|pre-process-backend=vaapi-surface-sharing pre-process-config=VAAPI_FAST_SCALE_LOAD_FACTOR=1
AGGREGATE="${AGGREGATE:="gvametaaggregate name=aggregate !"}" # Aggregate function at the end of the pipeline ex. "" | gvametaaggregate name=aggregate
PUBLISH="${PUBLISH:="name=destination file-format=2 file-path=/tmp/results/r$cid\"_gst\".jsonl"}" # address=localhost:1883 topic=inferenceEvent method=mqtt
PUBLISH="${PUBLISH:="name=destination file-format=2 file-path=/tmp/results/r$cid.jsonl"}" # address=localhost:1883 topic=inferenceEvent method=mqtt

if [ "$RENDER_MODE" == "1" ]; then
OUTPUT="${OUTPUT:="! videoconvert ! video/x-raw,format=I420 ! gvawatermark ! videoconvert ! fpsdisplaysink video-sink=ximagesink sync=true --verbose"}"
Expand All @@ -18,7 +18,7 @@ fi
echo "decode type $DECODE"
echo "Run yolov5s pipeline on $DEVICE with batch size = $BATCH_SIZE"

gstLaunchCmd="GST_DEBUG=\"GST_TRACER:7\" GST_TRACERS=\"latency_tracer(flags=pipeline,interval=100)\" gst-launch-1.0 $inputsrc ! $DECODE ! gvadetect batch-size=$BATCH_SIZE model-instance-id=odmodel name=detection model=models/object_detection/yolov5s/FP16-INT8/yolov5s.xml model-proc=models/object_detection/yolov5s/yolov5s.json threshold=.5 device=$DEVICE $PRE_PROCESS ! $AGGREGATE gvametaconvert name=metaconvert add-empty-results=true ! gvametapublish name=destination file-format=2 file-path=/tmp/results/r$cid\"_gst\".jsonl $OUTPUT 2>&1 | tee >/tmp/results/gst-launch_$cid\"_gst\".log >(stdbuf -oL sed -n -e 's/^.*current: //p' | stdbuf -oL cut -d , -f 1 > /tmp/results/pipeline$cid\"_gst\".log)"
gstLaunchCmd="GST_DEBUG=\"GST_TRACER:7\" GST_TRACERS=\"latency_tracer(flags=pipeline,interval=100)\" gst-launch-1.0 $inputsrc ! $DECODE ! gvadetect batch-size=$BATCH_SIZE model-instance-id=odmodel name=detection model=models/object_detection/yolov5s/FP16-INT8/yolov5s.xml model-proc=models/object_detection/yolov5s/yolov5s.json threshold=.5 device=$DEVICE $PRE_PROCESS ! $AGGREGATE gvametaconvert name=metaconvert add-empty-results=true ! gvametapublish name=destination file-format=2 file-path=/tmp/results/r$cid.jsonl $OUTPUT 2>&1 | tee >/tmp/results/gst-launch_$cid.log >(stdbuf -oL sed -n -e 's/^.*current: //p' | stdbuf -oL cut -d , -f 1 > /tmp/results/pipeline$cid.log)"

echo "$gstLaunchCmd"

Expand Down
Loading
Loading