Skip to content
Draft
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
18 changes: 18 additions & 0 deletions backend/core/migrations/0009_alter_model_base_model.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Generated by Django 5.2.1 on 2025-08-14 11:55

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('core', '0008_prediction_result_count'),
]

operations = [
migrations.AlterField(
model_name='model',
name='base_model',
field=models.CharField(choices=[('RAMP', 'RAMP'), ('YOLO_V8_V1', 'YOLO_V8_V1'), ('YOLO_V8_V2', 'YOLO_V8_V2'), ('YOLO_V11', 'YOLO_V11'), ('YOLO_V11_SAM', 'YOLO_V11_SAM')], default='RAMP', max_length=50),
),
]
2 changes: 2 additions & 0 deletions backend/core/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ class Model(models.Model):
("RAMP", "RAMP"),
("YOLO_V8_V1", "YOLO_V8_V1"),
("YOLO_V8_V2", "YOLO_V8_V2"),
("YOLO_V11", "YOLO_V11"),
("YOLO_V11_SAM", "YOLO_V11_SAM"),
)

class ModelStatus(models.IntegerChoices):
Expand Down
75 changes: 57 additions & 18 deletions backend/core/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,8 +127,16 @@ def _train_yolo(self, output_path):
from hot_fair_utilities.preprocessing.yolo_v8_v2.yolo_format import (
yolo_format as v2,
)
from hot_fair_utilities.preprocessing.yolo_v11.yolo_format import (
yolo_format as v11,
)
from hot_fair_utilities.preprocessing.yolo_v11_sam.yolo_format import (
yolo_format as v11_sam,
)
from hot_fair_utilities.training.yolo_v8_v1.train import train as train_v1
from hot_fair_utilities.training.yolo_v8_v2.train import train as train_v2
from hot_fair_utilities.training.yolo_v11.train import train as train_v11
from hot_fair_utilities.training.yolo_v11_sam.train import train as train_v11_sam

(
inst,
Expand Down Expand Up @@ -161,31 +169,62 @@ def _train_yolo(self, output_path):
rasterize_options=["binary"],
georeference_images=True,
multimasks=(multimasks or self.model_type == "YOLO_V8_V1"),
epsg=4326 if self.model_type == "YOLO_V8_V2" else 3857,
epsg=4326 if (self.model_type == "YOLO_V8_V2" or self.model_type == "YOLO_V11" or self.model_type == "YOLO_V11_sam") else 3857,
input_contact_spacing=4,
input_boundary_width=2,
)

inst.chips_length = get_file_count(os.path.join(prep, "chips"))
inst.save()

with print_time("YOLO format"):
if self.model_type == "YOLO_V8_V1":
v1(
preprocessed_dirs=prep,
yolo_dir=model_dir,
multimask=True,
p_val=0.05,
)
else:
v2(input_path=prep, output_path=model_dir)

train_fn = train_v1 if self.model_type == "YOLO_V8_V1" else train_v2
weights = (
"yolov8s_v1-seg-best.pt"
if self.model_type == "YOLO_V8_V1"
else "yolov8s_v2-seg.pt"
)
match self.model_type:
case "YOLO_V8_V1":
with print_time("YOLO format"):
v1(
preprocessed_dirs=prep,
yolo_dir=model_dir,
multimask=True,
p_val=0.05,
)
weights = "yolov8s_v1-seg-best.pt"
case "YOLO_V8_V2":
with print_time("YOLO format"):
v2(input_path=prep, output_path=model_dir)
train_fn = train_v1
weights = "yolov8s_v2-seg.pt"
case "YOLO_V11":
with print_time("YOLO format"):
v11(input_path=prep, output_path=model_dir)
train_fn = train_v11
weights = "yolo11n-seg.pt"
case "YOLO_V11_SAM":
with print_time("YOLO format"):
v11_sam(input_path=prep, output_path=model_dir)
train_fn = train_v11_sam
weights = "yolo11n-seg.pt"
case _:
with print_time("YOLO format"):
v2(input_path=prep, output_path=model_dir)
train_fn = train_v2
weights = "yolov8s_v1-seg-best.pt"

