Skip to content

Commit c99725e

Browse files
Merge branch 'main' into fix/instance-segmentation-post-processing
2 parents 4657396 + 3153b3c commit c99725e

File tree

15 files changed

+190
-169
lines changed

15 files changed

+190
-169
lines changed

docker/dockerfiles/Dockerfile.onnx.jetson.4.6.1

Lines changed: 29 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -85,34 +85,34 @@ COPY Makefile Makefile
8585
RUN make create_inference_cli_whl PYTHON=python3.9
8686
RUN python3.9 -m pip install dist/inference_cli*.whl
8787

88-
ENV VERSION_CHECK_MODE=continuous
89-
ENV PROJECT=roboflow-platform
90-
ENV ORT_TENSORRT_FP16_ENABLE=1
91-
ENV ORT_TENSORRT_ENGINE_CACHE_ENABLE=1
92-
ENV PROJECT=roboflow-platform
93-
ENV NUM_WORKERS=1
94-
ENV HOST=0.0.0.0
95-
ENV PORT=9001
96-
ENV OPENBLAS_CORETYPE=ARMV8
97-
ENV WORKFLOWS_STEP_EXECUTION_MODE=local
98-
ENV WORKFLOWS_MAX_CONCURRENT_STEPS=2
99-
ENV API_LOGGING_ENABLED=True
100-
ENV RUNS_ON_JETSON=True
101-
ENV ENABLE_PROMETHEUS=True
102-
ENV ENABLE_STREAM_API=True
103-
ENV STREAM_API_PRELOADED_PROCESSES=2
104-
105-
ENV CORE_MODEL_GAZE_ENABLED=False
106-
ENV CORE_MODEL_OWLV2_ENABLED=False
107-
ENV CORE_MODEL_PE_ENABLED=False
108-
ENV CORE_MODEL_SAM_ENABLED=False
109-
ENV CORE_MODEL_SAM2_ENABLED=False
110-
ENV CORE_MODEL_TROCR_ENABLED=False
111-
ENV DEPTH_ESTIMATION_ENABLED=False
112-
ENV FLORENCE2_ENABLED=False
113-
ENV MOONDREAM2_ENABLED=False
114-
ENV PALIGEMMA_ENABLED=False
115-
ENV QWEN_2_5_ENABLED=False
116-
ENV SMOLVLM2_ENABLED=False
88+
ENV VERSION_CHECK_MODE=continuous \
89+
PROJECT=roboflow-platform \
90+
ORT_TENSORRT_FP16_ENABLE=1 \
91+
ORT_TENSORRT_ENGINE_CACHE_ENABLE=1 \
92+
PROJECT=roboflow-platform \
93+
NUM_WORKERS=1 \
94+
HOST=0.0.0.0 \
95+
PORT=9001 \
96+
OPENBLAS_CORETYPE=ARMV8 \
97+
WORKFLOWS_STEP_EXECUTION_MODE=local \
98+
WORKFLOWS_MAX_CONCURRENT_STEPS=2 \
99+
API_LOGGING_ENABLED=True \
100+
RUNS_ON_JETSON=True \
101+
ENABLE_PROMETHEUS=True \
102+
ENABLE_STREAM_API=True \
103+
STREAM_API_PRELOADED_PROCESSES=2 \
104+
CORE_MODEL_GAZE_ENABLED=False \
105+
CORE_MODEL_OWLV2_ENABLED=False \
106+
CORE_MODEL_PE_ENABLED=False \
107+
CORE_MODEL_SAM_ENABLED=False \
108+
CORE_MODEL_SAM2_ENABLED=False \
109+
CORE_MODEL_TROCR_ENABLED=False \
110+
DEPTH_ESTIMATION_ENABLED=False \
111+
FLORENCE2_ENABLED=False \
112+
MOONDREAM2_ENABLED=False \
113+
PALIGEMMA_ENABLED=False \
114+
QWEN_2_5_ENABLED=False \
115+
SMOLVLM2_ENABLED=False \
116+
PYTHONPATH=/app:$PYTHONPATH
117117

