Train a YOLO Model in Our GPU Lab: Images to Live Endpoint

Train a YOLO Model in Our GPU Lab: Images to Live Endpoint

How We Train a YOLO Model from Scratch in One Lab Session

Last Thursday, a student in our current Computer Vision & Visual AI cohort walked into office hours with a hard drive full of warehouse shelf photos and a product requirements doc that said "detect misplaced items in real time." By the end of that same two-hour session, she had a live endpoint returning bounding boxes. Not a slide deck promise. That's what happens when the environment is already configured and you stop wasting time on CUDA versioning.

This post walks through the exact process we use in AI Labs' GPU Training Lab to train a YOLO model on custom data and ship it somewhere real.

What the GPU Training Lab Actually Gives You

The lab spins up a JupyterLab instance backed by an A100 80GB, with Ultralytics 8.2, CUDA 12.4, and PyTorch 2.3 already installed. No conda environment hell. No driver mismatches. The YOLOv8 GPU training environment is just there, which sounds minor until you've watched someone spend 45 minutes on a torch.cuda.is_available() that returns False. That particular support request showed up three times in a single week during our last cohort. Three times.

We also pre-mount a shared CVAT (Computer Vision Annotation Tool) instance so students can export annotations directly in YOLO format. The directory structure lands exactly where Ultralytics expects it:

dataset/
  images/
    train/
    val/
  labels/
    train/
    val/
  data.yaml

That data.yaml is the thing people mess up most often. It needs absolute paths in the lab environment, not relative ones. We've baked a generation script into the starter notebook so nobody has to remember that on their own.

How Does the Training Command Actually Work?

Once your labels are exported and data.yaml is correct, training a YOLOv8 nano model on a 500-image custom dataset looks like this:

from ultralytics import YOLO

model = YOLO("yolov8n.pt")

results = model.train(
    data="/workspace/dataset/data.yaml",
    epochs=100,
    imgsz=640,
    batch=32,
    device=0,
    project="/workspace/runs",
    name="shelf_detector_v1",
    augment=True,
    hsv_h=0.015,
    hsv_s=0.7,
    flipud=0.3,
    mosaic=1.0,
)

That runs in about 11 minutes on the A100. You get a best.pt checkpoint, a confusion matrix, and a PR curve, all written to /workspace/runs/shelf_detector_v1/. The built-in augmentation matters a lot when you have fewer than 500 images per class. mosaic, flipud, HSV shifts, then Albumentations on top for geometric distortions. We've seen mAP50 jump from 0.71 to 0.84 just from that combination. Students who skip augmentation and go straight to "I need more data" are almost always wrong.

One thing students consistently underestimate: validation split. Default is 20%. On a 300-image dataset that's 60 val images, which is statistically shaky. We push students to 25% val, or to use the k-fold cross-validation notebooks we keep in the lab's shared templates folder.

When Should You Move to a Larger Model?

Stick with YOLOv8n until your mAP50 on the validation set plateaus below your target. Nano is fast enough that you can run five experiments in the time it takes to train YOLOv8m once. The jump from nano to small (YOLOv8s) typically adds 3 to 5 mAP50 points on datasets with more than 10 classes. Medium earns its weight when objects are small relative to the frame or you need sub-5% false positive rates in dense scenes. Those are the two cases where I'd reach for YOLOv8m without hesitation. Everything else, start small and measure.

For the warehouse use case above, YOLOv8s was the right call. Two classes, decent image resolution, latency budget under 100ms. Nano hit 0.87 mAP50, small hit 0.91. She shipped small.

Deploying to a Live Endpoint in Under 20 Minutes

This is the part most YOLO object detection tutorials skip entirely. Training is the easy half.

We export best.pt to ONNX first:

model = YOLO("/workspace/runs/shelf_detector_v1/weights/best.pt")
model.export(format="onnx", dynamic=True, simplify=True)

Then we wrap inference in a FastAPI app (the template lives in the lab's /templates/deployment/ folder), containerize with Docker, and push to Cloud Run. The whole thing runs on CPU at Cloud Run's minimum instance size for low-traffic endpoints, which keeps costs under $5/month for a demo. Students who need GPU inference swap Cloud Run for a Vertex AI Prediction endpoint with an L4 instance.

The final call looks like this from any HTTP client:

curl -X POST https://shelf-detector-xxxx.run.app/predict \
  -F "file=@test_image.jpg" \
  | jq '.detections'

Bounding boxes, class names, confidence scores. Done.

Custom YOLO Training Is a Pipeline Problem, Not a Model Problem

Every time a student's custom YOLO training run produces garbage results, the issue is upstream: inconsistent labels, wrong image paths, class imbalance nobody caught, or validation leakage from augmenting before splitting. I've reviewed maybe 40 failed training runs across the last two cohorts. The model architecture was the culprit exactly once.

The GPU Training Lab forces you to confront the pipeline because the model part is already solved. That's the point. If you want to go deeper on the full workflow, including multi-class detection, tracking with ByteTrack, and edge deployment to Jetson, that's what Computer Vision & Visual AI is built around.

The question isn't whether YOLOv8 can detect your objects. It almost certainly can. The question is whether your labels are clean enough to let it.

Frequently asked questions

How many images do I need to train a YOLO model on a custom class?+

In practice, 300 to 500 well-labeled images per class gets you a usable baseline with YOLOv8. Below 200, validation mAP tends to swing wildly epoch to epoch. We've seen students hit production-ready accuracy with as few as 400 images when augmentation is dialed in correctly.

Which YOLOv8 model size should I start with for custom YOLO training?+

Start with YOLOv8n (nano) for speed and iteration, then promote to YOLOv8s or YOLOv8m once your pipeline is clean. Training nano on an A100 takes about 3 minutes per 50 epochs on a 500-image dataset, which makes debugging fast.

Can I use the GPU Training Lab if I'm not enrolled in a computer vision course?+

Yes. The GPU Training Lab is available to all active AI Labs students regardless of which course they're in. That said, the structured walkthrough we describe here is part of the Computer Vision & Visual AI course curriculum.

Ready to learn AI seriously?

Browse our 13 live, instructor-led programs.

Explore Courses