System designTroubleshooting

YOLO training segmentation fault: GPU memory and CUDA fixes

A Darknet YOLO training run dies with a segmentation fault on an old GPU. Sort VRAM, cuDNN, driver and dataset causes, with the tests and fixes for each.

LumaSpec Vision11 min read Share on LinkedIn

On this page 9 sections
  1. 01Read the log before you change anything
  2. 02Cause 1: the resize runs the card out of VRAM
  3. 03Worked example: 736 MiB free against a 576 pixel resize
  4. 04Cause 2: a cuDNN library that does not match CUDA 8.0
  5. 05Cause 3: broken paths and corrupted images in the dataset
  6. 06Ruled out: the 410.78 driver and the CUDA 10.0 label
  7. 07Which cards can train YOLOv2, and where the job runs
  8. 08Prevention: checks before the next training run
  9. 09Questions

Darknet YOLOv2 training on an older card dies seconds after it starts: the weights load, the first image batch loads, then the terminal prints Segmentation fault (core dumped). The reflex is to reinstall the driver or rewrite the dataset config, and both are usually wrong. The fault is one of three things, in this order of likelihood: video memory exhausted at the first resize, a cuDNN library that does not match the CUDA toolkit, or a dataset file the loader cannot read. This guide gives you the log reading that separates the causes, the test that confirms each one, the fix that matches it, and the decision on whether the card in front of you can train YOLOv2 at all. The worked example uses the numbers from exactly this situation: a GTX 645 with 974 MiB on board, toolkit 8.0.62, driver 410.78, batch=20, subdivisions=20 at 416×416.

Read the log before you change anything

The sequence in the terminal output already narrows the field:

  • The cfg parses and the network builds. The layer table prints down to the detection layer, 13 x 13 x 30 at the output. Your filters line is right, and the arithmetic is worth checking once: filters = (classes + 5) × 5 = (1 + 5) × 5 = 30 for classes=1. A wrong filters line is a classic YOLOv2 crash, and yours is not it.
  • The pre-trained weights load: the log prints Loading weights from darknet19_448.conv.23 ... Done!
  • The first data batch loads in 0.05 s, so the path list worked at least once.
  • Resizing 576 prints, and the process dies before the first iteration line.

Configuration and weights are exonerated; the crash is in the first training step at the new input size. That is GPU territory. Everything that follows separates the three suspects that all die in the same place.

Cause 1: the resize runs the card out of VRAM

With random=1 in the [region] block, the trainer periodically changes the input resolution to another multiple of 32, and your log shows the first draw went to 576. Every activation buffer scales with input area, so 416 → 576 multiplies all of them by (576 ÷ 416)² ≈ 1.92. Training holds every layer's output for the backward pass, and cuDNN reserves convolution workspaces on top — workspaces Darknet never prints, which at this input size can take a few hundred megabytes alone. When an allocation inside that sequence fails, old Darknet builds do not print an out-of-memory message; they die with a segmentation fault. That is why a memory problem looks like a code problem.

images per pass = batch / subdivisions activation memory ≈ images per pass × (sum of layer outputs) × 4 bytes × (input / base)²

Your cfg has batch=20 with subdivisions=20, so exactly 1 image is in flight per step: already the smallest footprint the framework can make. Shrinking batch cannot rescue this run — the card itself is the constraint.

Test: set random=0, drop the input to 352×352, and train ten iterations. If the run survives there and dies again the moment random=1 returns, memory is confirmed. If you have chased depth-video playback hangs before, it is the same signature — memory pinned at the ceiling, then death.

Worked example: 736 MiB free against a 576 pixel resize

Inputs, read straight from the crash report:

  • Card memory: 974 MiB total, 238 MiB already used by the desktop, so 974 − 238 = 736 MiB free.
  • Input sizes: base 416×416 from the cfg, first resize 576×576 from the log.
  • Network shape: the layer table prints 18 filters per convolution down to the 13×13 head. Layer 0 alone holds 416 × 416 × 18 = 3,115,008 values per image, and the full printed stack sums to about 5.79 million values at the base size.
  • Precision: the framework stores activations as 32-bit floats, 4 bytes per value.

