Skip to content

Commit 6d46063

Browse files
onuralpszrUltralyticsAssistantglenn-jocher
authored
feat: 🚀 add YOLOv8s WorldV2 deployment workflow and model predictor (#21)
Signed-off-by: Glenn Jocher <glenn.jocher@ultralytics.com> Signed-off-by: Onuralp SEZER <onuralp@ultralytics.com> Co-authored-by: UltralyticsAssistant <web@ultralytics.com> Co-authored-by: Glenn Jocher <glenn.jocher@ultralytics.com>
1 parent 82cebe8 commit 6d46063

5 files changed

Lines changed: 117 additions & 2 deletions

File tree

‎.github/workflows/push.yml‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ jobs:
1515
runs-on: ubuntu-latest
1616
strategy:
1717
matrix:
18-
model: [yolo11n]
18+
model: [yolo11n,yolov8s-worldv2]
1919
steps:
2020
- name: Checkout
2121
uses: actions/checkout@v4
@@ -31,7 +31,7 @@ jobs:
3131
uses: replicate/setup-cog@v2
3232
with:
3333
token: ${{ secrets.REPLICATE_API_TOKEN }}
34-
- name: Download YOLO11n weights
34+
- name: Download model weights
3535
run: python ${{ matrix.model }}/download.py
3636
- name: Build model image
3737
working-directory: ${{ matrix.model }}

‎yolov8s-worldv2/README.md‎

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# YOLOv8s WorldV2 Demo Deployment
2+
3+
Deploy the official YOLOv8s WorldV2 model to Replicate with PyTorch inference at https://replicate.com/ultralytics/yolov8s-worldv2.
4+
5+
## Setup
6+
7+
1. **Deploy to Replicate:**
8+
9+
```bash
10+
cog push r8.im/ultralytics/yolov8s-worldv2
11+
```
12+
13+
## Model Details
14+
15+
- **Model**: YOLOv8s WorldV2 (Small)
16+
- **Parameters**: 12.7M
17+
- **Format**: PyTorch (.pt)
18+
- **Use Case**: Demonstration of official Ultralytics model deployment
19+
20+
## Model Files
21+
22+
**Note:** The model weights (`yolov8s-worldv2.pt`) will be automatically downloaded by ultralytics when the container starts.
23+
24+
## Configuration
25+
26+
- **GPU**: Disabled by default (CPU inference)
27+
- **Python**: 3.12 with PyTorch 2.3.1+
28+
- **Framework**: Ultralytics 8.3+
29+
- **Input**: Single image with configurable confidence/IoU thresholds
30+
- **Output**: Annotated image with detected objects

‎yolov8s-worldv2/cog.yaml‎

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# Ultralytics 🚀 AGPL-3.0 License - https://ultralytics.com/license
2+
3+
build:
4+
gpu: false
5+
python_version: "3.12"
6+
system_packages:
7+
- "libgl1-mesa-glx"
8+
- "libglib2.0-0"
9+
- "ffmpeg"
10+
python_packages:
11+
- "ultralytics>=8.3.0"
12+
- "clip @ git+https://github.com/ultralytics/CLIP.git@main#egg=clip"
13+
14+
predict: predict.py:Predictor
15+
image: r8.im/ultralytics/yolov8s-worldv2
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# Ultralytics 🚀 AGPL-3.0 License - https://ultralytics.com/license
2+
3+
from pathlib import Path
4+
5+
from ultralytics import YOLOWorld
6+
7+
8+
def main():
9+
"""Download YOLOv8s-worldv2 weights and move to model directory."""
10+
current_dir = Path(__file__).parent
11+
YOLOWorld(current_dir / "yolov8s-worldv2.pt")
12+
13+
# List files in model directory
14+
print(f"Files in {current_dir.name} directory:")
15+
for file in sorted(current_dir.iterdir()):
16+
print(f" {file.stat().st_size:>10} {file.name}")
17+
18+
19+
if __name__ == "__main__":
20+
main()

‎yolov8s-worldv2/predict.py‎

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# Ultralytics 🚀 AGPL-3.0 License - https://ultralytics.com/license
2+
3+
from typing import Optional
4+
5+
from cog import BaseModel, BasePredictor, Input, Path
6+
from ultralytics import YOLOWorld
7+
8+
9+
class Output(BaseModel):
10+
"""Output model for predictions."""
11+
12+
image: Optional[Path] = None
13+
json_str: Optional[str] = None
14+
15+
16+
class Predictor(BasePredictor):
17+
"""YOLOv8s WorldV2 model predictor for Replicate deployment."""
18+
19+
def setup(self) -> None:
20+
"""Load YOLOWorld model into memory."""
21+
self.model = YOLOWorld("yolov8s-worldv2.pt")
22+
23+
def re_init_model(self, class_names: str) -> None:
24+
"""Re-Initialize model with class names."""
25+
self.model = YOLOWorld("yolov8s-worldv2.pt")
26+
class_list = class_names.split(", ")
27+
self.model.set_classes(class_list)
28+
29+
def predict(
30+
self,
31+
image: Path = Input(description="Input image"),
32+
conf: float = Input(description="Confidence threshold", default=0.25, ge=0.0, le=1.0),
33+
iou: float = Input(description="IoU threshold for NMS", default=0.45, ge=0.0, le=1.0),
34+
imgsz: int = Input(description="Image size", default=640, choices=[320, 416, 512, 640, 832, 1024, 1280]),
35+
class_names: str = Input(
36+
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.",
37+
default="person, bus, sign",
38+
),
39+
return_json: bool = Input(description="Return detection results as JSON", default=False),
40+
) -> Output:
41+
"""Run inference and return annotated image with optional JSON results."""
42+
self.re_init_model(class_names)
43+
result = self.model(str(image), conf=conf, iou=iou, imgsz=imgsz)[0]
44+
image_path = "output.png"
45+
result.save(image_path)
46+
47+
if return_json:
48+
return Output(image=Path(image_path), json_str=result.to_json())
49+
else:
50+
return Output(image=Path(image_path))

0 commit comments

Comments
 (0)