118118
ENTRYPOINT uvicorn gpu_http:app --workers $NUM_WORKERS --host $HOST --port $PORT

docker/dockerfiles/Dockerfile.onnx.jetson.5.1.1

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -76,24 +76,25 @@ COPY Makefile Makefile
7676
RUN make create_inference_cli_whl PYTHON=python3.9
7777
RUN python3.9 -m pip install dist/inference_cli*.whl
7878

79-
ENV VERSION_CHECK_MODE=continuous
80-
ENV PROJECT=roboflow-platform
81-
ENV ORT_TENSORRT_FP16_ENABLE=1
82-
ENV ORT_TENSORRT_ENGINE_CACHE_ENABLE=1
83-
ENV CORE_MODEL_SAM_ENABLED=False
84-
ENV PROJECT=roboflow-platform
85-
ENV NUM_WORKERS=1
86-
ENV HOST=0.0.0.0
87-
ENV PORT=9001
88-
ENV OPENBLAS_CORETYPE=ARMV8
89-
ENV LD_PRELOAD=/usr/lib/aarch64-linux-gnu/libgomp.so.1
90-
ENV WORKFLOWS_STEP_EXECUTION_MODE=local
91-
ENV WORKFLOWS_MAX_CONCURRENT_STEPS=2
92-
ENV API_LOGGING_ENABLED=True
93-
ENV CORE_MODEL_TROCR_ENABLED=false
94-
ENV RUNS_ON_JETSON=True
95-
ENV ENABLE_PROMETHEUS=True
96-
ENV ENABLE_STREAM_API=True
97-
ENV STREAM_API_PRELOADED_PROCESSES=2
79+
ENV VERSION_CHECK_MODE=continuous \
80+
PROJECT=roboflow-platform \
81+
ORT_TENSORRT_FP16_ENABLE=1 \
82+
ORT_TENSORRT_ENGINE_CACHE_ENABLE=1 \
83+
CORE_MODEL_SAM_ENABLED=False \
84+
PROJECT=roboflow-platform \
85+
NUM_WORKERS=1 \
86+
HOST=0.0.0.0 \
87+
PORT=9001 \
88+
OPENBLAS_CORETYPE=ARMV8 \
89+
LD_PRELOAD=/usr/lib/aarch64-linux-gnu/libgomp.so.1 \
90+
WORKFLOWS_STEP_EXECUTION_MODE=local \
91+
WORKFLOWS_MAX_CONCURRENT_STEPS=2 \
92+
API_LOGGING_ENABLED=True \
93+
CORE_MODEL_TROCR_ENABLED=false \
94+
RUNS_ON_JETSON=True \
95+
ENABLE_PROMETHEUS=True \
96+
ENABLE_STREAM_API=True \
97+
STREAM_API_PRELOADED_PROCESSES=2 \
98+
PYTHONPATH=/app:$PYTHONPATH
9899

99100
ENTRYPOINT uvicorn gpu_http:app --workers $NUM_WORKERS --host $HOST --port $PORT

docker/dockerfiles/Dockerfile.onnx.jetson.5.1.1.stream_manager

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -65,17 +65,18 @@ COPY Makefile Makefile
6565
RUN make create_inference_cli_whl PYTHON=python3.9
6666
RUN python3.9 -m pip install dist/inference_cli*.whl
6767

