← All posts
YOLO26 tutorial: train a safety gear detection model in 30 minutes on an RTX 5060 8 GB
gcube · hands-on

YOLO26 tutorial: train a safety gear detection model in 30 minutes on an RTX 5060 8 GB

on this page

Introduction

When people think of a GPU cloud, they usually picture expensive GPUs running large language models. But plenty of AI that’s put to work in the field only needs a single 8 GB GPU. A prime example is object detection, which finds objects in photos and video.

In this post, we train Ultralytics’ latest model, YOLO26, on a gcube RTX 5060 8 GB container to build a model that spots whether workers are wearing helmets, vests, gloves, safety boots and goggles in construction site photos.

By the end of this post, you’ll have

  • your own model (best.pt) that draws boxes around safety gear when you give it a photo,
  • learned how to read the training curves and accuracy metrics (mAP), and
  • an ONNX file you can use on other servers or edge devices.
ItemDetails
DifficultyBeginner (basic Python is all you need)
GPUgcube RTX 5060 8 GB × 1
ModelUltralytics YOLO26n (optional: YOLO26s)
DataConstruction-PPE (1,416 images, 11 classes, downloads automatically)
Time requiredAbout 30 minutes (including 7.5 minutes of YOLO26n training)

1. Background

YOLO26

  • The latest YOLO model, officially released by Ultralytics in January 2026.
  • Earlier YOLO models needed a separate post-processing step (NMS) to remove overlapping boxes, but YOLO26 handles this inside the model with an NMS-free architecture, which makes deployment simpler.
  • It comes in five sizes — n, s, m, l and x. Here we use n (default) and s (optional), which fit comfortably in 8 GB.

The Construction-PPE dataset

A construction site safety gear dataset released by Ultralytics. It contains 1,416 real site images (1,132 train / 143 validation / 141 test) labeled with 11 classes.

GroupClasses
Gear worn (5)helmet, gloves, vest, boots, goggles
Gear missing (4)no_helmet, no_gloves, no_boots, no_goggle
Other (2)Person, none

Because “worn” and “missing” are trained as separate classes, you can go beyond simple detection to detecting safety violations. Just specify the dataset name in the training code and it downloads automatically.

2. Create a gcube workload

On gcube, you register a workload by entering the container image address and start command yourself. Use the settings below as is, and the workload starts with PyTorch and JupyterLab ready for the RTX 5060.

ItemValue
GPURTX 5060 (8 GB) × 1
Registry TypeDocker Hub
Container Imagepytorch/pytorch:2.9.1-cuda12.8-cudnn9-runtime
Container Port8888
Minimum CUDA Version12.8 or later

Container command

bash -c "apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y git wget libgl1 libglib2.0-0 && pip install jupyterlab && jupyter lab --ip=0.0.0.0 --port=8888 --no-browser --allow-root --ServerApp.token='' --ServerApp.password=''"

Why this image? The RTX 5060 is a Blackwell-generation GPU, so it needs PyTorch built with CUDA 12.8 or later. With an older image, the GPU may be detected but computations won’t work properly. Installing libgl1 up front also lets you proceed without the OpenCV error (libGL.so.1).

Once the workload is running, add /lab to the end of the service URL to open it, then open Notebook → Python 3 from the Launcher. This setup opens without a token, so don’t share the URL with anyone outside your team.

3. Check the GPU environment

In the first notebook cell, check that PyTorch recognizes the RTX 5060 properly.

import torch
print("PyTorch:", torch.__version__)
print("CUDA:", torch.version.cuda)
print("GPU available:", torch.cuda.is_available())
print("GPU name:", torch.cuda.get_device_name(0))
print("Compute capability:", torch.cuda.get_device_capability(0))
PyTorch: 2.9.1+cu128
CUDA: 12.8
GPU available: True
GPU name: NVIDIA GeForce RTX 5060
Compute capability: (12, 0)

You’re all set if CUDA is 12.8 or later and there’s no sm_120 is not compatible warning.