Rule in words: training memory ≈ images per pass × sum of layer outputs × 4 bytes × (input ÷ base)², plus cuDNN workspaces.

Arithmetic:

  • Resize factor: (576 ÷ 416)² = 1.385² ≈ 1.92.
  • Activations per image at the base: 5,790,000 × 4 bytes ≈ 23 MB.
  • Activations per image at 576: 23 MB × 1.92 ≈ 44 MB. Layer 0 alone accounts for 18 × 576 × 576 × 4 ≈ 24 MB of that.
  • Images per pass: 20 ÷ 20 = 1.

Result: activations need about 44 MB, and the card shows 736 MiB free. Plain buffer math says this should run, and it dies anyway. The gap sits in the part Darknet does not print: cuDNN convolution workspaces and batch-normalization buffers at 576×576×18. On a card with 736 MiB free while the desktop already holds 238 MiB, those unprinted allocations are the difference between running and dying.

Decision and threshold: this card has no margin left to trade. The practitioner floor for full YOLOv2 training is a card with 8 GB or more, because the standard batch=64, subdivisions=8 run is done on 8 GB hardware. At 736 MiB free the card sits an order of magnitude below that floor, and no cfg edit closes the gap. Stop editing the cfg on this card; move the training job — the next sections show where it runs instead.

Cause 2: a cuDNN library that does not match CUDA 8.0

The toolkit in the report is release 8.0, V8.0.62 by nvcc -V. cuDNN ships separately from the toolkit, and a cuDNN built against a different toolkit crashes on exactly the training path: Darknet reports segmentation faults that trace into cudnnBatchNormalizationForwardTraining().

The test is one rebuild. Compile Darknet with cuDNN disabled and run the identical command. If the segfault disappears — training will be slower — the library was the fault. Install the cuDNN release built for CUDA 8.0, rebuild with cuDNN enabled, and keep that pair fixed. One toolkit and one matching cuDNN per machine is the same discipline that keeps version drift out of container deployments: pin one SDK version everywhere.

Run the crash under gdb first and read the backtrace, because the two GPU causes leave different signatures. A backtrace that lands inside a cudnn symbol is this cause. Death at the resize with free memory near zero is Cause 1.

Cause 3: broken paths and corrupted images in the dataset

The list files in the report carry the classic traps. The train.txt lines read /home/uaer/src/... while the dataset sits in /home/user/src/..., dataset.data points at /home/useer/src/..., and the filenames contain spaces: img (10).jpg. A path that misses by one character, or an image file that is truncated, kills the loader. Corrupted images are a recorded training-time segfault cause in Darknet, and the loader dies without naming the bad file.

Check the entire list before the next run. This loop prints every path that does not exist:

while IFS= read -r p; do
  [ -f "$p" ] || echo "missing: $p"
done < cfg/task/train.txt

Then open a sample of the images in any viewer, confirm each has a matching label .txt, and rename the spaces out: img_10.jpg rather than img (10).jpg, then regenerate the list. Your label lines are already in the right form — 0 0.435937 0.033333 0.190625 0.058333 is class, x-centre, y-centre, width, height, normalized 0 to 1.

In this particular run the first batch loaded cleanly, which points away from paths as the immediate killer. Fix them anyway: the same list crashes the next run at a different image. Dataset-side crashes look identical across frameworks — the folder and mask errors that break anomaly-detection training reach the terminal the same way.

Ruled out: the 410.78 driver and the CUDA 10.0 label

The report suspects the driver because nvidia-smi prints CUDA Version: 10.0 next to Driver Version: 410.78 while the build used toolkit 8.0. That label is the newest toolkit the installed driver can run, not a demand on your build. Drivers are backward compatible: an application compiled against CUDA 8.0.62 runs on a 410.78 driver, and the GTX 645 is covered by both. The pairing in the report is legal.

Driver state is still the right lever for some industrial GPU crashes, just on other software: a robot-simulation startup crash fixed by the GPU driver rather than a reinstall is the same distinction pointed the other way. Here, the driver stays as it is.

Which cards can train YOLOv2, and where the job runs