# with print_time("YOLO format"):
# if self.model_type == "YOLO_V8_V1":
# v1(
# preprocessed_dirs=prep,
# yolo_dir=model_dir,
# multimask=True,
# p_val=0.05,
# )
# else:
# v2(input_path=prep, output_path=model_dir)

# train_fn = train_v1 if self.model_type == "YOLO_V8_V1" else train_v2
# weights = (
# "yolov8s_v1-seg-best.pt"
# if self.model_type == "YOLO_V8_V1"
# else "yolov8s_v2-seg.pt"
# )

model_path, acc = train_fn(
data=base,
Expand Down
2 changes: 1 addition & 1 deletion backend/core/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ def create(self, validated_data):
raise ValidationError(
f"Batch size can't be greater than {settings.RAMP_BATCH_SIZE_LIMIT} on this server"
)
if model.base_model in ["YOLO_V8_V1", "YOLO_V8_V2"]:
if model.base_model in ["YOLO_V8_V1", "YOLO_V8_V2", "YOLO_V11", "YOLO_V11_SAM"]:
if epochs > settings.YOLO_EPOCHS_LIMIT:
raise ValidationError(
f"Epochs can't be greater than {settings.YOLO_EPOCHS_LIMIT} on this server"
Expand Down
1 change: 1 addition & 0 deletions backend/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
protobuf==3.20.2
1 change: 1 addition & 0 deletions frontend/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
protobuf==3.20.2
38 changes: 38 additions & 0 deletions frontend/src/app/providers/models-provider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,44 @@ export const FORM_VALIDATION_CONFIG = {
min: 1,
},
},
[BASE_MODELS.YOLOV11]: {
epoch: {
max: 150,
min: 20,
},
batchSize: {
max: 16,
min: 8,
},
// These are not used
contactSpacing: {
max: 8,
min: 1,
},
boundaryWidth: {
max: 8,
min: 1,
},
},
[BASE_MODELS.YOLOV11_SAM]: {
epoch: {
max: 150,
min: 20,
},
batchSize: {
max: 16,
min: 8,
},
// These are not used
contactSpacing: {
max: 8,
min: 1,
},
boundaryWidth: {
max: 8,
min: 1,
},
},
};

