Unanswered
Hello, Have Been Trying For A Long Time To Make A Task That Collect A Dataset From Cvat And Trains A Yolo Modell In Clearml. But Cannot Figure It Out And Get The Understanding On How We Actually Do This Following Best Practices.
My Sync Script:
Hello, Have been trying for a long time to make a task that collect a dataset from cvat and trains a yolo modell in clearml. But cannot figure it out and get the understanding on how we actually do this following best practices.
My sync script:
import argparse
import tempfile
import zipfile
import time
from pathlib import Path
from urllib.parse import urlparse
from clearml import Dataset, Task
from cvat_sdk.api_client import ApiClient, Configuration
from cvat_sdk.exceptions import ApiException
# sync_dataset_to_clearml-funksjonen er uendret...
def sync_dataset_to_clearml(project_name: str, dataset_name: str, local_path: Path) -> str:
print(f"Sjekker datasett '{dataset_name}' i prosjekt '{project_name}'...")
latest_remote_dataset = None
try:
latest_remote_dataset = Dataset.get(
dataset_project=project_name, dataset_name=dataset_name, only_latest=True)
remote_hash = latest_remote_dataset.file_hash
local_hash = Dataset.hash_local_folder(local_path)
if remote_hash == local_hash:
print(":white_check_mark: Datasettet er allerede synkronisert. Ingen endringer funnet.")
return latest_remote_dataset.id
print(":arrows_counterclockwise: Endringer oppdaget. Oppretter en ny versjon...")
except ValueError:
print(f"Finner ikke et eksisterende datasett. Oppretter første versjon.")
new_dataset = Dataset.create(
dataset_project=project_name, dataset_name=dataset_name,
parent_datasets=[latest_remote_dataset] if latest_remote_dataset else None)
new_dataset.add_files(path=local_path)
new_dataset.upload()
new_dataset.finalize()
print(f":white_check_mark: Ny versjon '{new_dataset.version}' opprettet med ID: {new_dataset.id}")
return new_dataset.id
def main():
task = Task.init(
project_name="Dataset Management",
task_name="Sync CVAT Dataset",
task_type=Task.TaskTypes.data_processing)
parser = argparse.ArgumentParser(description="Synkroniser et CVAT-datasett til ClearML.")
parser.add_argument("--cvat-url", required=True, help="URL til CVAT-serveren.")
parser.add_argument("--cvat-user", required=True, help="Brukernavn for CVAT.")
parser.add_argument("--cvat-password", required=True, help="Passord for CVAT.")
parser.add_argument("--cvat-project-id", type=int, required=True, help="ID-en til prosjektet i CVAT.")
parser.add_argument("--clearml-project", default="My Datasets", help="ClearML-prosjekt for datasettet.")
parser.add_argument("--clearml-dataset-name", required=True, help="Navn på datasettet i ClearML.")
args = parser.parse_args()
task.connect(args)
print("Kobler til CVAT-server...")
with tempfile.TemporaryDirectory() as temp_dir:
temp_path = Path(temp_dir)
dataset_zip_path = temp_path / "dataset.zip"
config = Configuration(host=args.cvat_url, username=args.cvat_user, password=args.cvat_password)
with ApiClient(config) as api_client:
print(f"Steg 1: Starter eksport-jobb for prosjekt ID: {args.cvat_project_id}...")
# --- ENDRINGEN ER HER ---
(request, _) = api_client.projects_api.create_dataset_export(
id=args.cvat_project_id,
format="Ultralytics YOLO Detection 1.0",
save_images=True # Forteller CVAT at vi vil ha med bildene
)
# --- SLUTT PÅ ENDRING ---
rq_id = request.rq_id
print(f"Eksport-jobb startet med Request ID: {rq_id}")
print("Steg 2: Venter på at serveren skal klargjøre ZIP-filen...")
final_status_request = None
while True:
try:
(status_request, _) = api_client.requests_api.retrieve(id=rq_id)
status = status_request.status.value
if status == "finished":
print(":white_check_mark: Eksporten er ferdig!")
final_status_request = status_request
break
elif status == "failed":
raise Exception("Eksport-jobben på CVAT-serveren feilet.")
print(f"Status er '{status}'. Venter 10 sekunder...")
time.sleep(10)
except ApiException as e:
print(f"Feil under status-sjekk: {e}. Prøver igjen...")
time.sleep(10)
print("Steg 3: Henter nedlastings-URL fra den ferdige jobben...")
download_url = final_status_request.result_url
if not download_url:
raise Exception("CVAT returnerte ikke en 'result_url'. Kan ikke laste ned datasettet.")
print(f"Funnet nedlastings-URL: {download_url}")
parsed_url = urlparse(download_url)
resource_path = parsed_url.path
if parsed_url.query:
resource_path += "?" + parsed_url.query
print(f"Steg 4: Laster ned ZIP-fil fra ressurs-sti: {resource_path}...")
(_, response) = api_client.call_api(
resource_path=resource_path, method='GET',
auth_settings=['basicAuth', 'cookieAuth', 'tokenAuth'],
_parse_response=False, _request_timeout=600)
status_code = response.status
if status_code != 200:
raise Exception(f"Nedlasting fra result_url feilet med statuskode {status_code}")
print(f"Laster ned ZIP-fil til {dataset_zip_path}...")
with open(dataset_zip_path, 'wb') as f:
f.write(response.data)
if dataset_zip_path.exists() and dataset_zip_path.stat().st_size > 100:
print(f":white_check_mark: ZIP-filen er lastet ned og har en størrelse på {dataset_zip_path.stat().st_size} bytes.")
else:
raise FileNotFoundError("Nedlasting av ZIP-filen ser ut til å ha feilet.")
unzip_dir = temp_path / "unzipped_data"
unzip_dir.mkdir()
print(f"Pakker ut datasettet til {unzip_dir}...")
with zipfile.ZipFile(dataset_zip_path, 'r') as zip_ref:
zip_ref.extractall(unzip_dir)
print("Innhold i den utpakkede mappen:")
for item in sorted(list(unzip_dir.iterdir())):
print(f"- {item.name}")
sync_dataset_to_clearml(
project_name=args.clearml_project,
dataset_name=args.clearml_dataset_name,
local_path=unzip_dir)
print("Jobb fullført!")
if __name__ == "__main__":
main()
And my train script:
import argparse
import os
import yaml
from pathlib import Path
from ultralytics import YOLO
from clearml import Task, Dataset
def rewrite_path_files(directory: Path):
"""
Går gjennom train.txt, val.txt, og test.txt i en mappe,
og fjerner et overflødig 'data/' prefiks fra hver linje.
Dette fikser vanlige feil i stier fra CVAT-eksporter.
"""
files_to_process = ["train.txt", "val.txt", "test.txt"]
print("--- Starter korrigering av stier i .txt-filer ---")
for filename in files_to_process:
filepath = directory / filename
if filepath.exists():
print(f"Behandler fil: {filepath}...")
lines = filepath.read_text().splitlines()
# Sjekker om korrigering er nødvendig ved å se på første linje
if lines and (lines.lower().startswith("data/images") or lines.lower().startswith("./data/images")):
corrected_lines = []
for line in lines:
# Fjerner 'data/' eller './data/' og sikrer riktig casing for 'images'
# Eksempel: 'data/images/Train/...' -> 'images/train/...'
parts = Path(line).parts
try:
images_index = [p.lower() for p in parts].index('images')
correct_path = Path(*parts[images_index:])
corrected_lines.append(str(correct_path))
except ValueError:
corrected_lines.append(line)
filepath.write_text("\n".join(corrected_lines))
print(f":white_check_mark: Filen er korrigert. Ny første linje: {corrected_lines if corrected_lines else 'Tom fil'}")
else:
print(f":+1: Ingen korrigering nødvendig for {filename}.")
else:
print(f":information_source: Fant ikke {filename}, hopper over.")
print("--- Ferdig med korrigering av stier ---")
def main(args):
# Steg 1: Initialiser ClearML-task
task = Task.init(project_name=args.clearml_project, task_name=args.task_name, task_type=Task.TaskTypes.training)
task.connect(args)
# Steg 2: Hent datasett fra ClearML
print(f"Henter ClearML-datasett: Prosjekt='{args.dataset_project}', Navn='{args.dataset_name}'")
try:
dataset = Dataset.get(dataset_project=args.dataset_project, dataset_name=args.dataset_name)
dataset_path = Path(dataset.get_local_copy())
print(f"Datasett (ID: {dataset.id}, Versjon: {dataset.version}) lastet ned til: {dataset_path}")
except Exception as e:
print(f"Kunne ikke hente datasettet. Feilmelding: {e}")
task.close()
exit(1)
# Steg 2.5: Fiks stier
rewrite_path_files(dataset_path)
# Steg 3: Finn data.yaml-filen
data_yaml_path = dataset_path / "data.yaml"
if not data_yaml_path.exists():
print(f"FEIL: Fant ikke 'data.yaml' i datasettets rotmappe: {dataset_path}")
task.close()
exit(1)
print(f"Fant konfigurasjonsfil: {data_yaml_path}")
# Bytt arbeidsmappe til rotmappen for datasettet
print(f"Bytter arbeidsmappe til: {dataset_path}")
os.chdir(dataset_path)
# Steg 4: Last inn modell og start trening
print(f"Laster inn modell: {args.model_variant}")
model = YOLO(args.model_variant)
print(f"Starter trening for {args.epochs} epoker...")
model.train(data="data.yaml", epochs=args.epochs, imgsz=args.imgsz)
print("\n--- Trening fullført! ---")
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Tren en YOLOv8-modell med data fra ClearML.")
parser.add_argument("--clearml-project", type=str, default="Frigate V2")
parser.add_argument("--task-name", type=str, default="YOLOv8 Training - Fixed Paths")
parser.add_argument("--dataset-project", type=str, default="Frigate V2")
parser.add_argument("--dataset-name", type=str, default="CVAT Frigate Dataset YOLO 1.1")
parser.add_argument("--model-variant", type=str, default="yolov8s.pt")
parser.add_argument("--epochs", type=int, default=50)
parser.add_argument("--imgsz", type=int, default=640)
arguments = parser.parse_args()
main(arguments)
Have no qlue if this is made correctly the way clearml is designed to work?
53 Views
0
Answers
19 hours ago
8 hours ago
Tags