4. Install Ultralytics

!pip install -q ultralytics
import ultralytics
ultralytics.checks()
Ultralytics 8.4.178 🚀 Python-3.11.14 torch-2.9.1+cu128 CUDA:0 (NVIDIA GeForce RTX 5060, 8151MiB)
Setup complete ✅ (12 CPUs, 20.5 GB RAM, 60.8/75.6 GB disk)

When you see Setup complete ✅, you’re ready.

5. First run: detect right away with a pretrained model

Before training, check that the base model — which already knows 80 kinds of objects such as people, cars and buses — runs properly.

from ultralytics import YOLO
from ultralytics.utils import ASSETS
from IPython.display import Image, display

model = YOLO("yolo26n.pt")  # downloaded automatically on first run
results = model.predict(ASSETS / "bus.jpg", save=True)  # sample image bundled with the package

save_dir = results[0].save_dir
print("Results saved to:", save_dir)
display(Image(filename=f"{save_dir}/bus.jpg", width=600))

The actual output was 640x480 4 persons, 1 bus, 6.1ms. That works out to about 0.006 seconds to analyze one photo.

6. Train the safety gear detection model

import time, torch
from ultralytics import YOLO

torch.cuda.reset_peak_memory_stats()
t0 = time.time()
model = YOLO("yolo26n.pt")
results = model.train(
    data="construction-ppe.yaml",  # dataset downloads automatically
    epochs=50,
    imgsz=640,
    batch=16,
    device=0,
    workers=4,
    project="ppe",
    name="y26n",
)
print(f"Training time: {(time.time()-t0)/60:.1f} min")
print(f"Peak VRAM: {torch.cuda.max_memory_allocated()/1024**3:.2f} GB")

When you run it, it downloads the dataset (170 MB) and starts training right away. If you check GPU_mem in the log, you’ll see it uses only about 3.2 GB of the 8 GB.

OptionMeaning8 GB tip
epochsHow many times to train over the full dataset50 is enough
batchNumber of images processed at onceLower it to 8 if you run out of memory
workersNumber of data loading processes2 or 0 if you hit a shared memory error

6-2. Higher accuracy with YOLO26s (optional)

If you run this in the same kernel right after 6-1, GPU memory left over from the previous training causes CUDA error: out of memory. Restart the kernel from the menu with Kernel → Restart Kernel… → Restart before running it.

import time, torch
from ultralytics import YOLO

torch.cuda.reset_peak_memory_stats()
t0 = time.time()
model = YOLO("yolo26s.pt")
results = model.train(data="construction-ppe.yaml", epochs=100, imgsz=640, batch=16,
                      device=0, workers=4, project="ppe", name="y26s")
print(f"Training time: {(time.time()-t0)/60:.1f} min")
print(f"Peak VRAM: {torch.cuda.max_memory_allocated()/1024**3:.2f} GB")

7. Check the training results

from IPython.display import Image, display  # re-import if you restarted the kernel
save_dir = model.trainer.save_dir  # actual save location
print("Training results folder:", save_dir)
display(Image(filename=f"{save_dir}/results.png", width=900))
display(Image(filename=f"{save_dir}/val_batch0_pred.jpg", width=900))

results.png shows loss and accuracy curves per epoch, and val_batch0_pred.jpg shows example predictions on validation images. We also measure final performance on the test set, which the model never saw during training.

best = YOLO(f"{save_dir}/weights/best.pt")
metrics = best.val(data="construction-ppe.yaml", split="test")
print("mAP50:", round(metrics.box.map50, 3))
print("mAP50-95:", round(metrics.box.map, 3))

Measured results (RTX 5060 8 GB, batch 16)

ModelEpochsTraining timePeak VRAMTest mAP50Test mAP50-95
YOLO26n507.5 min2.6 GB0.5350.267
YOLO26s10021.7 min4.6 GB0.5620.273
  • Both models trained comfortably, using around half of the 8 GB or less.
  • s is slightly more accurate than n but takes about 3x as long. We recommend starting with n to learn the workflow.
  • By class, the model finds gear being worn, like helmets and vests, well, but accuracy was lower for the “missing” classes, because there are fewer examples of missing gear in the training data.
  • Training twice with the same image and settings produced exactly the same numbers, so if you follow along, you should get nearly the same results.

