Skip to content

Commit 170a109

Browse files
authored
Merge branch 'main' into dependabot/pip/idna-3.7
2 parents 1ab3056 + dcf3d17 commit 170a109

File tree

15 files changed

+217
-58
lines changed

15 files changed

+217
-58
lines changed

.devcontainer/devcontainer.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
"vscode": {
99
"extensions": [
1010
"ms-python.python",
11+
"ms-python.debugpy",
1112
"ms-python.black-formatter"
1213
],
1314
"settings": {

CONTRIBUTING.md

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,13 @@ If you want to extend our Python library or if you find a bug, please open a PR!
55

66
Also be sure to test your code the `unittest` command at the `/root` level directory.
77

8-
Run tests:
8+
### Devcontainer
9+
10+
This project comes with a [convenient devcontainer](https://www.loom.com/share/a183c4a351ed4700a79476fedf08ab9b) that makes it easier to run tests and has black configured to run on save.
11+
12+
On rare occasions a full rebuild is needed, you can do it in VSCode by pressing `Ctrl+Shift+P` and running `Dev Containers: Rebuild Container`.
13+
14+
### Tests
915

1016
```bash
1117
python -m unittest
@@ -39,4 +45,12 @@ make check_code_quality
3945

4046
**Note** These tests will be run automatically when you commit thanks to git hooks.
4147

42-
**Note** This project also comes with a [convenient devcontainer](https://www.loom.com/share/a183c4a351ed4700a79476fedf08ab9b) that makes it easier to run tests and has black configured to run on save.
48+
### Docs
49+
50+
The docs can be built with `mkdocs serve`.
51+
52+
Before that, install the dependencies:
53+
54+
```python
55+
python -m pip install mkdocs mkdocs-material mkdocstrings mkdocstrings[python]
56+
```

requirements.txt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
certifi==2023.7.22
1+
certifi
22
chardet==4.0.0
3-
cycler==0.10.0
43
idna==3.7
4+
cycler
55
kiwisolver>=1.3.1
66
matplotlib
77
numpy>=1.18.5
8-
opencv-python-headless==4.8.0.74
8+
opencv-python-headless==4.10.0.84
99
Pillow>=7.1.2
1010
python-dateutil
1111
python-dotenv

roboflow/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
from roboflow.models import CLIPModel, GazeModel # noqa: F401
1515
from roboflow.util.general import write_line
1616

17-
__version__ = "1.1.27"
17+
__version__ = "1.1.32"
1818

1919

2020
def check_key(api_key, model, notebook, num_retries=0):

roboflow/config.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ def get_conditional_configuration_variable(key, default):
7575
DEFAULT_JOB_NAME = "Annotated via API"
7676

7777
RF_WORKSPACES = get_conditional_configuration_variable("workspaces", default={})
78+
TQDM_DISABLE = os.getenv("TQDM_DISABLE", None)
7879

7980

8081
def load_roboflow_api_key(workspace_url=None):

roboflow/core/project.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -528,9 +528,9 @@ def single_upload(
528528

529529
def _annotation_params(self, annotation_path):
530530
annotation_name, annotation_string = None, None
531-
if isinstance(annotation_path, dict):
531+
if isinstance(annotation_path, dict) and annotation_path.get("rawText"):
532532
annotation_name = annotation_path["name"]
533-
annotation_string = json.dumps(annotation_path["parsed"])
533+
annotation_string = annotation_path["rawText"]
534534
elif os.path.exists(annotation_path):
535535
with open(annotation_path, "r"):
536536
annotation_string = open(annotation_path, "r").read()

roboflow/core/version.py

Lines changed: 75 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
API_URL,
1818
APP_URL,
1919
DEMO_KEYS,
20+
TQDM_DISABLE,
2021
TYPE_CLASSICATION,
2122
TYPE_INSTANCE_SEGMENTATION,
2223
TYPE_KEYPOINT_DETECTION,
@@ -432,11 +433,15 @@ def deploy(self, model_type: str, model_path: str, filename: str = "weights/best
432433
filename (str, optional): The name of the weights file. Defaults to "weights/best.pt".
433434
"""
434435

435-
supported_models = ["yolov5", "yolov7-seg", "yolov8", "yolov9", "yolonas"]
436+
supported_models = ["yolov5", "yolov7-seg", "yolov8", "yolov9", "yolonas", "paligemma", "yolov10"]
436437

437438
if not any(supported_model in model_type for supported_model in supported_models):
438439
raise (ValueError(f"Model type {model_type} not supported. Supported models are" f" {supported_models}"))
439440

441+
if "paligemma" in model_type:
442+
self.deploy_paligemma(model_type, model_path, filename)
443+
return
444+
440445
if "yolonas" in model_type:
441446
self.deploy_yolonas(model_type, model_path, filename)
442447
return
@@ -454,6 +459,17 @@ def deploy(self, model_type: str, model_path: str, filename: str = "weights/best
454459

455460
print_warn_for_wrong_dependencies_versions([("ultralytics", "==", "8.0.196")], ask_to_continue=True)
456461

462+
elif "yolov10" in model_type:
463+
try:
464+
import torch
465+
import ultralytics
466+
467+
except ImportError:
468+
raise (
469+
"The ultralytics python package is required to deploy yolov10"
470+
" models. Please install it with `pip install ultralytics`"
471+
)
472+
457473
elif "yolov5" in model_type or "yolov7" in model_type or "yolov9" in model_type:
458474
try:
459475
import torch
@@ -474,7 +490,7 @@ def deploy(self, model_type: str, model_path: str, filename: str = "weights/best
474490
class_names.sort(key=lambda x: x[0])
475491
class_names = [x[1] for x in class_names]
476492

477-
if "yolov8" in model_type:
493+
if "yolov8" in model_type or "yolov10" in model_type:
478494
# try except for backwards compatibility with older versions of ultralytics
479495
if "-cls" in model_type:
480496
nc = model["model"].yaml["nc"]
@@ -548,6 +564,57 @@ def deploy(self, model_type: str, model_path: str, filename: str = "weights/best
548564

549565
self.upload_zip(model_type, model_path)
550566

567+
def deploy_paligemma(
568+
self, model_type: str, model_path: str, filename: str = "fine-tuned-paligemma-3b-pt-224.f16.npz"
569+
) -> None:
570+
# Check if model_path exists
571+
if not os.path.exists(model_path):
572+
raise FileNotFoundError(f"Model path {model_path} does not exist.")
573+
model_files = os.listdir(model_path)
574+
print(f"Model files found in {model_path}: {model_files}")
575+
576+
files_to_deploy = []
577+
578+
# Find first .npz file in model_path
579+
npz_filename = next((file for file in model_files if file.endswith(".npz")), None)
580+
if any([file.endswith(".safetensors") for file in model_files]):
581+
print("Found .safetensors file in model path. Deploying PyTorch PaliGemma model.")
582+
necessary_files = [
583+
"config.json",
584+
"generation_config.json",
585+
"model.safetensors.index.json",
586+
"preprocessor_config.json",
587+
"special_tokens_map.json",
588+
"tokenizer_config.json",
589+
"tokenizer.json",
590+
]
591+
for file in necessary_files:
592+
if file not in model_files:
593+
print("Missing necessary file", file)
594+
res = input("Do you want to continue? (y/n)")
595+
if res.lower() != "y":
596+
exit(1)
597+
for file in model_files:
598+
files_to_deploy.append(file)
599+
elif npz_filename is not None:
600+
print(f"Found .npz file {npz_filename} in model path. Deploying JAX PaliGemma model.")
601+
files_to_deploy.append(npz_filename)
602+
else:
603+
raise FileNotFoundError(f"No .npz or .safetensors file found in model path {model_path}.")
604+
605+
if len(files_to_deploy) == 0:
606+
raise FileNotFoundError(f"No valid files found in model path {model_path}.")
607+
print(f"Zipping files for deploy: {files_to_deploy}")
608+
609+
import tarfile
610+
611+
with tarfile.open(os.path.join(model_path, "roboflow_deploy.tar"), "w") as tar:
612+
for file in files_to_deploy:
613+
tar.add(os.path.join(model_path, file), arcname=file)
614+
615+
print("Uploading to Roboflow... May take several minutes.")
616+
self.upload_zip(model_type, model_path, "roboflow_deploy.tar")
617+
551618
def deploy_yolonas(self, model_type: str, model_path: str, filename: str = "weights/best.pt") -> None:
552619
try:
553620
import torch
@@ -613,7 +680,7 @@ def deploy_yolonas(self, model_type: str, model_path: str, filename: str = "weig
613680

614681
self.upload_zip(model_type, model_path)
615682

616-
def upload_zip(self, model_type: str, model_path: str):
683+
def upload_zip(self, model_type: str, model_path: str, model_file_name: str = "roboflow_deploy.zip"):
617684
res = requests.get(
618685
f"{API_URL}/{self.workspace}/{self.project}/{self.version}"
619686
f"/uploadModel?api_key={self.__api_key}&modelType={model_type}&nocache=true"
@@ -632,7 +699,7 @@ def upload_zip(self, model_type: str, model_path: str):
632699

633700
res = requests.put(
634701
res.json()["url"],
635-
data=open(os.path.join(model_path, "roboflow_deploy.zip"), "rb"),
702+
data=open(os.path.join(model_path, model_file_name), "rb"),
636703
)
637704
try:
638705
res.raise_for_status()
@@ -685,9 +752,10 @@ def bar_progress(current, total, width=80):
685752
# write the zip file to the desired location
686753
with open(location + "/roboflow.zip", "wb") as f:
687754
total_length = int(response.headers.get("content-length"))
755+
desc = None if TQDM_DISABLE else f"Downloading Dataset Version Zip in {location} to {format}:"
688756
for chunk in tqdm(
689757
response.iter_content(chunk_size=1024),
690-
desc=f"Downloading Dataset Version Zip in {location} to {format}:",
758+
desc=desc,
691759
total=int(total_length / 1024) + 1,
692760
):
693761
if chunk:
@@ -711,10 +779,11 @@ def __extract_zip(self, location, format):
711779
Raises:
712780
RuntimeError: If there is an error unzipping the file
713781
""" # noqa: E501 // docs
782+
desc = None if TQDM_DISABLE else f"Extracting Dataset Version Zip to {location} in {format}:"
714783
with zipfile.ZipFile(location + "/roboflow.zip", "r") as zip_ref:
715784
for member in tqdm(
716785
zip_ref.infolist(),
717-
desc=f"Extracting Dataset Version Zip to {location} in {format}:",
786+
desc=desc,
718787
):
719788
try:
720789
zip_ref.extract(member, location)

roboflow/core/workspace.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -341,8 +341,8 @@ def _upload_image(imagedesc):
341341
labelmap = None
342342
annotationdesc = imagedesc.get("annotationfile")
343343
if annotationdesc:
344-
if annotationdesc.get("parsed"):
345-
annotation_path = {"name": annotationdesc["name"], "parsed": annotationdesc["parsed"]}
344+
if annotationdesc.get("rawText"):
345+
annotation_path = annotationdesc
346346
else:
347347
annotation_path = f"{location}{annotationdesc['file']}"
348348
labelmap = annotationdesc.get("labelmap")

0 commit comments

Comments
 (0)