type FormData = {
Expand Down
4 changes: 4 additions & 0 deletions frontend/src/config/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -393,6 +393,8 @@ export const PREDICTION_API_FILE_EXTENSIONS: Record<BASE_MODELS, string> = {
[BASE_MODELS.RAMP]: ".tflite",
[BASE_MODELS.YOLOV8_V1]: ".onnx",
[BASE_MODELS.YOLOV8_V2]: ".onnx",
[BASE_MODELS.YOLOV11]: ".onnx",
[BASE_MODELS.YOLOV11_SAM]: ".onnx",
};

/**
Expand Down Expand Up @@ -490,6 +492,8 @@ export const FAIR_BASE_MODELS_PATH: Record<BASE_MODELS, string> = {
[BASE_MODELS.RAMP]: `${FAIR_MODELS_BASE_PATH}/basemodels/ramp/baseline.tflite`,
[BASE_MODELS.YOLOV8_V1]: `${FAIR_MODELS_BASE_PATH}/basemodels/yolo/yolov8s_v1-seg.onnx`,
[BASE_MODELS.YOLOV8_V2]: `${FAIR_MODELS_BASE_PATH}/basemodels/yolo/yolov8s_v2-seg.onnx`,
[BASE_MODELS.YOLOV11]: `${FAIR_MODELS_BASE_PATH}/basemodels/yolo/yolov11-seg.onnx`,
[BASE_MODELS.YOLOV11_SAM]: `${FAIR_MODELS_BASE_PATH}/basemodels/yolo/yolov11-seg.onnx`,
};

export const OPENAERIALMAP_MOSAIC_TILES_URL =
Expand Down
6 changes: 6 additions & 0 deletions frontend/src/constants/ui-contents/models-content.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ export const MODELS_CONTENT: TModelsContent = {
"A well-balanced model offering good accuracy for detecting structures in major areas. Trained by the community.",
[BASE_MODELS.YOLOV8_V2]:
"Our most advanced model. Designed for detecting various features across different areas. Developed in collaboration with Omdena AI.",
[BASE_MODELS.YOLOV11]:
"YOLO11 is the latest iteration in the Ultralytics YOLO series of real-time object detectors, redefining what's possible with cutting-edge accuracy, speed, and efficiency.",
[BASE_MODELS.YOLOV11_SAM]:
"You can pair YOLO11 with SAM2 for segmentation within detected bounding boxes, enabling precise downstream tasks",
},
},
modelDescription: {
Expand Down Expand Up @@ -266,6 +270,8 @@ export const MODELS_CONTENT: TModelsContent = {
RAMP: "https://rampml.global/",
YOLO_V8_V2: "https://yolov8.com/ ",
YOLO_V8_V1: "https://yolov8.com/ ",
YOLO_V11: "https://yolov11.com/",
YOLO_V11_SAM: "https://blog.roboflow.com/train-yolov11-instance-segmentation/",
},
},
sourceImage: {
Expand Down
2 changes: 2 additions & 0 deletions frontend/src/enums/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ export enum BASE_MODELS {
RAMP = "RAMP",
YOLOV8_V1 = "YOLO_V8_V1",
YOLOV8_V2 = "YOLO_V8_V2",
YOLOV11 = "YOLO_V11",
YOLOV11_SAM = "YOLO_V11_SAM",
}

export enum ButtonVariant {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,22 @@ const baseModelOptions = [
BASE_MODELS.YOLOV8_V2
],
},
{
name: BASE_MODELS.YOLOV11,
value: BASE_MODELS.YOLOV11,
suffix:
MODELS_CONTENT.modelCreation.modelDetails.form.baseModel.suffixes[
BASE_MODELS.YOLOV11
],
},
{
name: BASE_MODELS.YOLOV11_SAM,
value: BASE_MODELS.YOLOV11_SAM,
suffix:
MODELS_CONTENT.modelCreation.modelDetails.form.baseModel.suffixes[
BASE_MODELS.YOLOV11_SAM
],
},
];

const ModelDetailsForm = () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,22 @@ export const ModelSelector = ({
PredictionModel.YOLOV8_V2
],
},
{
value: PredictionModel.YOLOV11,
label: "YOLO v11",
tooltip:
MODELS_CONTENT.modelCreation.modelDetails.form.baseModel.suffixes[
PredictionModel.YOLOV11
],
},
{
value: PredictionModel.YOLOV11_SAM,
label: "YOLO v11+SAM",
tooltip:
MODELS_CONTENT.modelCreation.modelDetails.form.baseModel.suffixes[
PredictionModel.YOLOV11_SAM
],
},
{
value: PredictionModel.CUSTOM,
label: "Custom",
Expand All @@ -92,6 +108,10 @@ export const ModelSelector = ({
FAIR_BASE_MODELS_PATH[PredictionModel.YOLOV8_V1],
[PredictionModel.YOLOV8_V2]:
FAIR_BASE_MODELS_PATH[PredictionModel.YOLOV8_V2],
[PredictionModel.YOLOV11]:
FAIR_BASE_MODELS_PATH[PredictionModel.YOLOV11],
[PredictionModel.YOLOV11_SAM]:
FAIR_BASE_MODELS_PATH[PredictionModel.YOLOV11_SAM],
[PredictionModel.CUSTOM]: predictionModelCheckpoint,
}),
[predictionModelCheckpoint, modelInfo, predictionModel],
Expand Down
2 changes: 2 additions & 0 deletions frontend/src/types/ui-contents.ts
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,8 @@ export type TModelsContent = {
RAMP: string;
YOLO_V8_V2: string;
YOLO_V8_V1: string;
YOLO_V11: string;
YOLO_V11_SAM: string;
};
};
sourceImage: {
Expand Down
Loading