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

update installation, support latest transformers version #799

Merged
merged 9 commits into from
Dec 24, 2022
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
16 changes: 8 additions & 8 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -72,30 +72,30 @@ jobs:
run: >
pip install -r requirements.txt

- name: Install PyTorch(1.12.1) and TorchVision(0.13.1) on Linux and Windows
- name: Install PyTorch(1.13.1) and TorchVision(0.14.1) on Linux and Windows
if: >
matrix.operating-system == 'ubuntu-latest' ||
matrix.operating-system == 'windows-latest'
run: >
pip install torch==1.12.1+cpu torchvision==0.13.1+cpu
pip install torch==1.13.1+cpu torchvision==0.14.1+cpu
-f https://download.pytorch.org/whl/torch_stable.html

- name: Install PyTorch on MacOS
if: matrix.operating-system == 'macos-latest'
run: pip install torch==1.12.1 torchvision==0.13.1
run: pip install torch==1.13.1 torchvision==0.14.1

- name: Install MMDetection(2.26.0) with MMCV(1.7.0)
run: >
pip install mmcv-full==1.7.0 -f https://download.openmmlab.com/mmcv/dist/cpu/torch1.12.0/index.html
pip install mmcv-full==1.7.0 -f https://download.openmmlab.com/mmcv/dist/cpu/torch1.13.0/index.html
pip install mmdet==2.26.0

- name: Install YOLOv5(7.0.3)
- name: Install YOLOv5(7.0.4)
run: >
pip install yolov5==7.0.3
pip install yolov5==7.0.4

- name: Install Transformers(4.24.0)
- name: Install Transformers(4.25.1)
run: >
pip install transformers==4.24.0
pip install transformers==4.25.1

- name: Install pycocotools(2.0.6)
run: >
Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/ci_torch1.10.yml
Original file line number Diff line number Diff line change
Expand Up @@ -90,19 +90,19 @@ jobs:
pip install mmcv-full==1.7.0 -f https://download.openmmlab.com/mmcv/dist/cpu/torch1.10.0/index.html
pip install mmdet==2.26.0

- name: Install YOLOv5(7.0.3)
- name: Install YOLOv5(7.0.4)
run: >
pip install yolov5==7.0.3
pip install yolov5==7.0.4

- name: Install Detectron2(0.6)
run: >
python -m pip install detectron2 -f https://dl.fbaipublicfiles.com/detectron2/wheels/cpu/torch1.10/index.html

- name: Install Transformers(4.24.0)
- name: Install Transformers(4.25.1)
if: >
matrix.python-version != '3.6'
run: >
pip install transformers==4.24.0
pip install transformers==4.25.1

- name: Install pycocotools(2.0.6)
run: >
Expand Down
14 changes: 6 additions & 8 deletions .github/workflows/package_testing.yml
Original file line number Diff line number Diff line change
Expand Up @@ -62,24 +62,22 @@ jobs:
if: matrix.operating-system == 'macos-latest'
run: pip install torch==1.10.1 torchvision==0.11.2

- name: Install MMDetection(2.25.3) with MMCV(1.7.0)
- name: Install MMDetection(2.26.9) with MMCV(1.7.0)
run: >
pip install mmcv-full==1.7.0 -f https://download.openmmlab.com/mmcv/dist/cpu/torch1.10.0/index.html
pip install mmdet==2.25.3
pip install mmdet==2.26.0

- name: Install YOLOv5(7.0.3)
- name: Install YOLOv5(7.0.4)
run: >
pip install yolov5==7.0.3
pip install yolov5==7.0.4

- name: Install Detectron2(0.6)
run: >
python -m pip install detectron2 -f https://dl.fbaipublicfiles.com/detectron2/wheels/cpu/torch1.10/index.html

- name: Install Transformers(4.24.0)
if: >
matrix.python-version != '3.6'
- name: Install Transformers(4.25.1)
run: >
pip install transformers==4.24.0
pip install transformers==4.25.1

