Limits of PyTorch DataLoader multiprocessing start‑method for CUDA workloads
0 reputation · 08 Aug 2020, 01:42 UTC
0 reputation · 08 Aug 2020, 01:42 UTC
Goal: assess whether the forkserver start method can be employed with PyTorch DataLoader workers to avoid per‑worker CUDA context re‑initialization while maintaining safe GPU usage in distributed training.
Constraints: the official documentation warns that fork‑ing a process holding CUDA resources is unsafe, and there is no stable API for forkserver in PyTorch 2.2; using spawn incurs noticeable startup overhead and possible OOM when the main process already holds large GPU tensors.
Questions: Is there a supported way to enable forkserver start method before CUDA initialization in PyTorch 2.2? What are the concrete risks of invoking torch.multiprocessing.set_start_method('forkserver', force=True) after CUDA tensors have been created? Does the PyTorch roadmap include a stable forkserver option for CUDA workloads?
32775 reputation · 08 Aug 2020, 05:53 UTC
As of PyTorch 2.2 there is no officially stable API for the forkserver start method when using CUDA. You can attempt to set it before any CUDA initialization, but the call may fail or be unsupported on some platforms. The only method guaranteed to work safely with CUDA workers is spawn.
fork, spawn, and forkserver.fork is unsafe with CUDA because forking a process that holds CUDA resources can corrupt the driver state.spawn creates a brand‑new process, guaranteeing a fresh CUDA context in each worker; it is the only method that is reliably safe for CUDA workloads.forkserver behaves like spawn but starts a dedicated server process first. It is safe for CUDA where available, but it is not guaranteed to exist on all systems (e.g., Windows) and is not marked as a stable API in PyTorch 2.2.torch.multiprocessing.set_start_method after any multiprocessing activity (including after CUDA tensors have been created) raises a RuntimeError.If you invoke torch.multiprocessing.set_start_method('forkserver', force=True) after CUDA tensors exist in the parent process, the server process that forkserver creates will have been forked after CUDA initialization. Although the workers themselves are spawned from that server, the inherited CUDA context can lead to undefined behavior, driver crashes, or out‑of‑memory errors. The safest approach is to set the start method before any CUDA operation and before creating the DataLoader.
torch or immediately after:import torch
try:
torch.multiprocessing.set_start_method('forkserver', force=True)
except ValueError as e:
# Already set or not supported
print('Cannot set forkserver:', e)
num_workers>0 (optionally pass multiprocessing_context=torch.multiprocessing.get_context('forkserver')).print(torch.multiprocessing.get_start_method()) # should show 'forkserver'
__getitem__), you can safely create CUDA tensors; each worker will have its own context.The recommendation changes if you are running on Windows, where forkserver is not available. In that case you must use spawn. Please confirm your operating system if you are unsure whether forkserver can be attempted.
Use comments to ask for clarification. Post a solution as an answer.
32,775 reputation · 08 Aug 2020, 04:41 UTC
One practical boundary to keep in mind is the ordering relative to DataLoader construction. The start method must be set before any CUDA initialization and before the DataLoader is instantiated, because the first iteration will start workers immediately. If the server process is forked after the main process has touched the GPU, the server inherits that CUDA state even though workers are later forked from the server.
With PyTorch 2.2 the forkserver path remains platform-dependent and not marked stable for CUDA. A conservative check is to set the method at program entry, confirm no CUDA tensors exist yet, and verify workers are children of the forkserver process rather than the main process. Roadmap status for a stable forkserver option for CUDA workloads is not confirmed in current releases.