Skip to content

Commit b918933

Browse files
Merge pull request #30 from OlafenwaMoses/main
release - hardware acceleration bottlenecks fixes
2 parents 7506707 + 0cb1f53 commit b918933

9 files changed

Lines changed: 88 additions & 16 deletions

File tree

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ dependencies = [
3737
"transformers>=5.6.2",
3838
"pillow>=12.2.0",
3939
"open3d>=0.18.0",
40+
"orjson>=3.9.0",
4041
]
4142

4243
# ---------------------------------------------------------------------------

tests/unit/test_coordinate_space.py

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -39,16 +39,16 @@
3939

4040
W, H = 20, 16
4141
FX = FY = 200.0
42-
CX, CY = 9.5, 7.5 # exact centre of 20 × 16
42+
CX, CY = 9.5, 7.5 # exact centre of 20 × 16
4343

4444
_STEREO_CFG = StereoDepthAdvancedConfig(
4545
focal_length=FX,
4646
cx=CX,
4747
cy=CY,
48-
baseline=100.0, # 100 mm
48+
baseline=100.0, # 100 mm
4949
doffs=0.0,
5050
z_far=1000.0,
51-
conf_threshold=0.0, # accept all pixels
51+
conf_threshold=0.0, # accept all pixels
5252
occ_threshold=0.0,
5353
)
5454