Training is the GPU-hungry half of a vision AI project — that is why GPUs beat CPUs for deep learning training. Inference is light: one image forward, no backward pass, no resize surprise. Typical working points for Darknet YOLOv2 training:

Card memory Working config What fits
8 GB and up batch=64, subdivisions=8, random=1 full YOLOv2 at speed
4-6 GB batch=64, subdivisions=16-32, random=0 full YOLOv2, slower
2 GB batch=64, subdivisions=64, 288-352 input, random=0 tiny-yolo and small custom nets
1 GB, 736 MiB free none training moves off the card

The basis: the standard config, batch=64 with subdivisions=8, puts 8 images in flight and is run on 8 GB cards, and the framework's own advice for an out-of-memory error is to keep batch and raise subdivisions. The GTX 645 sits below every row; its remaining useful life is as a display card.

On-site, the clean split is a training machine for the offline half and inference hardware for the line.

On-site training, kept off the line PCs:

Vision controllersHikrobot MV-TS1004-256GR-960G16TR10 AI training server 1000 quad-GPU standardMV-TS1004-256GR-960G16TR10
LAN ports
2 LAN ports
USB 3 ports
3-4 USB 3 ports
Price on requestView and quoteBuild a system with it

A quad-GPU AI training server takes the team's training jobs while production keeps running.

Once trained, the line-side job is inference, which needs a fraction of the memory. The AI inference terminals come in single-card and dual-card versions:

Specification MV-VAC3504X-128G01 MV-VAC5724-256G02
CPU Intel® Core™ i5-12400 processor, 6 cores, 12 threads Intel® Core™ i7-12700 processor, 12 cores, 20 threads
Memory 2*8 GB, 2 × DDR4 SO-DIMM memory slots, Up to 32 GB per module, Up to 64 GB 16 GB, 2 × DDR5 SO-DIMM memory slots, Up to 32 GB per module, Up to 64 GB
Storage 128 GB M.2 SATA 2280 SSD; 2 TB 2.5-inch 5400 rpm HDD 256 GB M.2 SATA 2280 SSD; 2 TB 3.5-inch 5400 rpm HDD
GPU AI inference card 1070D; Video memory: 8 GB GDDR4X; Power: 25 W; Compute: INT8/UINT8 TC: 70 TOPS AI inference card 1070D × 2; Video memory: 8 GB GDDR4X × 2; Power: 25 W; Compute: INT8/UINT8 TC: 70 TOPS
Network interface 6× Gigabit Ethernet ports GigE interface × 7, including interface for PoE × 4
USB Interface 4 × external USB2.0 ports, 4× USB 3.0 ports; Built-in 1× USB 2.0 port 4 × external USB2.0 ports, 4× USB 3.0 ports; Built-in 1× USB 2.0 port
Light interface 4-channel 24 V constant-voltage light driver (separate power required), Max. power per channel: 72 W, Max. power, 4 cards: 80 W 8-channel 24 V constant-voltage light driver (separate power required), Max. power per channel: 72 W, 8 channels, max. power 190 W
Serial Port 2 × RS-232 by default, Configurable as RS-485/RS-422 2 × RS-232 by default, Configurable as RS-485/RS-422
Digital I/O 8 digital isolated inputs supported; 16 opto-isolated outputs supported (NPN/PNP switchable) 8 opto-isolated inputs supported; 12 opto-isolated outputs supported (NPN/PNP switchable), 8 digitally isolated low-side driver outputs; 4 non-isolated bidirectional differential I/O supported
Video output HDMI interface × 1, VGA interface × 1; Supports independent display output at the same time; Max. resolution 1920 × 1080 @ 60 Hz HDMI interface × 1, VGA interface × 1; Supports independent display output at the same time; Max. resolution 1920 × 1080 @ 60 Hz
Task types Supports all VM traditional algorithms; Supports all VM edge-learning (CPU); Supports deep learning GPU and CPU modules Supports all VM traditional algorithms; Supports all VM edge-learning (CPU); Supports deep learning GPU and CPU modules
AI parallel processing Parallel processing of multiple AI inference tasks, but no parallel acceleration Parallel processing of multiple AI inference tasks, Significant acceleration
Price $3,929.00 · quoted $4,609.00 · quoted

All 2 share: Power supply 24 V DC; Installation method Desktop or wall mounting; Temperature 0 to 45 °C; Humidity 20% RH to 95% RH (no condensation); Certification CE, KC. Values as printed in each product's data sheet; open a part for its drawing and full specifications.

For a multi-camera cell that runs cameras and the trained model together, one vision controller does both jobs:

Vision controllersHikrobot MV-VC5525-256G70-NN VC5000 Vision Controller, 12th-I5, 32GB+256G SSD, Supported PCIEMV-VC5525-256G70-NN
LAN ports
5+ LAN ports
USB 3 ports
3-4 USB 3 ports
PoE
PoE camera ports
Light outputs
8 built-in channels
$4,479.00 · quotedView and quoteBuild a system with it

This VC5000 controller carries 32 GB of memory, PoE camera ports and 8 built-in light channels, so cameras and lights land on one box. Deployment is its own discipline: shrinking the GPU container for embedded deployment covers the software side, and CPU-only inference is the fallback for slower lines.

Prevention: checks before the next training run

Each item exists because it kills a run somewhere:

  • Compute images per pass first — batch ÷ subdivisions — and match the card to that number. VRAM scales with images in flight, not with batch alone.
  • Train with random=0 until a full run survives, then step the input size up deliberately. random changes the memory target mid-run.
  • Keep nvidia-smi open on a second terminal for the whole run. The crash-moment reading picks the cause in seconds.
  • Validate the dataset before training: the missing-file loop, a sample of opened images, label files present. The loader segfaults on bad input instead of reporting it.
  • Fix one toolkit and one matching cuDNN per machine, and rebuild after every change. Version drift is its own crash class.
  • Split the job: train off-line, deploy inference on the line. A training crash should never be able to touch production.
  • If your own inference code shares the GPU with other processes, own the contexts and buffers explicitly — the CUDA context mistakes that follow camera close apply to training machines too.

One environment rule: do not train inside a virtual machine unless the GPU is passed through to it. A virtual display adapter brings its own crash class, as in an HMI black screen traced to a virtual GPU adapter.

If the split between a training machine and a line-side controller needs numbers for your cell, send the cfg and the nvidia-smi output through the contact page — the sizing answer is a page of arithmetic. More debugging at this layer lives on the systems topic page.

Questions

Why does Darknet crash with a segmentation fault instead of saying out of memory?

Old Darknet builds rarely check every CUDA and cuDNN return code on the training path, so a failed allocation surfaces as a plain segmentation fault with a core dump. Watch nvidia-smi during the run: a memory trace that climbs to the card's ceiling and dies is exhaustion. Running the same command under gdb and reading the backtrace separates a memory death from a library death in one run.

Does a CUDA 10.0 label in nvidia-smi force me to upgrade my CUDA 8.0 build?

No. The CUDA Version line shows the newest toolkit the installed driver can run, not a version your build must match. The driver is backward compatible, so an application compiled against toolkit 8.0.62 runs normally on driver 410.78, and the GTX 645 is covered by both. Leave the driver and the toolkit alone while you debug; changing either adds a variable without touching the fault.

What batch and subdivisions should I use when the card runs out of memory?

Keep the memory in flight at batch divided by subdivisions of 1 to 4, and set random=0 while you tune. The framework's own advice for an out-of-memory error is to raise subdivisions while keeping batch at 64, so batch=64 with subdivisions=32 puts 2 images in flight per step. The standard batch=64, subdivisions=8 run assumes a card with 8 GB or more.

Can corrupted images or wrong label files really cause a training segfault?

Yes. Corrupted images are a recorded cause of training-time segmentation faults in Darknet, and missing files hit the loader just as hard. Test every path in train.txt with a file-exists loop, open a sample of the images in a viewer, and check each label file: one integer class followed by four normalized values, five numbers per line.

Where should the training job run if our floor machines are small?

Off the line. A quad-GPU AI training server keeps training inside your network, and the trained model deploys as inference: a single-card AI inference terminal for a small cell, a dual-card one for more cameras, or a vision controller that also carries camera acquisition. Inference runs at a fraction of training memory because there is no backward pass and no random resize.