68-
ENV ORT_TENSORRT_FP16_ENABLE=1
69-
ENV ORT_TENSORRT_ENGINE_CACHE_ENABLE=1
70-
ENV CORE_MODEL_SAM_ENABLED=False
71-
ENV OPENBLAS_CORETYPE=ARMV8
72-
ENV LD_PRELOAD=/usr/lib/aarch64-linux-gnu/libgomp.so.1:/usr/local/lib/python3.8/dist-packages/torch.libs/libgomp-d22c30c5.so.1.0.0
73-
ENV VERSION_CHECK_MODE=continuous
74-
ENV PROJECT=roboflow-platform
75-
ENV HOST=0.0.0.0
76-
ENV PORT=7070
77-
ENV WORKFLOWS_STEP_EXECUTION_MODE=local
78-
ENV WORKFLOWS_MAX_CONCURRENT_STEPS=1
79-
ENV SUPERVISON_DEPRECATION_WARNING=0
68+
ENV ORT_TENSORRT_FP16_ENABLE=1 \
69+
ORT_TENSORRT_ENGINE_CACHE_ENABLE=1 \
70+
CORE_MODEL_SAM_ENABLED=False \
71+
OPENBLAS_CORETYPE=ARMV8 \
72+
LD_PRELOAD=/usr/lib/aarch64-linux-gnu/libgomp.so.1:/usr/local/lib/python3.8/dist-packages/torch.libs/libgomp-d22c30c5.so.1.0.0 \
73+
VERSION_CHECK_MODE=continuous \
74+
PROJECT=roboflow-platform \
75+
HOST=0.0.0.0 \
76+
PORT=7070 \
77+
WORKFLOWS_STEP_EXECUTION_MODE=local \
78+
WORKFLOWS_MAX_CONCURRENT_STEPS=1 \
79+
SUPERVISON_DEPRECATION_WARNING=0 \
80+
PYTHONPATH=/app:$PYTHONPATH
8081

8182
ENTRYPOINT ["python3.9", "-m", "inference.enterprise.stream_management.manager.app"]

docker/dockerfiles/Dockerfile.onnx.jetson.6.0.0

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,8 @@ ENV VERSION_CHECK_MODE=continuous \
7373
RUNS_ON_JETSON=True \
7474
ENABLE_PROMETHEUS=True \
7575
ENABLE_STREAM_API=True \
76-
STREAM_API_PRELOADED_PROCESSES=2
76+
STREAM_API_PRELOADED_PROCESSES=2 \
77+
PYTHONPATH=/app:$PYTHONPATH
7778

7879
# Expose the application port
7980
EXPOSE 9001

docker/dockerfiles/Dockerfile.onnx.jetson.6.2.0

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,8 @@ ENV VERSION_CHECK_MODE=continuous \
7878
RUNS_ON_JETSON=True \
7979
ENABLE_PROMETHEUS=True \
8080
ENABLE_STREAM_API=True \
81-
STREAM_API_PRELOADED_PROCESSES=2
81+
STREAM_API_PRELOADED_PROCESSES=2 \
82+
PYTHONPATH=/app:$PYTHONPATH
8283

8384
# Expose the application port
8485
EXPOSE 9001

inference/core/constants.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@
22
OBJECT_DETECTION_TASK = "object-detection"
33
INSTANCE_SEGMENTATION_TASK = "instance-segmentation"
44
KEYPOINTS_DETECTION_TASK = "keypoint-detection"
5+
PROCESSING_TIME_HEADER = "X-Processing-Time"

