diff --git a/machine-learning/immich_ml/models/transforms.py b/machine-learning/immich_ml/models/transforms.py index 7d473a90a..debaf03c6 100644 --- a/machine-learning/immich_ml/models/transforms.py +++ b/machine-learning/immich_ml/models/transforms.py @@ -74,8 +74,8 @@ def serialize_np_array(arr: NDArray[np.float32]) -> str: def widen(array: NDArray[Any]) -> NDArray[Any]: """Single precision from half through OpenCV, as numpy converts one value at a time without native half support.""" - if array.dtype != np.float16: - return array + if array.dtype != np.float16 or array.size == 0: + return array.astype(np.float32, copy=False) return cv2.convertFp16(array.reshape(-1, array.shape[-1]).view(np.int16)).reshape(array.shape) # int16 carries half diff --git a/machine-learning/test_main.py b/machine-learning/test_main.py index b0e31ec3c..50319d530 100644 --- a/machine-learning/test_main.py +++ b/machine-learning/test_main.py @@ -1801,6 +1801,15 @@ class TestOcr: assert indices.tolist() == [[2, 1, 1, 0]] assert np.allclose(confidence, [[1 / (1 + 2 * np.exp(-10)), 1 / (1 + np.exp(-1) + np.exp(-2)), 0, 0]]) + def test_rec_decodes_half_precision_logits_that_are_all_blank(self) -> None: + raw = np.full((2, 3, 1, 3), -5.0, dtype=np.float16) + raw[..., 0] = 5.0 # every step reads as the blank, so no character is kept + + indices, confidence = logits(raw) + + assert indices.tolist() == [[0, 0, 0], [0, 0, 0]] + assert confidence.dtype == np.float32 and not confidence.any() + def test_set_rec_set_default_max_batch_size( self, ort_session: mock.Mock, path: mock.Mock, mocker: MockerFixture ) -> None: