Zum Inhalt springen

YOLOE: Echtzeit-Objekterkennung für alles

Einführung

YOLOE Prompting-Optionen

YOLOE (Real-Time Seeing Anything) ist eine neue Weiterentwicklung im Bereich der Zero-Shot, promptfähigen YOLO-Modelle, die für die Open-Vocabulary-Detektion und -Segmentierung entwickelt wurden. Im Gegensatz zu früheren YOLO-Modellen, die auf feste Kategorien beschränkt waren, verwendet YOLOE Text-, Bild- oder interne Vokabular-Prompts, die eine Echtzeit-Detektion jeder Objektklasse ermöglichen. Basierend auf YOLOv10 und inspiriert von YOLO-World, erreicht YOLOE eine State-of-the-Art Zero-Shot Performance mit minimalen Auswirkungen auf Geschwindigkeit und Genauigkeit.



Ansehen: Wie man YOLOE mit dem Ultralytics Python-Paket verwendet: Open Vocabulary & Real-Time Seeing Anything 🚀

Im Vergleich zu früheren YOLO-Modellen steigert YOLOE die Effizienz und Genauigkeit erheblich. Es verbessert sich um +3.5 AP gegenüber YOLO-Worldv2 auf LVIS, während es nur ein Drittel der Trainingsressourcen nutzt und 1.4× schnellere Inferenzgeschwindigkeiten erreicht. Feinabgestimmt auf COCO, übertrifft YOLOE-v8-large YOLOv8-L um 0.1 mAP, bei fast 4× weniger Trainingszeit. Dies zeigt YLOEs außergewöhnliches Gleichgewicht aus Genauigkeit, Effizienz und Vielseitigkeit. Die folgenden Abschnitte untersuchen die Architektur von YOLOE, Benchmark-Vergleiche und die Integration in das Ultralytics-Framework.

Architektur-Überblick

YOLOE Architektur

YOLOE behält die Standard-YOLO-Struktur bei: ein konvolutionelles Backbone (z. B. CSP-Darknet) zur Merkmalsextraktion, ein Neck (z. B. PAN-FPN) zur multiskaligen Fusion und ein ankerfreier, entkoppelter Erkennungs-Head (wie in YOLOv8/YOLO11), der Objektivität, Klassen und Boxen unabhängig voneinander vorhersagt. YOLOE führt drei neuartige Module ein, die die Erkennung mit offenem Vokabular ermöglichen:

  • Re-parameterizable Region-Text Alignment (RepRTA): Unterstützt die textgesteuerte Erkennung, indem Text-Einbettungen (z. B. von CLIP) über ein kleines Hilfsnetzwerk verfeinert werden. Bei der Inferenz wird dieses Netzwerk in das Hauptmodell eingefaltet, wodurch ein Overhead von Null gewährleistet wird. YOLOE erkennt somit beliebige textbeschriftete Objekte (z. B. ungesehenes "Verkehrslicht") ohne Laufzeitbeeinträchtigungen.

  • Semantic-Activated Visual Prompt Encoder (SAVPE): Ermöglicht visuell-gesteuerte Detektion mittels eines leichtgewichtigen Embedding-Zweigs. Anhand eines Referenzbildes kodiert SAVPE semantische und Aktivierungsmerkmale, wodurch das Modell konditioniert wird, visuell ähnliche Objekte zu detect – eine One-Shot-Detektionsfähigkeit, die für Logos oder spezifische Teile nützlich ist.

  • Lazy Region-Prompt Contrast (LRPC): Im Prompt-freien Modus führt YOLOE eine Open-Set-Erkennung mithilfe interner Einbettungen durch, die auf großen Vokabularen trainiert wurden (1200+ Kategorien von LVIS und Objects365). Ohne externe Prompts oder Encoder identifiziert YOLOE Objekte über die Ähnlichkeit der Einbettungen und verarbeitet so effizient große Label-Räume bei der Inferenz.

Zusätzlich integriert YOLOE Echtzeit-Instanzsegmentierung, indem der Erkennungskopf um einen Masken-Vorhersagezweig erweitert wird (ähnlich wie bei YOLACT oder YOLOv8-Seg), wodurch nur minimaler Overhead entsteht.

Entscheidend ist, dass die Open-World-Module von YOLOE keine Inferenzkosten verursachen, wenn sie als reguläres Closed-Set-YOLO verwendet werden. Nach dem Training können YOLOE-Parameter in einen Standard-YOLO-Head reparametrisiert werden, wodurch identische FLOPs und Geschwindigkeit erhalten bleiben (z. B. genau übereinstimmend mit YOLO11).

Verfügbare Modelle, unterstützte Aufgaben und Betriebsmodi

Dieser Abschnitt beschreibt die verfügbaren Modelle mit ihren spezifischen vortrainierten Gewichten, die von ihnen unterstützten Aufgaben und ihre Kompatibilität mit verschiedenen Betriebsmodi wie Inferenz, Validierung, Training und Export, gekennzeichnet durch ✅ für unterstützte Modi und ❌ für nicht unterstützte Modi.

Text/Visual Prompt Modelle

ModelltypVortrainierte GewichteUnterstützte AufgabenInferenzValidierungTrainingExport
YOLOE-11Syoloe-11s-seg.ptInstanzsegmentierung
YOLOE-11Myoloe-11m-seg.ptInstanzsegmentierung
YOLOE-11Lyoloe-11l-seg.ptInstanzsegmentierung
YOLOE-v8Syoloe-v8s-seg.ptInstanzsegmentierung
YOLOE-v8Myoloe-v8m-seg.ptInstanzsegmentierung
YOLOE-v8Lyoloe-v8l-seg.ptInstanzsegmentierung

Prompt-freie Modelle

ModelltypVortrainierte GewichteUnterstützte AufgabenInferenzValidierungTrainingExport
YOLOE-11S-PFyoloe-11s-seg-pf.ptInstanzsegmentierung
YOLOE-11M-PFyoloe-11m-seg-pf.ptInstanzsegmentierung
YOLOE-11L-PFyoloe-11l-seg-pf.ptInstanzsegmentierung
YOLOE-v8S-PFyoloe-v8s-seg-pf.ptInstanzsegmentierung
YOLOE-v8M-PFyoloe-v8m-seg-pf.ptInstanzsegmentierung
YOLOE-v8L-PFyoloe-v8l-seg-pf.ptInstanzsegmentierung

Anwendungsbeispiele

Die YOLOE-Modelle lassen sich einfach in Ihre Python-Anwendungen integrieren. Ultralytics bietet benutzerfreundliche Python APIs und CLI-Befehle, um die Entwicklung zu optimieren.

Trainingsanwendung

Feinabstimmung auf einem benutzerdefinierten Datensatz

Sie können jedes vorab trainierte YOLOE-Modell auf Ihrem benutzerdefinierten YOLO-Datensatz sowohl für Erkennungs- als auch für Instanzsegmentierungsaufgaben feinabstimmen.



Ansehen: Wie man YOLOE auf dem Datensatz für die Segmentierung von Autoteilen trainiert | Open-Vocabulary-Modell, Vorhersage & Export 🚀

Beispiel

Instanzsegmentierung

Die Feinabstimmung eines vortrainierten YOLOE-Checkpoints folgt im Wesentlichen dem Standard-YOLO-TrainingsverfahrenDer Hauptunterschied besteht in der expliziten Übergabe von YOLOEPESegTrainer als trainer Parameter auf model.train():

from ultralytics import YOLOE
from ultralytics.models.yolo.yoloe import YOLOEPESegTrainer

model = YOLOE("yoloe-11s-seg.pt")

# Fine-tune on your segmentation dataset
results = model.train(
    data="coco128-seg.yaml",  # Segmentation dataset
    epochs=80,
    patience=10,
    trainer=YOLOEPESegTrainer,  # <- Important: use segmentation trainer
)

Objekterkennung

Alle vortrainierten YOLOE-Modelle führen standardmäßig eine Instanzsegmentierung durch. Um diese vortrainierten Checkpoints für das Training eines Erkennungsmodells zu verwenden, initialisieren Sie ein Erkennungsmodell von Grund auf mit der YAML-Konfiguration und laden Sie dann den vortrainierten Segmentierungs-Checkpoint der gleichen Skala. Beachten Sie, dass wir YOLOEPETrainer anstelle von YOLOEPESegTrainer verwenden, da wir ein Erkennungsmodell trainieren:

from ultralytics import YOLOE
from ultralytics.models.yolo.yoloe import YOLOEPETrainer

# Initialize a detection model from a config
model = YOLOE("yoloe-11s.yaml")

# Load weights from a pretrained segmentation checkpoint (same scale)
model.load("yoloe-11s-seg.pt")

# Fine-tune on your detection dataset
results = model.train(
    data="coco128.yaml",  # Detection dataset
    epochs=80,
    patience=10,
    trainer=YOLOEPETrainer,  # <- Important: use detection trainer
)

Lineares Sondieren (Linear Probing) optimiert nur den Klassifizierungszweig und friert den Rest des Modells ein. Dieser Ansatz ist nützlich, wenn mit begrenzten Daten gearbeitet wird, da er eine Überanpassung verhindert, indem er zuvor gelernte Merkmale nutzt und nur den Klassifizierungskopf anpasst.

Instanzsegmentierung

from ultralytics import YOLOE
from ultralytics.models.yolo.yoloe import YOLOEPESegTrainer

# Load a pretrained segmentation model
model = YOLOE("yoloe-11s-seg.pt")

# Identify the head layer index
head_index = len(model.model.model) - 1

# Freeze all backbone and neck layers (i.e., everything before the head)
freeze = [str(i) for i in range(0, head_index)]

# Freeze parts of the segmentation head, keeping only the classification branch trainable
for name, child in model.model.model[-1].named_children():
    if "cv3" not in name:
        freeze.append(f"{head_index}.{name}")

# Freeze detection branch components
freeze.extend(
    [
        f"{head_index}.cv3.0.0",
        f"{head_index}.cv3.0.1",
        f"{head_index}.cv3.1.0",
        f"{head_index}.cv3.1.1",
        f"{head_index}.cv3.2.0",
        f"{head_index}.cv3.2.1",
    ]
)

# Train only the classification branch
results = model.train(
    data="coco128-seg.yaml",  # Segmentation dataset
    epochs=80,
    patience=10,
    trainer=YOLOEPESegTrainer,  # <- Important: use segmentation trainer
    freeze=freeze,
)

Objekterkennung

Für die Objekterkennungsaufgabe ist der Trainingsprozess fast identisch mit dem obigen Beispiel zur Instanzsegmentierung, aber wir verwenden YOLOEPETrainer anstelle von YOLOEPESegTrainerund initialisieren das Objekterkennungsmodell mit dem YAML und laden dann die Gewichte aus dem vortrainierten Instanzsegmentierungs-Checkpoint.

from ultralytics import YOLOE
from ultralytics.models.yolo.yoloe import YOLOEPETrainer

# Initialize a detection model from a config
model = YOLOE("yoloe-11s.yaml")

# Load weights from a pretrained segmentation checkpoint (same scale)
model.load("yoloe-11s-seg.pt")

# Identify the head layer index
head_index = len(model.model.model) - 1

# Freeze all backbone and neck layers (i.e., everything before the head)
freeze = [str(i) for i in range(0, head_index)]

# Freeze parts of the segmentation head, keeping only the classification branch trainable
for name, child in model.model.model[-1].named_children():
    if "cv3" not in name:
        freeze.append(f"{head_index}.{name}")

# Freeze detection branch components
freeze.extend(
    [
        f"{head_index}.cv3.0.0",
        f"{head_index}.cv3.0.1",
        f"{head_index}.cv3.1.0",
        f"{head_index}.cv3.1.1",
        f"{head_index}.cv3.2.0",
        f"{head_index}.cv3.2.1",
    ]
)

# Train only the classification branch
results = model.train(
    data="coco128.yaml",  # Detection dataset
    epochs=80,
    patience=10,
    trainer=YOLOEPETrainer,  # <- Important: use detection trainer
    freeze=freeze,
)

Vorhersageanwendung

YOLOE unterstützt sowohl textbasierte als auch visuelle Prompts. Die Verwendung von Prompts ist unkompliziert—einfach durch die predict Methode, wie unten gezeigt, verwenden:

Beispiel

Textaufforderungen ermöglichen es Ihnen, die Klassen zu spezifizieren, die Sie durch textuelle Beschreibungen detect möchten. Der folgende Code zeigt, wie Sie YOLOE verwenden können, um Personen und Busse in einem Bild zu detect:

from ultralytics import YOLOE

# Initialize a YOLOE model
model = YOLOE("yoloe-11l-seg.pt")  # or select yoloe-11s/m-seg.pt for different sizes

# Set text prompt to detect person and bus. You only need to do this once after you load the model.
names = ["person", "bus"]
model.set_classes(names, model.get_text_pe(names))

# Run detection on the given image
results = model.predict("path/to/image.jpg")

# Show results
results[0].show()

Visuelle Prompts ermöglichen es Ihnen, das Modell zu steuern, indem Sie ihm visuelle Beispiele der Zielklassen zeigen, anstatt sie im Text zu beschreiben.

Die visual_prompts Argument ein Dictionary mit zwei Schlüsseln entgegen: bboxes und cls. Jedes Begrenzungsfeld in bboxes sollte ein Beispiel des Objekts, das das Modell detecten soll, und den entsprechenden Eintrag in cls gibt die Klassenbezeichnung für diese Box an. Diese Paarung teilt dem Modell mit: „So sieht Klasse X aus—finde nun mehr davon.“

Klassen-IDs (cls) in visual_prompts werden verwendet, um jede Bounding Box mit einer bestimmten Kategorie innerhalb Ihres Prompts zu verknüpfen. Es handelt sich nicht um feste Labels, sondern um temporäre Kennungen, die Sie jedem Beispiel zuweisen. Die einzige Voraussetzung ist, dass die Klassen-IDs fortlaufend sein müssen und bei 0 beginnen. Dies hilft dem Modell, jede Box korrekt mit der entsprechenden Klasse zu verknüpfen.

Sie können visuelle Prompts direkt innerhalb desselben Bildes bereitstellen, auf dem Sie eine Inferenz ausführen möchten. Zum Beispiel:

import numpy as np

from ultralytics import YOLOE
from ultralytics.models.yolo.yoloe import YOLOEVPSegPredictor

# Initialize a YOLOE model
model = YOLOE("yoloe-11l-seg.pt")

# Define visual prompts using bounding boxes and their corresponding class IDs.
# Each box highlights an example of the object you want the model to detect.
visual_prompts = dict(
    bboxes=np.array(
        [
            [221.52, 405.8, 344.98, 857.54],  # Box enclosing person
            [120, 425, 160, 445],  # Box enclosing glasses
        ],
    ),
    cls=np.array(
        [
            0,  # ID to be assigned for person
            1,  # ID to be assigned for glassses
        ]
    ),
)

# Run inference on an image, using the provided visual prompts as guidance
results = model.predict(
    "ultralytics/assets/bus.jpg",
    visual_prompts=visual_prompts,
    predictor=YOLOEVPSegPredictor,
)

# Show results
results[0].show()

Oder Sie können Beispiele aus einem separaten Referenzbild mit der refer_image Argument. In diesem Fall wird der bboxes und cls in visual_prompts sollte Objekte im Referenzbild beschreiben, nicht das Zielbild, auf dem Sie Vorhersagen treffen:

Hinweis

Wenn source ist ein Video oder Stream, verwendet das Modell automatisch den ersten Frame als refer_imageDas bedeutet Ihre visual_prompts werden auf diesen ersten Frame angewendet, um dem Modell zu helfen, zu verstehen, wonach es im Rest des Videos suchen soll. Alternativ können Sie jeden beliebigen Frame explizit als refer_image um zu steuern, welche visuellen Beispiele das Modell als Referenz verwendet.

import numpy as np

from ultralytics import YOLOE
from ultralytics.models.yolo.yoloe import YOLOEVPSegPredictor

# Initialize a YOLOE model
model = YOLOE("yoloe-11l-seg.pt")

# Define visual prompts based on a separate reference image
visual_prompts = dict(
    bboxes=np.array([[221.52, 405.8, 344.98, 857.54]]),  # Box enclosing person
    cls=np.array([0]),  # ID to be assigned for person
)

# Run prediction on a different image, using reference image to guide what to look for
results = model.predict(
    "ultralytics/assets/zidane.jpg",  # Target image for detection
    refer_image="ultralytics/assets/bus.jpg",  # Reference image used to get visual prompts
    visual_prompts=visual_prompts,
    predictor=YOLOEVPSegPredictor,
)

# Show results
results[0].show()

Verwendung von refer_image legt die Klassen auch dauerhaft fest, sodass Sie Vorhersagen ausführen können, ohne dieselben visuellen Prompts erneut bereitstellen zu müssen, und das Modell exportieren können, während die Fähigkeit erhalten bleibt, dieselben Klassen nach dem Export weiterhin zu detecten:

# After making prediction with `refer_image`, you can run predictions without passing visual_prompts again and still get the same classes back
results = model("ultralytics/assets/bus.jpg")

# Or export it to a different format while retaining the classes
model.export(format="onnx")

Sie können auch mehrere Zielbilder übergeben, um eine Vorhersage auszuführen:

import numpy as np

from ultralytics import YOLOE
from ultralytics.models.yolo.yoloe import YOLOEVPSegPredictor

# Initialize a YOLOE model
model = YOLOE("yoloe-11l-seg.pt")

# Define visual prompts using bounding boxes and their corresponding class IDs.
# Each box highlights an example of the object you want the model to detect.
visual_prompts = dict(
    bboxes=[
        np.array(
            [
                [221.52, 405.8, 344.98, 857.54],  # Box enclosing person
                [120, 425, 160, 445],  # Box enclosing glasses
            ],
        ),
        np.array([[150, 200, 1150, 700]]),
    ],
    cls=[
        np.array(
            [
                0,  # ID to be assigned for person
                1,  # ID to be assigned for glasses
            ]
        ),
        np.array([0]),
    ],
)

# Run inference on multiple image, using the provided visual prompts as guidance
results = model.predict(
    ["ultralytics/assets/bus.jpg", "ultralytics/assets/zidane.jpg"],
    visual_prompts=visual_prompts,
    predictor=YOLOEVPSegPredictor,
)

# Show results
results[0].show()

YOLOE umfasst auch prompt-freie Varianten, die mit einem eingebauten Vokabular ausgestattet sind. Diese Modelle benötigen keine Prompts und funktionieren wie traditionelle YOLO-Modelle. Anstatt sich auf benutzerdefinierte Labels oder visuelle Beispiele zu verlassen, detect sie Objekte aus einer vordefinierten Liste von 4.585 Klassen, basierend auf dem Tag-Set, das vom Recognize Anything Model Plus (RAM++) verwendet wird.

from ultralytics import YOLOE

# Initialize a YOLOE model
model = YOLOE("yoloe-11l-seg-pf.pt")

# Run prediction. No prompts required.
results = model.predict("path/to/image.jpg")

# Show results
results[0].show()

Val-Anwendung

Die Modellvalidierung auf einem Datensatz wird wie folgt optimiert:

Beispiel

from ultralytics import YOLOE

# Create a YOLOE model
model = YOLOE("yoloe-11l-seg.pt")  # or select yoloe-11s/m-seg.pt for different sizes

# Conduct model validation on the COCO128-seg example dataset
metrics = model.val(data="coco128-seg.yaml")

Standardmäßig werden die visuellen Einbettungen für jede Kategorie aus dem bereitgestellten Datensatz extrahiert.

from ultralytics import YOLOE

# Create a YOLOE model
model = YOLOE("yoloe-11l-seg.pt")  # or select yoloe-11s/m-seg.pt for different sizes

# Conduct model validation on the COCO128-seg example dataset
metrics = model.val(data="coco128-seg.yaml", load_vp=True)

Alternativ könnten wir ein anderes Dataset als Referenz-Dataset verwenden, um visuelle Einbettungen für jede Kategorie zu extrahieren. Beachten Sie, dass dieses Referenz-Dataset genau die gleichen Kategorien wie das bereitgestellte Dataset haben sollte.

from ultralytics import YOLOE

# Create a YOLOE model
model = YOLOE("yoloe-11l-seg.pt")  # or select yoloe-11s/m-seg.pt for different sizes

# Conduct model validation on the COCO128-seg example dataset
metrics = model.val(data="coco128-seg.yaml", load_vp=True, refer_data="coco.yaml")
from ultralytics import YOLOE

# Create a YOLOE model
model = YOLOE("yoloe-11l-seg-pf.pt")  # or select yoloe-11s/m-seg-pf.pt for different sizes

# Conduct model validation on the COCO128-seg example dataset
metrics = model.val(data="coco128-seg.yaml", single_cls=True)

Export-Nutzung

Der Exportprozess ähnelt dem anderer YOLO-Modelle, bietet aber zusätzlich die Flexibilität, Text- und visuelle Prompts zu verarbeiten:

Beispiel

from ultralytics import YOLOE

# Select yoloe-11s/m-seg.pt for different sizes
model = YOLOE("yoloe-11l-seg.pt")

# Configure the set_classes() before exporting the model
names = ["person", "bus"]
model.set_classes(names, model.get_text_pe(names))

export_model = model.export(format="onnx")
model = YOLOE(export_model)

# Run detection on the given image
results = model.predict("path/to/image.jpg")

# Show results
results[0].show()

Offizielle Modelle trainieren

Datensätze vorbereiten

Hinweis

Das Training offizieller YOLOE-Modelle erfordert Segmentierungs-Annotationen für die Trainingsdaten. Hier ist das von dem offiziellen Team bereitgestellte Skript das Datensätze in segment-Annotationen umwandelt, unterstützt durch SAM2.1 Modelle. Oder Sie können die bereitgestellte Datei direkt herunterladen Processed Segment Annotations in der folgenden Tabelle, die vom offiziellen Team bereitgestellt wird.

  • Trainingsdaten
DatensatzTypStichprobenBoxenRohe Detektions-AnnotationenVerarbeitete Segment-Annotationen
Objects365v1Erkennung609k9621kobjects365_train.jsonobjects365_train_segm.json
GQAGrounding621k3681kfinal_mixed_train_no_coco.jsonfinal_mixed_train_no_coco_segm.json
Flickr30kGrounding149k641kfinal_flickr_separateGT_train.jsonfinal_flickr_separateGT_train_segm.json
  • Val-Daten
DatensatzTypAnmerkungsdateien
LVIS minivalErkennungminival.txt

Training von Grund auf starten

Hinweis

Visual Prompt Modelle werden basierend auf gut trainierten Modellen feinabgestimmt Text Prompt Modelle.

Beispiel

from ultralytics import YOLOE
from ultralytics.models.yolo.yoloe import YOLOESegTrainerFromScratch

data = dict(
    train=dict(
        yolo_data=["Objects365.yaml"],
        grounding_data=[
            dict(
                img_path="flickr/full_images/",
                json_file="flickr/annotations/final_flickr_separateGT_train_segm.json",
            ),
            dict(
                img_path="mixed_grounding/gqa/images",
                json_file="mixed_grounding/annotations/final_mixed_train_no_coco_segm.json",
            ),
        ],
    ),
    val=dict(yolo_data=["lvis.yaml"]),
)

model = YOLOE("yoloe-11l-seg.yaml")
model.train(
    data=data,
    batch=128,
    epochs=30,
    close_mosaic=2,
    optimizer="AdamW",
    lr0=2e-3,
    warmup_bias_lr=0.0,
    weight_decay=0.025,
    momentum=0.9,
    workers=4,
    trainer=YOLOESegTrainerFromScratch,
    device="0,1,2,3,4,5,6,7",
)

Da nur die SAVPE Modul muss während des Trainings aktualisiert werden. Konvertierung eines gut trainierten Text-Prompt-Modells in ein Erkennungsmodell und Übernahme einer Erkennungs-Pipeline mit geringeren Trainingskosten. Beachten Sie, dass dieser Schritt optional ist, Sie können auch direkt mit der Segmentierung beginnen.

from ultralytics import YOLOE
from ultralytics.utils.patches import torch_load

det_model = YOLOE("yoloe-11l.yaml")
state = torch_load("yoloe-11l-seg.pt")
det_model.load(state["model"])
det_model.save("yoloe-11l-seg-det.pt")

Training starten:

from ultralytics import YOLOE
from ultralytics.models.yolo.yoloe import YOLOESegVPTrainer

data = dict(
    train=dict(
        yolo_data=["Objects365.yaml"],
        grounding_data=[
            dict(
                img_path="flickr/full_images/",
                json_file="flickr/annotations/final_flickr_separateGT_train_segm.json",
            ),
            dict(
                img_path="mixed_grounding/gqa/images",
                json_file="mixed_grounding/annotations/final_mixed_train_no_coco_segm.json",
            ),
        ],
    ),
    val=dict(yolo_data=["lvis.yaml"]),
)

model = YOLOE("yoloe-11l-seg.pt")
# replace to yoloe-11l-seg-det.pt if converted to detection model
# model = YOLOE("yoloe-11l-seg-det.pt")

# freeze every layer except of the savpe module.
head_index = len(model.model.model) - 1
freeze = list(range(0, head_index))
for name, child in model.model.model[-1].named_children():
    if "savpe" not in name:
        freeze.append(f"{head_index}.{name}")

model.train(
    data=data,
    batch=128,
    epochs=2,
    close_mosaic=2,
    optimizer="AdamW",
    lr0=16e-3,
    warmup_bias_lr=0.0,
    weight_decay=0.025,
    momentum=0.9,
    workers=4,
    trainer=YOLOESegVPTrainer,  # use YOLOEVPTrainer if converted to detection model
    device="0,1,2,3,4,5,6,7",
    freeze=freeze,
)

Nach dem Training zurück zum Segmentierungsmodell konvertieren. Nur erforderlich, wenn Sie das Segmentierungsmodell vor dem Training in ein Erkennungsmodell konvertiert haben.

from copy import deepcopy

from ultralytics import YOLOE

model = YOLOE("yoloe-11l-seg.yaml")
model.load("yoloe-11l-seg.pt")

vp_model = YOLOE("yoloe-11l-vp.pt")
model.model.model[-1].savpe = deepcopy(vp_model.model.model[-1].savpe)
model.eval()
model.save("yoloe-11l-seg.pt")

Ähnlich wie beim visuellen Prompt-Training muss für das Prompt-freie Modell nur das spezialisierte Prompt-Embedding während des Trainings aktualisiert werden. Konvertierung eines gut trainierten Text-Prompt-Modells in ein Erkennungsmodell und Übernahme der Erkennungs-Pipeline mit geringeren Trainingskosten. Beachten Sie, dass dieser Schritt optional ist, Sie können auch direkt mit der Segmentierung beginnen.

from ultralytics import YOLOE
from ultralytics.utils.patches import torch_load

det_model = YOLOE("yoloe-11l.yaml")
state = torch_load("yoloe-11l-seg.pt")
det_model.load(state["model"])
det_model.save("yoloe-11l-seg-det.pt")
Training starten:
from ultralytics import YOLOE

data = dict(
    train=dict(
        yolo_data=["Objects365.yaml"],
        grounding_data=[
            dict(
                img_path="flickr/full_images/",
                json_file="flickr/annotations/final_flickr_separateGT_train_segm.json",
            ),
            dict(
                img_path="mixed_grounding/gqa/images",
                json_file="mixed_grounding/annotations/final_mixed_train_no_coco_segm.json",
            ),
        ],
    ),
    val=dict(yolo_data=["lvis.yaml"]),
)

model = YOLOE("yoloe-11l-seg.pt")
# replace to yoloe-11l-seg-det.pt if converted to detection model
# model = YOLOE("yoloe-11l-seg-det.pt")

# freeze layers.
head_index = len(model.model.model) - 1
freeze = [str(f) for f in range(0, head_index)]
for name, child in model.model.model[-1].named_children():
    if "cv3" not in name:
        freeze.append(f"{head_index}.{name}")

freeze.extend(
    [
        f"{head_index}.cv3.0.0",
        f"{head_index}.cv3.0.1",
        f"{head_index}.cv3.1.0",
        f"{head_index}.cv3.1.1",
        f"{head_index}.cv3.2.0",
        f"{head_index}.cv3.2.1",
    ]
)

model.train(
    data=data,
    batch=128,
    epochs=1,
    close_mosaic=1,
    optimizer="AdamW",
    lr0=2e-3,
    warmup_bias_lr=0.0,
    weight_decay=0.025,
    momentum=0.9,
    workers=4,
    trainer=YOLOEPEFreeTrainer,
    device="0,1,2,3,4,5,6,7",
    freeze=freeze,
    single_cls=True,  # this is needed
)

Nach dem Training zurück zum Segmentierungsmodell konvertieren. Nur erforderlich, wenn Sie das Segmentierungsmodell vor dem Training in ein Erkennungsmodell konvertiert haben.

from copy import deepcopy

from ultralytics import YOLOE

model = YOLOE("yoloe-11l-seg.pt")
model.eval()

pf_model = YOLOE("yoloe-11l-seg-pf.pt")
names = ["object"]
tpe = model.get_text_pe(names)
model.set_classes(names, tpe)
model.model.model[-1].fuse(model.model.pe)

model.model.model[-1].cv3[0][2] = deepcopy(pf_model.model.model[-1].cv3[0][2]).requires_grad_(True)
model.model.model[-1].cv3[1][2] = deepcopy(pf_model.model.model[-1].cv3[1][2]).requires_grad_(True)
model.model.model[-1].cv3[2][2] = deepcopy(pf_model.model.model[-1].cv3[2][2]).requires_grad_(True)
del model.model.pe
model.save("yoloe-11l-seg-pf.pt")

YOLOE Performancevergleich

YOLOE erreicht oder übertrifft die Genauigkeit von Closed-Set YOLO-Modellen auf Standard-Benchmarks wie COCO, ohne dabei Geschwindigkeit oder Modellgröße zu beeinträchtigen. Die folgende Tabelle vergleicht YOLOE-L (basierend auf YOLO11) mit entsprechenden YOLOv8- und YOLO11-Modellen:

ModellCOCO mAP50-95Inferenzgeschwindigkeit (T4)ParameterGFLOPs (640px)
YOLOv8-L (Closed-Set)52.9%9.06 ms (110 FPS)43.7 M165.2 B
YOLO11-L (Closed-Set)53.5%6.2 ms (130 FPS)26.2 M86.9 B
YOLOE-L (Open-Vocab)52.6%6.2 ms (130 FPS)26.2 M86.9 B

YOLO11-L und YOLOE-L verfügen über identische Architekturen (Prompt-Module in YOLO11-L deaktiviert), was zu einer identischen Inferenzgeschwindigkeit und ähnlichen GFLOPs-Schätzungen führt.

YOLOE-L erreicht 52,6 % mAP und übertrifft YOLOv8-L (52,9 %) mit etwa 40 % weniger Parametern (26M vs. 43,7M). Es verarbeitet 640×640 Bilder in 6,2 ms (161 FPS) im Vergleich zu YOLOv8-L's 9,06 ms (110 FPS), was die Effizienz von YOLO11 unterstreicht. Entscheidend ist, dass die Open-Vocabulary-Module von YOLOE keine Inferenzkosten verursachen, was ein „No Free Lunch Trade-off“-Design demonstriert.

Bei Zero-Shot- und Transfer-Aufgaben zeichnet sich YOLOE aus: Auf LVIS verbessert sich YOLOE-small gegenüber YOLO-Worldv2 um +3.5 AP bei Verwendung von 3-mal weniger Trainingsressourcen. Das Fine-Tuning von YOLOE-L von LVIS auf COCO erforderte zudem 4-mal weniger Trainingszeit als YOLOv8-L, was seine Effizienz und Anpassungsfähigkeit unterstreicht. YOLOE behält zudem die charakteristische Geschwindigkeit von YOLO bei und erreicht über 300 FPS auf einer T4 GPU und ~64 FPS auf dem iPhone 12 via CoreML, ideal für Edge- und mobile Bereitstellungen.

Hinweis

Benchmark-Bedingungen: Die YOLOE-Ergebnisse stammen von Modellen, die auf Objects365, GoldG und LVIS vortrainiert und anschließend auf COCO feinabgestimmt oder evaluiert wurden. Der leichte mAP-Vorteil von YOLOE gegenüber YOLOv8 resultiert aus dem umfangreichen Vortraining. Ohne dieses Open-Vocab-Training erreicht YOLOE die Leistung ähnlich großer YOLO-Modelle und bestätigt seine SOTA-Genauigkeit und Open-World-Flexibilität ohne Leistungseinbußen.

Vergleich mit früheren Modellen

YOLOE führt bemerkenswerte Fortschritte gegenüber früheren YOLO-Modellen und Open-Vocabulary-Detektoren ein:

  • YOLOE vs. YOLOv5:YOLOv5 bot ein gutes Gleichgewicht zwischen Geschwindigkeit und Genauigkeit, erforderte jedoch ein Nachtraining für neue Klassen und verwendete ankerbasierte Heads. Im Gegensatz dazu ist YOLOE ankerfrei und erkennt neue Klassen dynamisch. YOLOE, das auf den Verbesserungen von YOLOv8 aufbaut, erreicht eine höhere Genauigkeit (52,6 % vs. YOLOv5s ~50 % mAP auf COCO) und integriert im Gegensatz zu YOLOv5 die Instanzsegmentierung.

  • YOLOE vs. YOLOv8: YOLOE erweitert die überarbeitete Architektur von YOLOv8 und erreicht eine ähnliche oder überlegene Genauigkeit (52,6 % mAP mit ~26 Mio. Parametern vs. YOLOv8-Ls 52,9 % mit ~44 Mio. Parametern). Es reduziert die Trainingszeit aufgrund eines stärkeren Vortrainings erheblich. Die entscheidende Weiterentwicklung ist die Open-World-Fähigkeit von YOLOE, die ungesehene Objekte (z. B. „bird scooter“ oder „peace symbol“) über Prompts erkennt, im Gegensatz zum Closed-Set-Design von YOLOv8.

  • YOLOE vs. YOLO11:YOLO11 verbessert YOLOv8 durch erhöhte Effizienz und weniger Parameter (ca. 22 % Reduktion). YOLOE übernimmt diese Vorteile direkt, erreicht die Inferenzgeschwindigkeit und Parameteranzahl von YOLO11 (ca. 26 Mio. Parameter) und fügt gleichzeitig Open-Vocabulary-Detektion und -Segmentierung hinzu. In Closed-Set-Szenarien ist YOLOE äquivalent zu YOLO11, bietet aber entscheidend die Anpassungsfähigkeit, ungesehene Klassen zu detect, wodurch YOLO11 + Open-World-Fähigkeit ohne Geschwindigkeitseinbußen erreicht wird.

  • YOLOE vs. frühere Open-Vocabulary-Detektoren: Frühere Open-Vocabulary-Modelle (GLIP, OWL-ViT, YOLO-World) stützten sich stark auf Vision-Sprach-Transformatoren, was zu langsamer Inferenz führte. YOLOE übertrifft diese in der Zero-Shot-Genauigkeit (z. B. +3,5 AP vs. YOLO-Worldv2), während es 1,4-mal schneller läuft und deutlich weniger Trainingsressourcen benötigt. Im Vergleich zu transformatorbasierten Ansätzen (z. B. GLIP) bietet YOLOE eine um Größenordnungen schnellere Inferenz und überbrückt so effektiv die Lücke zwischen Genauigkeit und Effizienz bei der Open-Set-Detektion.

Zusammenfassend lässt sich sagen, dass YOLOE die bekannte Geschwindigkeit und Effizienz von YOLO beibehält, Vorgänger in der Genauigkeit übertrifft, die Segmentierung integriert und eine leistungsstarke Open-World-Erkennung einführt, was es einzigartig vielseitig und praktisch macht.

Anwendungsfälle und Anwendungen

Die Open-Vocabulary-Erkennung und -Segmentierung von YOLOE ermöglichen vielfältige Anwendungen, die über traditionelle Modelle mit festen Klassen hinausgehen:

  • Open-World Objekterkennung: Ideal für dynamische Szenarien wie in der Robotik, wo Roboter zuvor ungesehene Objekte mithilfe von Prompts erkennen, oder für Sicherheitssysteme, die sich schnell an neue Bedrohungen (z. B. gefährliche Gegenstände) anpassen, ohne neu trainiert werden zu müssen.

  • Few-Shot- und One-Shot-Erkennung: Mithilfe visueller Prompts (SAVPE) lernt YOLOE schnell neue Objekte aus einzelnen Referenzbildern – perfekt für die industrielle Inspektion (sofortige Identifizierung von Teilen oder Defekten) oder die kundenspezifische Überwachung, was visuelle Suchen mit minimalem Aufwand ermöglicht.

  • Großer Wortschatz & Long-Tail-Erkennung: Ausgestattet mit einem Vokabular von über 1000 Klassen, zeichnet sich YOLOE in Aufgaben wie dem Biodiversitätsmonitoring (detect seltener Arten), Museumssammlungen, Bestandsmanagement im Einzelhandel oder im E-Commerce aus, indem es viele Klassen zuverlässig identifiziert, ohne umfangreiches Training pro Klasse zu benötigen.

  • Interaktive Detektion und Segmentierung: YOLOE unterstützt interaktive Echtzeitanwendungen wie die durchsuchbare Video-/Bildabfrage, Augmented Reality (AR) und intuitive Bildbearbeitung, gesteuert durch natürliche Eingaben (Text- oder visuelle Prompts). Benutzer können Objekte präzise mithilfe von Segmentierungsmasken dynamisch isolieren, identifizieren oder bearbeiten.

  • Automatisierte Datenbeschriftung und Bootstrapping: YOLOE ermöglicht die schnelle Erstellung von Datensätzen durch die Bereitstellung anfänglicher Bounding-Box- und Segmentierungsannotationen, wodurch der manuelle Beschriftungsaufwand erheblich reduziert wird. Besonders wertvoll in der Analyse großer Mediensammlungen, wo es vorhandene Objekte automatisch identifizieren und so den Aufbau spezialisierter Modelle beschleunigen kann.

  • Segmentierung für beliebige Objekte: Erweitert die Segmentierungsfähigkeiten auf beliebige Objekte mittels Prompts—besonders vorteilhaft für die medizinische Bildgebung, Mikroskopie oder Satellitenbildanalyse, indem Strukturen automatisch identifiziert und präzise segmentiert werden, ohne spezialisierte vortrainierte Modelle. Im Gegensatz zu Modellen wie SAM erkennt und segmentiert YOLOE Objekte gleichzeitig und automatisch, was bei Aufgaben wie der Inhaltserstellung oder dem Szenenverständnis hilft.