inference/core/interfaces/camera/video_source.py

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -550,21 +550,12 @@ def read_frame(self, timeout: Optional[float] = None) -> Optional[VideoFrame]:
550550
self._fps = source_metadata.source_properties.fps
551551
if not self._fps or self._fps <= 0 or self._fps > 1000:
552552
self._fps = 30 # sane default
553-
if not self._is_file:
554-
current_timestamp = time.time_ns()
555-
if (current_timestamp - self._last_frame_timestamp) / 1e9 < 1 / self._fps:
556-
time.sleep(
557-
(1 / self._fps)
558-
- (current_timestamp - self._last_frame_timestamp) / 1e9
559-
)
560553
video_frame: Optional[Union[VideoFrame, str]] = get_from_queue(
561554
queue=self._frames_buffer,
562555
on_successful_read=self._video_consumer.notify_frame_consumed,
563556
timeout=timeout,
564557
purge=self._buffer_consumption_strategy is BufferConsumptionStrategy.EAGER,
565558
)
566-
if not self._is_file:
567-
self._last_frame_timestamp = time.time_ns()
568559
if video_frame == POISON_PILL:
569560
raise EndOfStreamError(
570561
"Attempted to retrieve frame from stream that already ended."
@@ -926,7 +917,7 @@ def _set_file_mode_buffering_strategies(self) -> None:
926917

927918
def _set_stream_mode_buffering_strategies(self) -> None:
928919
if self._buffer_filling_strategy is None:
929-
self._buffer_filling_strategy = BufferFillingStrategy.DROP_OLDEST
920+
self._buffer_filling_strategy = BufferFillingStrategy.ADAPTIVE_DROP_OLDEST
930921

931922
def _video_fps_should_be_sub_sampled(self) -> bool:
932923
if self._desired_fps is None:

inference/core/interfaces/http/http_api.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
from starlette.middleware.base import BaseHTTPMiddleware
1616

1717
from inference.core import logger
18+
from inference.core.constants import PROCESSING_TIME_HEADER
1819
from inference.core.devices.utils import GLOBAL_INFERENCE_SERVER_ID
1920
from inference.core.entities.requests.clip import (
2021
ClipCompareRequest,
@@ -536,7 +537,7 @@ async def dispatch(self, request, call_next):
536537
t1 = time.time()
537538
response = await call_next(request)
538539
t2 = time.time()
539-
response.headers["X-Processing-Time"] = str(t2 - t1)
540+
response.headers[PROCESSING_TIME_HEADER] = str(t2 - t1)
540541
return response
541542

542543

@@ -625,6 +626,7 @@ async def on_shutdown():
625626
allow_credentials=True,
626627
allow_methods=["*"],
627628
allow_headers=["*"],
629+
expose_headers=[PROCESSING_TIME_HEADER],
628630
)
629631

630632
# Optionally add middleware for profiling the FastAPI server and underlying inference API code

inference/core/interfaces/stream_manager/manager_app/inference_pipeline_manager.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -280,8 +280,6 @@ def start_loop(loop: asyncio.AbstractEventLoop):
280280
from_inference_queue=from_inference_queue,
281281
asyncio_loop=loop,
282282
webcam_fps=webcam_fps,
283-
max_consecutive_timeouts=parsed_payload.max_consecutive_timeouts,
284-
min_consecutive_on_time=parsed_payload.min_consecutive_on_time,
285283
processing_timeout=parsed_payload.processing_timeout,
286284
fps_probe_frames=parsed_payload.fps_probe_frames,
287285
data_output=data_output,

inference/core/interfaces/stream_manager/manager_app/webrtc.py

Lines changed: 23 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import asyncio
22
import concurrent.futures
3+
import datetime
34
import json
45
import time
56
from typing import Any, Dict, List, Optional, Tuple, Union
@@ -62,10 +63,27 @@ def get_frame_from_workflow_output(
6263
) -> Optional[np.ndarray]:
6364
step_output = workflow_output.get(frame_output_key)
6465
if isinstance(step_output, WorkflowImageData):
66+
if (
67+
step_output.video_metadata
68+
and step_output.video_metadata.frame_timestamp is not None
69+
):
70+
latency = (
71+
datetime.datetime.now() - step_output.video_metadata.frame_timestamp
72+
)
73+
logger.info("Processing latency: %ss", latency.total_seconds())
6574
return step_output.numpy_image
6675
elif isinstance(step_output, dict):
6776
for frame_output in step_output.values():
6877
if isinstance(frame_output, WorkflowImageData):
78+
if (
79+
frame_output.video_metadata
80+
and frame_output.video_metadata.frame_timestamp is not None
81+
):
82+
latency = (
83+
datetime.datetime.now()
84+
- frame_output.video_metadata.frame_timestamp
85+
)
86+
logger.info("Processing latency: %ss", latency.total_seconds())
6987
return frame_output.numpy_image
7088

7189

@@ -77,8 +95,6 @@ def __init__(
7795
asyncio_loop: asyncio.AbstractEventLoop,
7896
processing_timeout: float,
7997
fps_probe_frames: int,
80-
min_consecutive_on_time: int,
81-
max_consecutive_timeouts: Optional[int] = None,
8298
webcam_fps: Optional[float] = None,
8399
*args,
84100
**kwargs,
@@ -104,10 +120,6 @@ def __init__(
104120
self.incoming_stream_fps: Optional[float] = webcam_fps
105121

106122
self._last_frame: Optional[VideoFrame] = None
107-
self._consecutive_timeouts: int = 0
108-
self._consecutive_on_time: int = 0
109-
self._max_consecutive_timeouts: Optional[int] = max_consecutive_timeouts
110-
self._min_consecutive_on_time: int = min_consecutive_on_time
111123

112124
self._av_logging_set: bool = False
113125

@@ -146,7 +158,7 @@ async def recv(self):
146158

147159
if not await self.to_inference_queue.async_full():
148160
await self.to_inference_queue.async_put(frame)
149-
elif not self._last_frame:
161+
else:
150162
await self.to_inference_queue.async_get_nowait()
151163
await self.to_inference_queue.async_put_nowait(frame)
152164

@@ -157,55 +169,22 @@ async def recv(self):
157169
)
158170
new_frame = VideoFrame.from_ndarray(np_frame, format="bgr24")
159171
self._last_frame = new_frame
160-
161-
if self._max_consecutive_timeouts:
162-
self._consecutive_on_time += 1
163-
if self._consecutive_on_time >= self._min_consecutive_on_time:
164-
self._consecutive_timeouts = 0
165172
except asyncio.TimeoutError:
166-
while not await self.to_inference_queue.async_empty():
167-
await self.to_inference_queue.async_get_nowait()
168-
if self._last_frame:
169-
if self._max_consecutive_timeouts:
170-
self._consecutive_timeouts += 1
171-
if self._consecutive_timeouts >= self._max_consecutive_timeouts:
172-
self._consecutive_on_time = 0
173-
174-
workflow_too_slow_message = [
175-
"Workflow is too heavy to process all frames on time..."
176-
]
173+
pass
174+
177175
if np_frame is None:
178176
if not self._last_frame:
179177
np_frame = overlay_text_on_np_frame(
180178
frame.to_ndarray(format="bgr24"),
181179
["Inference pipeline is starting..."],
182180
)
183181
new_frame = VideoFrame.from_ndarray(np_frame, format="bgr24")
184-
elif (
185-
self._max_consecutive_timeouts
186-
and self._consecutive_timeouts >= self._max_consecutive_timeouts
187-
):
188-
np_frame = overlay_text_on_np_frame(
189-
self._last_frame.to_ndarray(format="bgr24"),
190-
workflow_too_slow_message,
191-
)
192-
new_frame = VideoFrame.from_ndarray(np_frame, format="bgr24")
193182
else:
194183
new_frame = self._last_frame
195184
else:
196-
if (
197-
self._max_consecutive_timeouts
198-
and self._consecutive_timeouts >= self._max_consecutive_timeouts
199-
):
200-
np_frame = overlay_text_on_np_frame(
201-
self._last_frame.to_ndarray(format="bgr24"),
202-
workflow_too_slow_message,
203-
)
204-
new_frame = VideoFrame.from_ndarray(np_frame, format="bgr24")
205-
else:
206-
new_frame = VideoFrame.from_ndarray(np_frame, format="bgr24")
185+
new_frame = VideoFrame.from_ndarray(np_frame, format="bgr24")
207186

208-
new_frame.pts = self._processed
187+
new_frame.pts = frame.pts
209188
new_frame.time_base = frame.time_base
210189

211190
return new_frame
@@ -312,8 +291,6 @@ async def init_rtc_peer_connection(
312291
asyncio_loop: asyncio.AbstractEventLoop,
313292
processing_timeout: float,
314293
fps_probe_frames: int,
315-
max_consecutive_timeouts: int,
316-
min_consecutive_on_time: int,
317294
webrtc_turn_config: Optional[WebRTCTURNConfig] = None,
318295
webcam_fps: Optional[float] = None,
319296
stream_output: Optional[str] = None,
@@ -326,8 +303,6 @@ async def init_rtc_peer_connection(
326303
webcam_fps=webcam_fps,
327304
processing_timeout=processing_timeout,
328305
fps_probe_frames=fps_probe_frames,
329-
max_consecutive_timeouts=max_consecutive_timeouts,
330-
min_consecutive_on_time=min_consecutive_on_time,
331306
)
332307

333308
if webrtc_turn_config:

0 commit comments

Comments
 (0)