How to read mAP: A value between 0 and 1 that shows how accurately the model finds boxes. mAP50 counts a box as correct if it’s “roughly right,” while mAP50-95 requires “precise placement” to count.

8. Apply it to your own photos

Upload a site photo (for example, site.jpg) in the file panel on the left side of JupyterLab, then run:

from PIL import Image as PILImage

res = best.predict("site.jpg", conf=0.4, save=True)
print([(best.names[int(b.cls)], round(float(b.conf), 2)) for b in res[0].boxes])

display(PILImage.fromarray(res[0].plot()[..., ::-1]))  # show the result with boxes drawn

Running it on a site photo from the test set gave [('helmet', 0.82), ('vest', 0.81), ('Person', 0.78), ('gloves', 0.51)]. It found a worker wearing a helmet, vest and gloves.

  • conf=0.4 means only detections with 40% confidence or higher are shown. Raise it if you get too many false positives, and lower it if it misses too much.
  • You can process video the same way with best.predict("site.mp4", save=True).

Picking out only missing gear — the basic form of a safety monitoring system.

VIOLATIONS = {"no_helmet", "no_gloves", "no_boots", "no_goggle"}
found = [best.names[int(b.cls)] for b in res[0].boxes if best.names[int(b.cls)] in VIOLATIONS]
print("Violations detected:", found if found else "none")

9. Export the model (ONNX)

To use the model on other servers or edge devices, convert it to ONNX format.

onnx_path = best.export(format="onnx")
print(onnx_path)

On the first run, the required packages install automatically and best.onnx is created within a few seconds. Even if you see a Restart runtime... warning partway through, it succeeded as long as Export complete appears. You can download it from the file panel with right-click → Download.

10. Troubleshooting

These are errors we actually ran into when using a different image or changing the order of steps.

SymptomCauseFix
sm_120 is not compatible warningPyTorch built for CUDA 12.4 or earlierUse the image recommended in step 2, or run pip install --upgrade torch torchvision --index-url https://download.pytorch.org/whl/cu128 and restart the kernel
ImportError: libGL.so.1The container lacks the libraries OpenCV needsInclude libgl1 in the step 2 command, or switch to opencv-python-headless and restart the kernel
Download failure ... Connection reset by peerIntermittent connection drops from the download serverRerun the cell. Download the dataset directly with the code below
CUDA error: out of memoryGPU memory from the previous training is still in useRestart the kernel and run again; if it’s still not enough, use batch=8

If the automatic dataset download fails:

from ultralytics.utils import DATASETS_DIR
from ultralytics.utils.downloads import download

download("https://github.com/ultralytics/assets/releases/download/v0.0.0/construction-ppe.zip", dir=DATASETS_DIR)

Wrapping up

With a single 8 GB GPU, we built a model that detects construction site safety gear in 30 minutes. Training used only 2.6 GB of VRAM, so you can absolutely get started with vision AI like object detection without an expensive GPU.

What to try next

  • Train on your own data: Create YOLO-format labels with Label Studio or CVAT, write a yaml file with the same structure, and you can train with the same code.
  • Extend to other tasks: The same API also handles segmentation (yolo26n-seg.pt) and pose estimation (yolo26n-pose.pt).
  • Larger models: If you need higher accuracy, try training the m or l models on a larger GPU on gcube.

License note: The Ultralytics YOLO code and the Construction-PPE dataset are licensed under AGPL-3.0. You can use them freely for learning and research, but deploying a commercial service that includes them triggers source-disclosure obligations, so look into an Ultralytics Enterprise License.

References

YOLO26 tutorial: train a safety gear detection model in 30 minutes on an RTX 5060 8 GB | gcube Lab