Bei all diesen Anwendungsfällen liegt der Hauptvorteil von YOLOE in seiner Vielseitigkeit, da es ein einheitliches Modell für Erkennung, Wiedererkennung und Segmentierung in dynamischen Szenarien bietet. Seine Effizienz gewährleistet Echtzeitleistung auf ressourcenbeschränkten Geräten, ideal für Robotik, autonomes Fahren, Verteidigung und darüber hinaus.

Tipp

Wählen Sie den Modus von YOLOE basierend auf Ihren Bedürfnissen:

  • Closed-Set-Modus: Für Aufgaben mit fester Klasse (maximale Geschwindigkeit und Genauigkeit).
  • Prompted Modus: Fügen Sie schnell neue Objekte über Text- oder visuelle Prompts hinzu.
  • Prompt-freier Open-Set-Modus: Allgemeine Erkennung über viele Kategorien hinweg (ideal für Katalogisierung und Entdeckung).

Oftmals schöpft die Kombination von Modi – wie z. B. die aufforderungsfreie Erkennung gefolgt von gezielten Aufforderungen – das volle Potenzial von YOLOE aus.

Training und Inferenz

YOLOE lässt sich nahtlos in die Ultralytics Python API und die CLI integrieren, ähnlich wie andere YOLO-Modelle (YOLOv8, YOLO-World). Hier erfahren Sie, wie Sie schnell loslegen können:

Training und Inferenz mit YOLOE

from ultralytics import YOLO

# Load pretrained YOLOE model and train on custom data
model = YOLO("yoloe-11s-seg.pt")
model.train(data="path/to/data.yaml", epochs=50, imgsz=640)

# Run inference using text prompts ("person", "bus")
model.set_classes(["person", "bus"])
results = model.predict(source="test_images/street.jpg")
results[0].save()  # save annotated output

Hier verhält sich YOLOE standardmäßig wie ein normaler Detektor, kann aber einfach auf Prompted Detection umschalten, indem Klassen angegeben werden (set_classes). Die Ergebnisse enthalten Begrenzungsrahmen, Masken und Beschriftungen.

# Training YOLOE on custom dataset
yolo train model=yoloe-11s-seg.pt data=path/to/data.yaml epochs=50 imgsz=640

# Inference with text prompts
yolo predict model=yoloe-11s-seg.pt source="test_images/street.jpg" classes="person,bus"

CLI-Eingabeaufforderungen (classes) Anleitung YOLOE ähnlich wie bei Pythons set_classes. Visuelles Prompting (bildbasierte Abfragen) erfordert derzeit die Python API.

Andere unterstützte Aufgaben

  • Validierung: Bewerten Sie die Genauigkeit einfach mit model.val() oder yolo val.
  • Exportieren: YOLOE-Modelle exportieren (model.export()) zu ONNX, TensorRT usw., was die Bereitstellung erleichtert.
  • Tracking: YOLOE unterstützt Objektverfolgung (yolo track) bei der Integration nützlich, um abgefragte Klassen in Videos zu verfolgen.

Hinweis

YOLOE beinhaltet automatisch Segmentierungsmasken in den Inferenz-Ergebnissen (results[0].masks), was pixelgenaue Aufgaben wie Objektextraktion oder -messung vereinfacht, ohne dass separate Modelle erforderlich sind.

Loslegen

Richten Sie YOLOE mit Ultralytics schnell ein, indem Sie diese Schritte befolgen:

  1. Installation: Installieren oder aktualisieren Sie das Ultralytics-Paket:

    pip install -U ultralytics
    
  2. YOLOE-Gewichte herunterladen: Vortrainierte YOLOE-Modelle (z. B. YOLOE-v8-S/L, YOLOE-11 Varianten) sind über die YOLOE GitHub-Releases verfügbar. Laden Sie einfach Ihr gewünschtes .pt Datei, die in die Ultralytics YOLO-Klasse geladen werden soll.

  3. Hardwareanforderungen:

    • Inferenz: Empfohlene GPU (NVIDIA mit ≥4-8 GB VRAM). Kleine Modelle laufen effizient auf Edge-GPUs (z. B. Jetson) oder CPUs mit niedrigeren Auflösungen.
    • Training: Das Feinjustieren von YOLOE auf benutzerdefinierten Daten erfordert typischerweise nur eine GPU. Umfangreiches Open-Vocabulary-Pre-Training (LVIS/Objects365), das von den Autoren verwendet wurde, erforderte erhebliche Rechenleistung (8× RTX 4090 GPUs).
  4. Konfiguration: YOLOE-Konfigurationen verwenden standardmäßige Ultralytics YAML-Dateien. Standardkonfigurationen (z. B. yoloe-11s-seg.yaml) in der Regel ausreichen, aber Sie können Backbone, Klassen oder die Bildgröße nach Bedarf anpassen.

  5. YOLOE ausführen:

    • Schnelle Inferenz (Prompt-frei):
      yolo predict model=yoloe-11s-seg-pf.pt source="image.jpg"
      
    • Prompted Detection (Text-Prompt-Beispiel):

      from ultralytics import YOLO
      
      model = YOLO("yoloe-11s-seg.pt")
      names = ["bowl", "apple"]
      model.set_classes(names, model.get_text_pe(names))
      results = model.predict("kitchen.jpg")
      results[0].save()
      
  6. Integrationstipps:

    • Klassennamen: Standardmäßige YOLOE-Ausgaben verwenden LVIS-Kategorien; verwenden Sie set_classes() um Ihre eigenen Labels anzugeben.
    • Geschwindigkeit: YOLOE hat keinen Overhead, es sei denn, es werden Prompts verwendet. Text-Prompts haben minimale Auswirkungen; visuelle Prompts etwas mehr.
    • Batch-Inferenz: Direkt unterstützt (model.predict([img1, img2])). Für bildspezifische Prompts führen Sie die Bilder einzeln aus.

