In my understanding, num_workers=1 uses multithreading while num_workers=0 does not.
Using multi-threading means that you need to run the majority of your training loop inside a if __name__ == '__main__': just due to how Python handles multi-threading.
The multi-threading in DataLoader seems to be a bit sensitive as well. Using a 16 thread system, I am only able to run the dataloader on 6-8 threads. Using more threads have previously crashed training randomly.