diff --git a/.conda/meta.yaml b/.conda/meta.yaml index 90147fd544..5eb28efa9c 100644 --- a/.conda/meta.yaml +++ b/.conda/meta.yaml @@ -16,7 +16,7 @@ build: requirements: host: - - python>=3.8, <3.12 + - python>=3.9, <3.12 - setuptools run: diff --git a/.github/workflows/builds.yml b/.github/workflows/builds.yml index e74b9bb698..03f8952287 100644 --- a/.github/workflows/builds.yml +++ b/.github/workflows/builds.yml @@ -13,7 +13,7 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest, macos-latest] - python: ["3.8", "3.9"] + python: ["3.9", "3.10"] framework: [tensorflow, pytorch] steps: - uses: actions/checkout@v4 @@ -57,7 +57,7 @@ jobs: - uses: conda-incubator/setup-miniconda@v3 with: auto-update-conda: true - python-version: 3.8 + python-version: 3.9 channels: pypdfium2-team,bblanchon,defaults,conda-forge channel-priority: strict - name: Install dependencies diff --git a/.github/workflows/demo.yml b/.github/workflows/demo.yml index 8b3f768d2b..a3b8a3c204 100644 --- a/.github/workflows/demo.yml +++ b/.github/workflows/demo.yml @@ -13,7 +13,7 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest] - python: ["3.8"] + python: ["3.9"] framework: [tensorflow, pytorch] steps: - if: matrix.os == 'macos-latest' diff --git a/.github/workflows/doc-status.yml b/.github/workflows/doc-status.yml index 4f8049d866..ca6d84c476 100644 --- a/.github/workflows/doc-status.yml +++ b/.github/workflows/doc-status.yml @@ -6,10 +6,10 @@ jobs: see-page-build-payload: runs-on: ubuntu-latest steps: - - name: Set up Python 3.8 + - name: Set up Python uses: actions/setup-python@v4 with: - python-version: "3.8" + python-version: "3.9" architecture: x64 - name: check status run: | diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index bde4703829..f19c87e358 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -12,16 +12,16 @@ jobs: steps: - uses: actions/checkout@v4 - name: Build docker image - run: docker build -t doctr-tf-py3.8-slim --build-arg SYSTEM=cpu . + run: docker build -t doctr-tf-py3.9-slim --build-arg SYSTEM=cpu . - name: Run docker container - run: docker run doctr-tf-py3.8-slim python3 -c 'import doctr' + run: docker run doctr-tf-py3.9-slim python3 -c 'import doctr' pytest-api: runs-on: ${{ matrix.os }} strategy: matrix: os: [ubuntu-latest] - python: ["3.8"] + python: ["3.9"] steps: - uses: actions/checkout@v4 - uses: actions/setup-python@v4 diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index ff8e87e71d..9ac34784a7 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -9,7 +9,7 @@ jobs: strategy: matrix: os: [ubuntu-latest] - python: ["3.8"] + python: ["3.9"] steps: - uses: actions/checkout@v4 with: diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 3be297ed66..b8e682cb76 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -12,7 +12,7 @@ jobs: strategy: matrix: os: [ubuntu-latest] - python: ["3.8"] + python: ["3.9"] steps: - uses: actions/checkout@v4 - name: Set up Python @@ -45,7 +45,7 @@ jobs: strategy: matrix: os: [ubuntu-latest] - python: ["3.8"] + python: ["3.9"] steps: - uses: actions/checkout@v4 - name: Set up Python @@ -78,7 +78,7 @@ jobs: strategy: matrix: os: [ubuntu-latest] - python: ["3.8"] + python: ["3.9"] steps: - uses: actions/checkout@v4 - name: Set up Python diff --git a/.github/workflows/public_docker_images.yml b/.github/workflows/public_docker_images.yml index de77d1a265..61a974e8fa 100644 --- a/.github/workflows/public_docker_images.yml +++ b/.github/workflows/public_docker_images.yml @@ -22,7 +22,7 @@ jobs: fail-fast: false matrix: # Must match version at https://www.python.org/ftp/python/ - python: ["3.8.18", "3.9.18", "3.10.13"] + python: ["3.9.18", "3.10.13", "3.11.8"] framework: ["tf", "torch"] system: ["cpu", "gpu"] diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index efc024fd21..e658e29966 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -11,7 +11,7 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest] - python: ["3.8"] + python: ["3.9"] runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v4 @@ -50,11 +50,11 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest] - python: ["3.8"] + python: ["3.9"] runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v4 - - name: Set up Python 3.8 + - name: Set up Python uses: actions/setup-python@v4 with: python-version: ${{ matrix.python }} @@ -73,7 +73,7 @@ jobs: - uses: conda-incubator/setup-miniconda@v3 with: auto-update-conda: true - python-version: 3.8 + python-version: 3.9 channels: pypdfium2-team,bblanchon,defaults,conda-forge channel-priority: strict - name: Install dependencies @@ -103,7 +103,7 @@ jobs: - uses: conda-incubator/setup-miniconda@v3 with: auto-update-conda: true - python-version: 3.8 + python-version: 3.9 - name: Install package shell: bash -el {0} run: | diff --git a/.github/workflows/pull_requests.yml b/.github/workflows/pull_requests.yml index 74656f831f..cfae7adf3b 100644 --- a/.github/workflows/pull_requests.yml +++ b/.github/workflows/pull_requests.yml @@ -9,10 +9,10 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - name: Set up Python 3.8 + - name: Set up Python uses: actions/setup-python@v4 with: - python-version: "3.8" + python-version: "3.9" architecture: x64 - name: Cache python modules uses: actions/cache@v3 diff --git a/.github/workflows/references.yml b/.github/workflows/references.yml index a6ad687a67..9e7cef1544 100644 --- a/.github/workflows/references.yml +++ b/.github/workflows/references.yml @@ -13,7 +13,7 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest] - python: ["3.8"] + python: ["3.9"] framework: [tensorflow, pytorch] steps: - uses: actions/checkout@v4 @@ -65,7 +65,7 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest] - python: ["3.8"] + python: ["3.9"] framework: [tensorflow, pytorch] steps: - uses: actions/checkout@v4 @@ -131,7 +131,7 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest] - python: ["3.8"] + python: ["3.9"] framework: [tensorflow, pytorch] steps: - uses: actions/checkout@v4 @@ -186,7 +186,7 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest] - python: ["3.8"] + python: ["3.9"] framework: [tensorflow, pytorch] steps: - uses: actions/checkout@v4 @@ -230,7 +230,7 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest] - python: ["3.8"] + python: ["3.9"] framework: [tensorflow, pytorch] steps: - uses: actions/checkout@v4 @@ -263,7 +263,7 @@ jobs: pip install -e .[torch] --upgrade - if: matrix.framework == 'tensorflow' name: Benchmark latency (TF) - run: python references/recognition/latency_tensorflow.py crnn_vgg16_bn --it 5 + run: python references/recognition/latency_tensorflow.py crnn_mobilenet_v3_small --it 5 - if: matrix.framework == 'pytorch' name: Benchmark latency (PT) run: python references/recognition/latency_pytorch.py crnn_mobilenet_v3_small --it 5 @@ -274,7 +274,7 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest] - python: ["3.8"] + python: ["3.9"] framework: [tensorflow, pytorch] steps: - uses: actions/checkout@v4 @@ -318,7 +318,7 @@ jobs: unzip toy_detection_set-bbbb4243.zip -d det_set - if: matrix.framework == 'tensorflow' name: Train for a short epoch (TF) - run: python references/detection/train_tensorflow.py --train_path ./det_set --val_path ./det_set db_resnet50 -b 2 --epochs 1 + run: python references/detection/train_tensorflow.py --train_path ./det_set --val_path ./det_set linknet_resnet18 -b 2 --epochs 1 - if: matrix.framework == 'pytorch' name: Train for a short epoch (PT) run: python references/detection/train_pytorch.py ./det_set ./det_set db_mobilenet_v3_large -b 2 --epochs 1 @@ -329,7 +329,7 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest] - python: ["3.8"] + python: ["3.9"] framework: [tensorflow, pytorch] steps: - uses: actions/checkout@v4 @@ -375,7 +375,7 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest] - python: ["3.8"] + python: ["3.9"] framework: [tensorflow, pytorch] steps: - uses: actions/checkout@v4 @@ -408,10 +408,10 @@ jobs: pip install -e .[torch] --upgrade - if: matrix.framework == 'tensorflow' name: Benchmark latency (TF) - run: python references/detection/latency_tensorflow.py linknet_resnet18 --it 5 --size 512 + run: python references/detection/latency_tensorflow.py db_mobilenet_v3_large --it 5 --size 512 - if: matrix.framework == 'pytorch' name: Benchmark latency (PT) - run: python references/detection/latency_pytorch.py linknet_resnet18 --it 5 --size 512 + run: python references/detection/latency_pytorch.py db_mobilenet_v3_large --it 5 --size 512 latency-object-detection: runs-on: ${{ matrix.os }} @@ -419,7 +419,7 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest] - python: ["3.8"] + python: ["3.9"] framework: [pytorch] steps: - uses: actions/checkout@v4 diff --git a/.github/workflows/scripts.yml b/.github/workflows/scripts.yml index 97d01ef6ac..60c126243b 100644 --- a/.github/workflows/scripts.yml +++ b/.github/workflows/scripts.yml @@ -13,7 +13,7 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest] - python: ["3.8", "3.9"] + python: ["3.9", "3.10"] framework: [tensorflow, pytorch] steps: - if: matrix.os == 'macos-latest' @@ -51,7 +51,7 @@ jobs: - name: Run analysis script run: | wget https://github.com/mindee/doctr/releases/download/v0.1.0/sample.pdf - python scripts/analyze.py sample.pdf --noblock + python scripts/analyze.py sample.pdf --noblock --detection db_mobilenet_v3_large test-detect-text: runs-on: ${{ matrix.os }} @@ -59,7 +59,7 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest] - python: ["3.8", "3.9"] + python: ["3.9", "3.10"] framework: [tensorflow, pytorch] steps: - if: matrix.os == 'macos-latest' @@ -97,7 +97,7 @@ jobs: - name: Run detection script run: | wget https://github.com/mindee/doctr/releases/download/v0.1.0/sample.pdf - python scripts/detect_text.py sample.pdf + python scripts/detect_text.py sample.pdf --detection db_mobilenet_v3_large test-evaluate: runs-on: ${{ matrix.os }} @@ -105,7 +105,7 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest] - python: ["3.8", "3.9"] + python: ["3.9", "3.10"] framework: [tensorflow, pytorch] steps: - if: matrix.os == 'macos-latest' @@ -150,7 +150,7 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest, macos-latest, windows-latest] - python: ["3.8", "3.9"] + python: ["3.9", "3.10"] steps: - uses: actions/checkout@v4 - name: Set up Python diff --git a/.github/workflows/style.yml b/.github/workflows/style.yml index 49885ace7c..aa866272b9 100644 --- a/.github/workflows/style.yml +++ b/.github/workflows/style.yml @@ -12,7 +12,7 @@ jobs: strategy: matrix: os: [ubuntu-latest] - python: ["3.8"] + python: ["3.9"] steps: - uses: actions/checkout@v4 - name: Set up Python @@ -31,7 +31,7 @@ jobs: strategy: matrix: os: [ubuntu-latest] - python: ["3.8"] + python: ["3.9"] steps: - uses: actions/checkout@v4 - name: Set up Python diff --git a/README.md b/README.md index 353e18a6e7..82cc3c2480 100644 --- a/README.md +++ b/README.md @@ -134,7 +134,7 @@ The KIE predictor results per page are in a dictionary format with each key repr ### Prerequisites -Python 3.8 (or higher) and [pip](https://pip.pypa.io/en/stable/) are required to install docTR. +Python 3.9 (or higher) and [pip](https://pip.pypa.io/en/stable/) are required to install docTR. Since we use [weasyprint](https://weasyprint.org/), you will need extra dependencies if you are not running Linux. diff --git a/api/pyproject.toml b/api/pyproject.toml index a101c4a436..cb76a5c648 100644 --- a/api/pyproject.toml +++ b/api/pyproject.toml @@ -10,7 +10,7 @@ authors = ["Mindee "] license = "Apache-2.0" [tool.poetry.dependencies] -python = ">=3.8.2,<3.11" # pypdfium2 needs a python version above 3.8.2 +python = ">=3.9,<3.12" tensorflow = ">=2.11.0,<2.16.0" # cf. https://github.com/mindee/doctr/pull/1461 python-doctr = {git = "https://github.com/mindee/doctr.git", extras = ['tf'], branch = "main" } # Fastapi: minimum version required to avoid pydantic error diff --git a/docs/source/getting_started/installing.rst b/docs/source/getting_started/installing.rst index 438910174c..d746ebc0b4 100644 --- a/docs/source/getting_started/installing.rst +++ b/docs/source/getting_started/installing.rst @@ -3,7 +3,7 @@ Installation ************ -This library requires `Python `_ 3.8 or higher. +This library requires `Python `_ 3.9 or higher. Prerequisites diff --git a/doctr/datasets/datasets/pytorch.py b/doctr/datasets/datasets/pytorch.py index 4a57662a36..bd4d840168 100644 --- a/doctr/datasets/datasets/pytorch.py +++ b/doctr/datasets/datasets/pytorch.py @@ -50,9 +50,9 @@ def _read_sample(self, index: int) -> Tuple[torch.Tensor, Any]: @staticmethod def collate_fn(samples: List[Tuple[torch.Tensor, Any]]) -> Tuple[torch.Tensor, List[Any]]: images, targets = zip(*samples) - images = torch.stack(images, dim=0) + images = torch.stack(images, dim=0) # type: ignore[assignment] - return images, list(targets) + return images, list(targets) # type: ignore[return-value] class VisionDataset(AbstractDataset, _VisionDataset): # noqa: D101 diff --git a/doctr/io/image/pytorch.py b/doctr/io/image/pytorch.py index 347e40a5b3..26e3e76f95 100644 --- a/doctr/io/image/pytorch.py +++ b/doctr/io/image/pytorch.py @@ -106,4 +106,4 @@ def tensor_from_numpy(npy_img: np.ndarray, dtype: torch.dtype = torch.float32) - def get_img_shape(img: torch.Tensor) -> Tuple[int, int]: """Get the shape of an image""" - return img.shape[-2:] + return img.shape[-2:] # type: ignore[return-value] diff --git a/doctr/models/detection/differentiable_binarization/pytorch.py b/doctr/models/detection/differentiable_binarization/pytorch.py index 9e4b81ef92..7f7bdd8efe 100644 --- a/doctr/models/detection/differentiable_binarization/pytorch.py +++ b/doctr/models/detection/differentiable_binarization/pytorch.py @@ -273,7 +273,7 @@ def compute_loss( dice_map = torch.softmax(out_map, dim=1) else: # compute binary map instead - dice_map = 1 / (1 + torch.exp(-50.0 * (prob_map - thresh_map))) # type: ignore[assignment] + dice_map = 1 / (1 + torch.exp(-50.0 * (prob_map - thresh_map))) # Class reduced inter = (seg_mask * dice_map * seg_target).sum((0, 2, 3)) cardinality = (seg_mask * (dice_map + seg_target)).sum((0, 2, 3)) diff --git a/doctr/models/kie_predictor/pytorch.py b/doctr/models/kie_predictor/pytorch.py index 81f342931d..06236d82dc 100644 --- a/doctr/models/kie_predictor/pytorch.py +++ b/doctr/models/kie_predictor/pytorch.py @@ -95,7 +95,7 @@ def forward( if self.detect_orientation else [estimate_orientation(seq_map) for seq_map in seg_maps] ) - pages = [rotate_image(page, -angle, expand=False) for page, angle in zip(pages, origin_page_orientations)] + pages = [rotate_image(page, -angle, expand=False) for page, angle in zip(pages, origin_page_orientations)] # type: ignore[arg-type] # Forward again to get predictions on straight pages loc_preds = self.det_predictor(pages, **kwargs) @@ -104,7 +104,7 @@ def forward( channels_last = len(pages) == 0 or isinstance(pages[0], np.ndarray) # Rectify crops if aspect ratio - dict_loc_preds = {k: self._remove_padding(pages, loc_pred) for k, loc_pred in dict_loc_preds.items()} + dict_loc_preds = {k: self._remove_padding(pages, loc_pred) for k, loc_pred in dict_loc_preds.items()} # type: ignore[arg-type] # Apply hooks to loc_preds if any for hook in self.hooks: @@ -114,7 +114,7 @@ def forward( crops = {} for class_name in dict_loc_preds.keys(): crops[class_name], dict_loc_preds[class_name] = self._prepare_crops( - pages, + pages, # type: ignore[arg-type] dict_loc_preds[class_name], channels_last=channels_last, assume_straight_pages=self.assume_straight_pages, @@ -147,10 +147,10 @@ def forward( languages_dict = None out = self.doc_builder( - pages, + pages, # type: ignore[arg-type] boxes_per_page, text_preds_per_page, - origin_page_shapes, + origin_page_shapes, # type: ignore[arg-type] orientations, languages_dict, ) diff --git a/doctr/models/modules/layers/pytorch.py b/doctr/models/modules/layers/pytorch.py index 07a179b52f..b7ad119ec9 100644 --- a/doctr/models/modules/layers/pytorch.py +++ b/doctr/models/modules/layers/pytorch.py @@ -106,7 +106,7 @@ def _identity_to_conv( id_tensor = torch.from_numpy(kernel_value).to(identity.weight.device) self.id_tensor = self._pad_to_mxn_tensor(id_tensor) kernel = self.id_tensor - std = (identity.running_var + identity.eps).sqrt() # type: ignore[attr-defined] + std = (identity.running_var + identity.eps).sqrt() t = (identity.weight / std).reshape(-1, 1, 1, 1) return kernel * t, identity.bias - identity.running_mean * identity.weight / std diff --git a/doctr/models/modules/transformer/pytorch.py b/doctr/models/modules/transformer/pytorch.py index de76043265..6f1c612978 100644 --- a/doctr/models/modules/transformer/pytorch.py +++ b/doctr/models/modules/transformer/pytorch.py @@ -51,8 +51,8 @@ def scaled_dot_product_attention( scores = torch.matmul(query, key.transpose(-2, -1)) / math.sqrt(query.size(-1)) if mask is not None: # NOTE: to ensure the ONNX compatibility, masked_fill works only with int equal condition - scores = scores.masked_fill(mask == 0, float("-inf")) # type: ignore[attr-defined] - p_attn = torch.softmax(scores, dim=-1) # type: ignore[call-overload] + scores = scores.masked_fill(mask == 0, float("-inf")) + p_attn = torch.softmax(scores, dim=-1) return torch.matmul(p_attn, value), p_attn diff --git a/doctr/models/predictor/pytorch.py b/doctr/models/predictor/pytorch.py index be22024116..ce5a0f51e3 100644 --- a/doctr/models/predictor/pytorch.py +++ b/doctr/models/predictor/pytorch.py @@ -93,7 +93,7 @@ def forward( if self.detect_orientation else [estimate_orientation(seq_map) for seq_map in seg_maps] ) - pages = [rotate_image(page, -angle, expand=False) for page, angle in zip(pages, origin_page_orientations)] + pages = [rotate_image(page, -angle, expand=False) for page, angle in zip(pages, origin_page_orientations)] # type: ignore[arg-type] # Forward again to get predictions on straight pages loc_preds = self.det_predictor(pages, **kwargs) @@ -106,7 +106,7 @@ def forward( channels_last = len(pages) == 0 or isinstance(pages[0], np.ndarray) # Rectify crops if aspect ratio - loc_preds = self._remove_padding(pages, loc_preds) + loc_preds = self._remove_padding(pages, loc_preds) # type: ignore[arg-type] # Apply hooks to loc_preds if any for hook in self.hooks: @@ -114,7 +114,7 @@ def forward( # Crop images crops, loc_preds = self._prepare_crops( - pages, + pages, # type: ignore[arg-type] loc_preds, channels_last=channels_last, assume_straight_pages=self.assume_straight_pages, @@ -134,10 +134,10 @@ def forward( languages_dict = None out = self.doc_builder( - pages, + pages, # type: ignore[arg-type] boxes, text_preds, - origin_page_shapes, + origin_page_shapes, # type: ignore[arg-type] orientations, languages_dict, ) diff --git a/doctr/models/preprocessor/pytorch.py b/doctr/models/preprocessor/pytorch.py index b155425f49..58a236bd08 100644 --- a/doctr/models/preprocessor/pytorch.py +++ b/doctr/models/preprocessor/pytorch.py @@ -79,7 +79,7 @@ def sample_transforms(self, x: Union[np.ndarray, torch.Tensor]) -> torch.Tensor: else: x = x.to(dtype=torch.float32) # type: ignore[union-attr] - return x # type: ignore[return-value] + return x def __call__(self, x: Union[torch.Tensor, np.ndarray, List[Union[torch.Tensor, np.ndarray]]]) -> List[torch.Tensor]: """Prepare document data for model forwarding @@ -103,7 +103,7 @@ def __call__(self, x: Union[torch.Tensor, np.ndarray, List[Union[torch.Tensor, n elif x.dtype not in (torch.uint8, torch.float16, torch.float32): raise TypeError("unsupported data type for torch.Tensor") # Resizing - if x.shape[-2] != self.resize.size[0] or x.shape[-1] != self.resize.size[1]: # type: ignore[union-attr] + if x.shape[-2] != self.resize.size[0] or x.shape[-1] != self.resize.size[1]: x = F.resize( x, self.resize.size, interpolation=self.resize.interpolation, antialias=self.resize.antialias ) @@ -118,11 +118,11 @@ def __call__(self, x: Union[torch.Tensor, np.ndarray, List[Union[torch.Tensor, n # Sample transform (to tensor, resize) samples = list(multithread_exec(self.sample_transforms, x)) # Batching - batches = self.batch_inputs(samples) # type: ignore[assignment] + batches = self.batch_inputs(samples) else: raise TypeError(f"invalid input type: {type(x)}") # Batch transforms (normalize) batches = list(multithread_exec(self.normalize, batches)) - return batches # type: ignore[return-value] + return batches diff --git a/doctr/models/recognition/master/pytorch.py b/doctr/models/recognition/master/pytorch.py index 8b882bbccb..875fcbd687 100644 --- a/doctr/models/recognition/master/pytorch.py +++ b/doctr/models/recognition/master/pytorch.py @@ -107,7 +107,7 @@ def make_source_and_target_mask( # NOTE: nn.TransformerDecoder takes the inverse from this implementation # [True, True, True, ..., False, False, False] -> False is masked # (N, 1, 1, max_length) - target_pad_mask = (target != self.vocab_size + 2).unsqueeze(1).unsqueeze(1) # type: ignore[attr-defined] + target_pad_mask = (target != self.vocab_size + 2).unsqueeze(1).unsqueeze(1) target_length = target.size(1) # sub mask filled diagonal with True = see and False = masked (max_length, max_length) # NOTE: onnxruntime tril/triu works only with float currently (onnxruntime 1.11.1 - opset 14) @@ -142,7 +142,7 @@ def compute_loss( # Input length : number of timesteps input_len = model_output.shape[1] # Add one for additional token (sos disappear in shift!) - seq_len = seq_len + 1 # type: ignore[assignment] + seq_len = seq_len + 1 # Compute loss: don't forget to shift gt! Otherwise the model learns to output the gt[t-1]! # The "masked" first gt char is . Delete last logit of the model output. cce = F.cross_entropy(model_output[:, :-1, :].permute(0, 2, 1), gt[:, 1:], reduction="none") diff --git a/doctr/models/recognition/parseq/pytorch.py b/doctr/models/recognition/parseq/pytorch.py index 555cb4172d..c3a21cd578 100644 --- a/doctr/models/recognition/parseq/pytorch.py +++ b/doctr/models/recognition/parseq/pytorch.py @@ -212,7 +212,7 @@ def generate_permutations(self, seqlen: torch.Tensor) -> torch.Tensor: sos_idx = torch.zeros(len(final_perms), 1, device=seqlen.device) eos_idx = torch.full((len(final_perms), 1), max_num_chars + 1, device=seqlen.device) - combined = torch.cat([sos_idx, final_perms + 1, eos_idx], dim=1).int() # type: ignore + combined = torch.cat([sos_idx, final_perms + 1, eos_idx], dim=1).int() if len(combined) > 1: combined[1, 1:] = max_num_chars + 1 - torch.arange(max_num_chars + 1, device=seqlen.device) return combined @@ -282,7 +282,7 @@ def decode_autoregressive(self, features: torch.Tensor, max_len: Optional[int] = ys[:, i + 1] = pos_prob.squeeze().argmax(-1) # Stop decoding if all sequences have reached the EOS token - if max_len is None and (ys == self.vocab_size).any(dim=-1).all(): # type: ignore[attr-defined] + if max_len is None and (ys == self.vocab_size).any(dim=-1).all(): break logits = torch.cat(pos_logits, dim=1) # (N, max_length, vocab_size + 1) @@ -297,7 +297,7 @@ def decode_autoregressive(self, features: torch.Tensor, max_len: Optional[int] = # Create padding mask for refined target input maskes all behind EOS token as False # (N, 1, 1, max_length) - target_pad_mask = ~((ys == self.vocab_size).int().cumsum(-1) > 0).unsqueeze(1).unsqueeze(1) # type: ignore[attr-defined] + target_pad_mask = ~((ys == self.vocab_size).int().cumsum(-1) > 0).unsqueeze(1).unsqueeze(1) mask = (target_pad_mask.bool() & query_mask[:, : ys.shape[1]].bool()).int() logits = self.head(self.decode(ys, features, mask, target_query=pos_queries)) diff --git a/doctr/models/recognition/sar/pytorch.py b/doctr/models/recognition/sar/pytorch.py index 523f8621a8..a66bd32036 100644 --- a/doctr/models/recognition/sar/pytorch.py +++ b/doctr/models/recognition/sar/pytorch.py @@ -293,7 +293,7 @@ def compute_loss( # Input length : number of timesteps input_len = model_output.shape[1] # Add one for additional token - seq_len = seq_len + 1 # type: ignore[assignment] + seq_len = seq_len + 1 # Compute loss # (N, L, vocab_size + 1) cce = F.cross_entropy(model_output.permute(0, 2, 1), gt, reduction="none") diff --git a/doctr/models/recognition/vitstr/pytorch.py b/doctr/models/recognition/vitstr/pytorch.py index a64807c626..ff6644220d 100644 --- a/doctr/models/recognition/vitstr/pytorch.py +++ b/doctr/models/recognition/vitstr/pytorch.py @@ -137,7 +137,7 @@ def compute_loss( # Input length : number of steps input_len = model_output.shape[1] # Add one for additional token (sos disappear in shift!) - seq_len = seq_len + 1 # type: ignore[assignment] + seq_len = seq_len + 1 # Compute loss: don't forget to shift gt! Otherwise the model learns to output the gt[t-1]! # The "masked" first gt char is . cce = F.cross_entropy(model_output.permute(0, 2, 1), gt[:, 1:], reduction="none") diff --git a/doctr/transforms/functional/pytorch.py b/doctr/transforms/functional/pytorch.py index a8118a129b..65649ea2c8 100644 --- a/doctr/transforms/functional/pytorch.py +++ b/doctr/transforms/functional/pytorch.py @@ -35,9 +35,9 @@ def invert_colors(img: torch.Tensor, min_val: float = 0.6) -> torch.Tensor: rgb_shift = min_val + (1 - min_val) * torch.rand(shift_shape) # Inverse the color if out.dtype == torch.uint8: - out = (out.to(dtype=rgb_shift.dtype) * rgb_shift).to(dtype=torch.uint8) # type: ignore[attr-defined] + out = (out.to(dtype=rgb_shift.dtype) * rgb_shift).to(dtype=torch.uint8) else: - out = out * rgb_shift.to(dtype=out.dtype) # type: ignore[attr-defined] + out = out * rgb_shift.to(dtype=out.dtype) # Inverse the color out = 255 - out if out.dtype == torch.uint8 else 1 - out return out @@ -81,7 +81,7 @@ def rotate_sample( rotated_geoms: np.ndarray = rotate_abs_geoms( _geoms, angle, - img.shape[1:], + img.shape[1:], # type: ignore[arg-type] expand, ).astype(np.float32) @@ -132,7 +132,7 @@ def random_shadow(img: torch.Tensor, opacity_range: Tuple[float, float], **kwarg ------- shaded image """ - shadow_mask = create_shadow_mask(img.shape[1:], **kwargs) + shadow_mask = create_shadow_mask(img.shape[1:], **kwargs) # type: ignore[arg-type] opacity = np.random.uniform(*opacity_range) shadow_tensor = 1 - torch.from_numpy(shadow_mask[None, ...]) diff --git a/doctr/transforms/modules/pytorch.py b/doctr/transforms/modules/pytorch.py index 6a4e38fd18..ac5998750f 100644 --- a/doctr/transforms/modules/pytorch.py +++ b/doctr/transforms/modules/pytorch.py @@ -135,9 +135,9 @@ def forward(self, x: torch.Tensor) -> torch.Tensor: # Reshape the distribution noise = self.mean + 2 * self.std * torch.rand(x.shape, device=x.device) - self.std if x.dtype == torch.uint8: - return (x + 255 * noise).round().clamp(0, 255).to(dtype=torch.uint8) # type: ignore[attr-defined] + return (x + 255 * noise).round().clamp(0, 255).to(dtype=torch.uint8) else: - return (x + noise.to(dtype=x.dtype)).clamp(0, 1) # type: ignore[attr-defined] + return (x + noise.to(dtype=x.dtype)).clamp(0, 1) def extra_repr(self) -> str: return f"mean={self.mean}, std={self.std}" @@ -199,7 +199,7 @@ def __call__(self, x: torch.Tensor) -> torch.Tensor: self.opacity_range, ) ) - .round() # type: ignore[attr-defined] + .round() .clip(0, 255) .to(dtype=torch.uint8) ) diff --git a/pyproject.toml b/pyproject.toml index 0ead9f02cc..bf90aad144 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -13,7 +13,7 @@ maintainers = [ {name = "Felix Dittrich"}, ] readme = "README.md" -requires-python = ">=3.8.0,<4" +requires-python = ">=3.8.0,<4" # TODO: bump to >=3.9 before release license = {file = "LICENSE"} keywords=["OCR", "deep learning", "computer vision", "tensorflow", "pytorch", "text detection", "text recognition"] classifiers=[ @@ -25,9 +25,9 @@ classifiers=[ "Natural Language :: English", "Operating System :: OS Independent", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", "Topic :: Scientific/Engineering :: Artificial Intelligence", ] dynamic = ["version"] @@ -170,7 +170,7 @@ ignore_missing_imports = true [tool.ruff] exclude = [".git", "venv*", "build", "**/__init__.py"] line-length = 120 -target-version = "py38" +target-version = "py39" preview=true [tool.ruff.lint]