Die Ultralytics-Dokumentation bietet weitere Ressourcen. Mit YOLOE können Sie auf einfache Weise leistungsstarke Open-World-Funktionen innerhalb des vertrauten YOLO-Ökosystems erkunden.

Tipp

Profi-Tipp: Um die Zero-Shot-Genauigkeit von YOLOE zu maximieren, sollten Sie ein Fine-Tuning von bereitgestellten Checkpoints aus durchführen, anstatt von Grund auf neu zu trainieren. Verwenden Sie Prompt-Wörter, die mit gängigen Trainingsbezeichnungen übereinstimmen (siehe LVIS-Kategorien), um die Erkennungsgenauigkeit zu verbessern.

Zitate und Danksagungen

Wenn YOLOE zu Ihrer Forschung oder Ihrem Projekt beigetragen hat, zitieren Sie bitte das Originalpapier von Ao Wang, Lihao Liu, Hui Chen, Zijia Lin, Jungong Han und Guiguang Ding von der Tsinghua University:

@misc{wang2025yoloerealtimeseeing,
      title={YOLOE: Real-Time Seeing Anything},
      author={Ao Wang and Lihao Liu and Hui Chen and Zijia Lin and Jungong Han and Guiguang Ding},
      year={2025},
      eprint={2503.07465},
      archivePrefix={arXiv},
      primaryClass={cs.CV},
      url={https://arxiv.org/abs/2503.07465},
}

Für weitere Informationen steht das Original YOLOE-Paper auf arXiv zur Verfügung. Der Quellcode des Projekts und zusätzliche Ressourcen sind über das GitHub-Repository zugänglich.

FAQ

Wie unterscheidet sich YOLOE von YOLO-World?

Obwohl sowohl YOLOE als auch YOLO-World Open-Vocabulary-Erkennung ermöglichen, bietet YOLOE mehrere Vorteile. YOLOE erreicht eine um +3.5 AP höhere Genauigkeit auf LVIS, verbraucht dabei 3× weniger Trainingsressourcen und läuft 1.4× schneller als YOLO-Worldv2. YOLOE unterstützt auch drei Prompting-Modi (Text, visuell und internes Vokabular), während YOLO-World sich primär auf Text-Prompts konzentriert. Zusätzlich enthält YOLOE integrierte Instanzsegmentierungs-Funktionen, die pixelgenaue Masken für detect Objekte ohne zusätzlichen Aufwand liefern.

Kann ich YOLOE als reguläres YOLO-Modell verwenden?

Ja, YOLOE kann genau wie ein Standard-YOLO-Modell ohne Leistungseinbußen funktionieren. Wenn YOLOE im Closed-Set-Modus (ohne Prompts) verwendet wird, werden die Open-Vocabulary-Module in den Standard-Detection-Head reparametrisiert, was zu identischer Geschwindigkeit und Genauigkeit wie bei äquivalenten YOLO11-Modellen führt. Dies macht YOLOE äußerst vielseitig – Sie können es als traditionellen Detektor für maximale Geschwindigkeit verwenden und nur bei Bedarf in den Open-Vocabulary-Modus wechseln.

Welche Arten von Prompts kann ich mit YOLOE verwenden?

YOLOE unterstützt drei Arten von Prompts:

  1. Text-Prompts: Geben Sie Objektklassen in natürlicher Sprache an (z. B. "Person", "Ampel", "Vogelroller")
  2. Visuelle Prompts: Stellen Sie Referenzbilder von Objekten bereit, die Sie detect möchten
  3. Internes Vokabular: Verwenden Sie das integrierte Vokabular von YOLOE mit über 1200 Kategorien ohne externe Prompts.

Diese Flexibilität ermöglicht es Ihnen, YOLOE an verschiedene Szenarien anzupassen, ohne das Modell neu trainieren zu müssen. Dies ist besonders nützlich für dynamische Umgebungen, in denen sich die Erkennungsanforderungen häufig ändern.

Wie handhabt YOLOE die Instanzsegmentierung?

YOLOE integriert die Instanzsegmentierung direkt in seine Architektur, indem es den Erkennungskopf um einen Maskenprädiktionszweig erweitert. Dieser Ansatz ähnelt YOLOv8-Seg, funktioniert aber für jede abgefragte Objektklasse. Segmentierungsmasken sind automatisch in den Inferenz-Ergebnissen enthalten und können abgerufen werden über results[0].masks. Dieser einheitliche Ansatz macht separate Detektions- und Segmentierungsmodelle überflüssig und rationalisiert die Arbeitsabläufe für Anwendungen, die pixelgenaue Objektgrenzen erfordern.

Wie verarbeitet YOLOE die Inferenz mit benutzerdefinierten Prompts?

Ähnlich wie YOLO-World unterstützt YOLOE eine „prompt-then-detect“-Strategie, die ein Offline-Vokabular zur Effizienzsteigerung nutzt. Benutzerdefinierte Prompts wie Bildunterschriften oder spezifische Objektkategorien werden vorab kodiert und als Offline-Vokabular-Embeddings gespeichert. Dieser Ansatz optimiert den Detektionsprozess, ohne ein erneutes Training zu erfordern. Sie können diese Prompts dynamisch innerhalb des Modells festlegen, um es an spezifische Detektionsaufgaben anzupassen:

from ultralytics import YOLO

# Initialize a YOLOE model
model = YOLO("yoloe-11s-seg.pt")

# Define custom classes
names = ["person", "bus"]
model.set_classes(names, model.get_text_pe(names))

# Execute prediction on an image
results = model.predict("path/to/image.jpg")

# Show results
results[0].show()


📅 Erstellt vor 9 Monaten ✏️ Aktualisiert vor 23 Tagen
RizwanMunawarglenn-jocherY-T-GLaughing-qpderrengeronuralpszrShuaiLYUpicsalexwillie.maddox@gmail.comJShengPleonnil

Kommentare