diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml index f78f7df..407e5b1 100644 --- a/.github/workflows/push.yml +++ b/.github/workflows/push.yml @@ -15,7 +15,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - model: [yolo11n,yolov8s-worldv2] + model: [yolo11n,yolov8s-worldv2,yoloe11s] steps: - name: Checkout uses: actions/checkout@v4 diff --git a/.gitignore b/.gitignore index e857811..86010ef 100644 --- a/.gitignore +++ b/.gitignore @@ -182,3 +182,25 @@ weights/ *_openvino_model/ *_paddle_model/ pnnx* +*.ts + +# Replicate deployment folder and files +cog.json +cog.lock +.cog + +# Ignore Picture files +*.jpg +*.jpeg +*.png +*.gif +*.bmps + +# Ignore video files +*.mp4 +*.avi +*.mov +*.mkv +*.webm +*.flv +*.wmv diff --git a/yolo11n/predict.py b/yolo11n/predict.py index 3f23445..ad27f4d 100644 --- a/yolo11n/predict.py +++ b/yolo11n/predict.py @@ -7,6 +7,8 @@ class Output(BaseModel): + """Output model for predictions.""" + image: Optional[Path] = None json_str: Optional[str] = None diff --git a/yoloe11s/README.md b/yoloe11s/README.md new file mode 100644 index 0000000..8347d24 --- /dev/null +++ b/yoloe11s/README.md @@ -0,0 +1,30 @@ +# YOLOE-11S Demo Deployment + +Deploy the official YOLOE-11S model to Replicate with PyTorch inference at . + +## Setup + +1. **Deploy to Replicate:** + + ```bash + cog push r8.im/ultralytics/yoloe-11s + ``` + +## Model Details + +- **Model**: YOLOE-11S (Small) +- **Parameters**: 10.2M +- **Format**: PyTorch (.pt) +- **Use Case**: Demonstration of official Ultralytics model deployment + +## Model Files + +**Note:** The model weights (`yoloe-11s-seg.pt`) and (`mobileclip_blt.ts`) will be automatically downloaded by ultralytics when the container starts. + +## Configuration + +- **GPU**: Disabled by default (CPU inference) +- **Python**: 3.12 with PyTorch 2.3.1+ +- **Framework**: Ultralytics 8.3+ +- **Input**: Single image with configurable confidence/IoU thresholds, image size, and class names. +- **Output**: Annotated image with detected objects diff --git a/yoloe11s/cog.yaml b/yoloe11s/cog.yaml new file mode 100644 index 0000000..38d4dc6 --- /dev/null +++ b/yoloe11s/cog.yaml @@ -0,0 +1,15 @@ +# Ultralytics 🚀 AGPL-3.0 License - https://ultralytics.com/license + +build: + gpu: false + python_version: "3.12" + system_packages: + - "libgl1-mesa-glx" + - "libglib2.0-0" + - "ffmpeg" + python_packages: + - "ultralytics>=8.3.0" + - "clip @ git+https://github.com/ultralytics/CLIP.git@main#egg=clip" + +predict: predict.py:Predictor +image: r8.im/ultralytics/yoloe-11s diff --git a/yoloe11s/download.py b/yoloe11s/download.py new file mode 100644 index 0000000..dc13a32 --- /dev/null +++ b/yoloe11s/download.py @@ -0,0 +1,21 @@ +# Ultralytics 🚀 AGPL-3.0 License - https://ultralytics.com/license + +from pathlib import Path + +from ultralytics import YOLOE + + +def main(): + """Download YOLOe-11s-seg and YOLOe-11s-seg-pf weights and move to model directory.""" + current_dir = Path(__file__).parent + YOLOE(current_dir / "yoloe-11s-seg.pt") + YOLOE(current_dir / "yoloe-11s-seg-pf.pt") + + # List files in model directory + print(f"Files in {current_dir.name} directory:") + for file in sorted(current_dir.iterdir()): + print(f" {file.stat().st_size:>10} {file.name}") + + +if __name__ == "__main__": + main() diff --git a/yoloe11s/predict.py b/yoloe11s/predict.py new file mode 100644 index 0000000..20df8d2 --- /dev/null +++ b/yoloe11s/predict.py @@ -0,0 +1,54 @@ +# Ultralytics 🚀 AGPL-3.0 License - https://ultralytics.com/license + +from typing import Optional + +from cog import BaseModel, BasePredictor, Input, Path +from ultralytics import YOLOE + + +class Output(BaseModel): + """Output model for predictions.""" + + image: Optional[Path] = None + json_str: Optional[str] = None + + +class Predictor(BasePredictor): + """YOLOE: Real-Time Seeing Anything model predictor for Replicate deployment.""" + + def setup(self) -> None: + """Load YOLOE-11S model into memory.""" + self.model = YOLOE("yoloe-11s-seg.pt") + + def re_init_model(self, class_names: str) -> None: + """Re-Initialize model with class names.""" + if class_names.strip() != "": + self.model = YOLOE("yoloe-11s-seg.pt") + class_list = class_names.split(", ") + self.model.set_classes(class_list, self.model.get_text_pe(class_list)) + else: + # Load YOLOE-11s model prompt free model into memory + self.model = YOLOE("yoloe-11s-seg-pf.pt") + + def predict( + self, + image: Path = Input(description="Input image"), + conf: float = Input(description="Confidence threshold", default=0.25, ge=0.0, le=1.0), + iou: float = Input(description="IoU threshold for NMS", default=0.45, ge=0.0, le=1.0), + imgsz: int = Input(description="Image size", default=640, choices=[320, 416, 512, 640, 832, 1024, 1280]), + class_names: str = Input( + description="Comma-separated list of class names to filter results (e.g., 'person, bus, sign') You can also leave it empty to detect classes automatically.", + default="person, bus, sign", + ), + return_json: bool = Input(description="Return detection results as JSON", default=False), + ) -> Output: + """Run inference and return annotated image with optional JSON results.""" + self.re_init_model(class_names) + result = self.model(str(image), conf=conf, iou=iou, imgsz=imgsz)[0] + image_path = "output.png" + result.save(image_path) + + if return_json: + return Output(image=Path(image_path), json_str=result.to_json()) + else: + return Output(image=Path(image_path))