@@ -95,9 +95,7 @@ def _run_depth(depth: np.ndarray, cfg: DepthEstimationAdvanceConfig = _DEPTH_CFG
9595
"""Run DepthEstimation with a mocked depth array and return the result."""
9696
h, w = depth.shape
9797
img = _image_bytes(w, h)
98-
with patch.object(
99-
DepthEstimationHandler, "_run_depth_anything_checkpoint", return_value=depth
100-
):
98+
with patch.object(DepthEstimationHandler, "_run_depth_anything_checkpoint", return_value=depth):
10199
return DepthEstimation().run(
102100
DepthEstimationCommand(
103101
image_input=img,
@@ -302,8 +300,8 @@ class TestDepthOrdering:
302300
"""Closer objects (larger disparity) must appear at smaller Z."""
303301

304302
def test_stereo_larger_disparity_means_smaller_z(self):
305-
disp_near = np.full((H, W), 50.0, dtype=np.float32) # closer
306-
disp_far = np.full((H, W), 10.0, dtype=np.float32) # further
303+
disp_near = np.full((H, W), 50.0, dtype=np.float32) # closer
304+
disp_far = np.full((H, W), 10.0, dtype=np.float32) # further
307305
pts_near = np.asarray(_run_stereo(disp_near).point_cloud.points)
308306
pts_far = np.asarray(_run_stereo(disp_far).point_cloud.points)
309307
assert pts_near[:, 2].mean() < pts_far[:, 2].mean(), (

tests/unit/test_stereo_depth_handler.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -213,8 +213,8 @@ def test_depth_image_closer_is_brighter(self, dummy_image_bytes, fake_disp):
213213
# Use a disparity field where the top-left quadrant has much higher
214214
# disparity (closer) so we can verify the inversion.
215215
near_far = fake_disp.copy()
216-
near_far[:24, :32] = 200.0 # very close (high disparity)
217-
near_far[24:, 32:] = 1.0 # very far (low disparity)
216+
near_far[:24, :32] = 200.0 # very close (high disparity)
217+
near_far[24:, 32:] = 1.0 # very far (low disparity)
218218
with patch.object(StereoDepthHandler, "_run_s2m2", return_value=near_far):
219219
result = StereoDepthHandler().handle(
220220
StereoDepthCommand(
@@ -272,7 +272,7 @@ def test_raw_depth_values_are_metric_metres(self, dummy_image_bytes):
272272
advanced_config=cfg,
273273
)
274274
)
275-
expected = (100.0 * 1000.0) / (10.0 * 1000.0) # = 10.0 m
275+
expected = (100.0 * 1000.0) / (10.0 * 1000.0) # = 10.0 m
276276
np.testing.assert_allclose(result.raw_depth, expected, rtol=1e-5)
277277

278278
def test_return_point_cloud_requires_open3d(self, dummy_image_bytes, fake_disp):

uv.lock

Lines changed: 55 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vizion3d/lifting/handlers.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
_DEFAULT_DEPTH_SCALE = 1000.0
1818
_DEFAULT_DEPTH_TRUNC = 10.0
1919

20+
2021
class DepthEstimationHandler(CommandHandler[DepthEstimationCommand, DepthEstimationResult]):
2122
_depth_anything_models = {}
2223
_model_lock = threading.Lock()
@@ -156,6 +157,12 @@ def _load_depth_anything_checkpoint(self, model_path: str):
156157
model.load_state_dict(state_dict)
157158
device = self._torch_device(torch)
158159
model = model.to(device).eval()
160+
161+
if device == "cuda":
162+
torch.backends.cudnn.benchmark = True
163+
torch.backends.cuda.matmul.allow_tf32 = True
164+
torch.backends.cudnn.allow_tf32 = True
165+
159166
processor = DPTImageProcessor(
160167
size={"height": 518, "width": 518},
161168
do_resize=True,

vizion3d/server/rest/depth_estimation.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@
66
``app.include_router(lifting_router)``.
77
"""
88

9+
import orjson
910
from fastapi import APIRouter, File, Form, UploadFile
11+
from fastapi.responses import Response
1012

1113
from vizion3d.lifting import DepthEstimation, DepthEstimationCommand
1214
from vizion3d.lifting.defaults import DEFAULT_DEPTH_MODEL_URL
@@ -85,7 +87,7 @@ async def depth_estimation(
8587
advanced_config=advanced_config,
8688
)
8789
result = DepthEstimation().run(cmd)
88-
return {
90+
payload = {
8991
"depth_map": result.depth_map,
9092
"min_depth": result.min_depth,
9193
"max_depth": result.max_depth,
@@ -101,3 +103,4 @@ async def depth_estimation(
101103
else None
102104
),
103105
}
106+
return Response(content=orjson.dumps(payload), media_type="application/json")

vizion3d/server/rest/serialisation.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ def o3d_depth_image_to_png_bytes(o3d_image) -> bytes:
1818
"""Encode an Open3D uint16 depth image as a PNG byte string."""
1919
arr = np.asarray(o3d_image)
2020
buf = io.BytesIO()
21-
Image.fromarray(arr).save(buf, format="PNG")
21+
Image.fromarray(arr).save(buf, format="PNG", compress_level=1)
2222
return buf.getvalue()
2323

2424

vizion3d/server/rest/stereo_depth.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@
66
``app.include_router(router)``.
77
"""
88

9+
import orjson
910
from fastapi import APIRouter, File, Form, UploadFile
11+
from fastapi.responses import Response
1012

1113
from vizion3d.stereo import StereoDepth, StereoDepthCommand
1214
from vizion3d.stereo.defaults import DEFAULT_STEREO_MODEL_URL
@@ -101,7 +103,7 @@ async def stereo_depth(
101103
advanced_config=advanced_config,
102104
)
103105
result = StereoDepth().run(cmd)
104-
return {
106+
payload = {
105107
"depth_map": result.depth_map,
106108
"disparity_map": result.disparity_map,
107109
"min_depth": result.min_depth,
@@ -118,3 +120,4 @@ async def stereo_depth(
118120
else None
119121
),
120122
}
123+
return Response(content=orjson.dumps(payload), media_type="application/json")

vizion3d/stereo/handlers.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,11 @@ def _load_s2m2(self, model_path: str):
167167
model.my_load_state_dict(state_dict)
168168
model = model.to(device).eval()
169169

170+
if device == "cuda":
171+
torch.backends.cudnn.benchmark = True
172+
torch.backends.cuda.matmul.allow_tf32 = True
173+
torch.backends.cudnn.allow_tf32 = True
174+
170175
self._stereo_models[model_path] = (model, torch, device)
171176
return self._stereo_models[model_path]
172177

@@ -222,8 +227,8 @@ def _run_s2m2(
222227
left_t_inp = left_t
223228
right_t_inp = right_t
224229

225-
left_pad = image_pad(left_t_inp, 32).to(device)
226-
right_pad = image_pad(right_t_inp, 32).to(device)
230+
left_pad = image_pad(left_t_inp, 32).to(device, non_blocking=True)
231+
right_pad = image_pad(right_t_inp, 32).to(device, non_blocking=True)
227232

228233
device_type = device if isinstance(device, str) else device.type
229234
if device_type == "cuda":

0 commit comments

Comments
 (0)