- name: Install pycocotools(2.0.6)
run: >
Expand Down
12 changes: 8 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,22 +109,26 @@ pip install sahi
conda install -c conda-forge shapely
```

- Install your desired version of pytorch and torchvision:
- Install your desired version of pytorch and torchvision (cuda 11.3 for detectron2, cuda 11.7 for rest):

```console
conda install pytorch=1.12.1 torchvision=0.13.1 cudatoolkit=11.3 -c pytorch
conda install pytorch=1.10.2 torchvision=0.11.3 cudatoolkit=11.3 -c pytorch
```

```console
conda install pytorch=1.13.1 torchvision=0.14.1 pytorch-cuda=11.7 -c pytorch -c nvidia
```

- Install your desired detection framework (yolov5):

```console
pip install yolov5==6.2.3
pip install yolov5==7.0.4
```

- Install your desired detection framework (mmdet):

```console
pip install mmcv-full==1.7.0 -f https://download.openmmlab.com/mmcv/dist/cu113/torch1.11.0/index.html
pip install mmcv-full==1.7.0 -f https://download.openmmlab.com/mmcv/dist/cu117/torch1.13.0/index.html
```

```console
Expand Down
41 changes: 19 additions & 22 deletions sahi/models/huggingface.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ def __init__(
self,
model_path: Optional[str] = None,
model: Optional[Any] = None,
feature_extractor: Optional[Any] = None,
processor: Optional[Any] = None,
config_path: Optional[str] = None,
device: Optional[str] = None,
mask_threshold: float = 0.5,
Expand All @@ -31,7 +31,7 @@ def __init__(
image_size: int = None,
):

self._feature_extractor = feature_extractor
self._processor = processor
self._image_shapes = []
super().__init__(
model_path,
Expand All @@ -48,11 +48,11 @@ def __init__(

def check_dependencies(self):
check_requirements(["torch", "transformers"])
ensure_package_minimum_version("transformers", "4.24.0")
ensure_package_minimum_version("transformers", "4.25.1")

@property
def feature_extractor(self):
return self._feature_extractor
def processor(self):
return self._processor

@property
def image_shapes(self):
Expand All @@ -67,31 +67,28 @@ def num_categories(self) -> int:

def load_model(self):

from transformers import AutoFeatureExtractor, AutoModelForObjectDetection
from transformers import AutoModelForObjectDetection, AutoProcessor

model = AutoModelForObjectDetection.from_pretrained(self.model_path)
if self.image_size is not None:
feature_extractor = AutoFeatureExtractor.from_pretrained(
self.model_path, size=self.image_size, do_resize=True
processor = AutoProcessor.from_pretrained(
self.model_path, size={"shortest_edge": self.image_size, "longest_edge": None}, do_resize=True
)
else:
feature_extractor = AutoFeatureExtractor.from_pretrained(self.model_path)
self.set_model(model, feature_extractor)

def set_model(self, model: Any, feature_extractor: Any = None):
feature_extractor = feature_extractor or self.feature_extractor
if feature_extractor is None:
raise ValueError(f"'feature_extractor' is required to be set, got {feature_extractor}.")
elif (
"ObjectDetection" not in model.__class__.__name__
or "FeatureExtractor" not in feature_extractor.__class__.__name__
):
processor = AutoProcessor.from_pretrained(self.model_path)
self.set_model(model, processor)

def set_model(self, model: Any, processor: Any = None):
processor = processor or self.processor
if processor is None:
raise ValueError(f"'processor' is required to be set, got {processor}.")
elif "ObjectDetection" not in model.__class__.__name__ or "ImageProcessor" not in processor.__class__.__name__:
raise ValueError(
"Given 'model' is not an ObjectDetectionModel or 'feature_extractor' is not a valid FeatureExtractor."
"Given 'model' is not an ObjectDetectionModel or 'processor' is not a valid ImageProcessor."
)
self.model = model
self.model.to(self.device)
self._feature_extractor = feature_extractor
self._processor = processor
self.category_mapping = self.model.config.id2label

def perform_inference(self, image: Union[List, np.ndarray]):
Expand All @@ -108,7 +105,7 @@ def perform_inference(self, image: Union[List, np.ndarray]):
raise RuntimeError("Model is not loaded, load it by calling .load_model()")

with torch.no_grad():
inputs = self.feature_extractor(images=image, return_tensors="pt")
inputs = self.processor(images=image, return_tensors="pt")
inputs["pixel_values"] = inputs.pixel_values.to(self.device)
if hasattr(inputs, "pixel_mask"):
inputs["pixel_mask"] = inputs.pixel_mask.to(self.device)
Expand Down
8 changes: 3 additions & 5 deletions tests/test_huggingfacemodel.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,20 +32,18 @@ def test_load_model(self):
self.assertNotEqual(huggingface_detection_model.model, None)

def test_set_model(self):
from transformers import AutoFeatureExtractor, AutoModelForObjectDetection
from transformers import AutoModelForObjectDetection, AutoProcessor

from sahi.models.huggingface import HuggingfaceDetectionModel

huggingface_model = AutoModelForObjectDetection.from_pretrained(
HuggingfaceTestConstants.YOLOS_TINY_MODEL_PATH
)
huggingface_feature_extractor = AutoFeatureExtractor.from_pretrained(
HuggingfaceTestConstants.YOLOS_TINY_MODEL_PATH
)
huggingface_processor = AutoProcessor.from_pretrained(HuggingfaceTestConstants.YOLOS_TINY_MODEL_PATH)

huggingface_detection_model = HuggingfaceDetectionModel(
model=huggingface_model,
feature_extractor=huggingface_feature_extractor,
processor=huggingface_processor,
confidence_threshold=CONFIDENCE_THRESHOLD,
device=MODEL_DEVICE,
category_remapping=None,
Expand Down