Re-implementation of the SmartCache mechanism in NVIDIA Clara-train SDK. At any time, the cache pool only keeps a subset of the whole dataset. In each epoch, only the items in the cache are used for training. This ensures that data needed for training is readily available, keeping G
| 966 | |
| 967 | |
| 968 | class SmartCacheDataset(Randomizable, CacheDataset): |
| 969 | """ |
| 970 | Re-implementation of the SmartCache mechanism in NVIDIA Clara-train SDK. |
| 971 | At any time, the cache pool only keeps a subset of the whole dataset. In each epoch, only the items |
| 972 | in the cache are used for training. This ensures that data needed for training is readily available, |
| 973 | keeping GPU resources busy. Note that cached items may still have to go through a non-deterministic |
| 974 | transform sequence before being fed to GPU. At the same time, another thread is preparing replacement |
| 975 | items by applying the transform sequence to items not in cache. Once one epoch is completed, Smart |
| 976 | Cache replaces the same number of items with replacement items. |
| 977 | Smart Cache uses a simple `running window` algorithm to determine the cache content and replacement items. |
| 978 | Let N be the configured number of objects in cache; and R be the number of replacement objects (R = ceil(N * r), |
| 979 | where r is the configured replace rate). |
| 980 | For more details, please refer to: |
| 981 | https://docs.nvidia.com/clara/clara-train-archive/3.1/nvmidl/additional_features/smart_cache.html |
| 982 | If passing slicing indices, will return a PyTorch Subset, for example: `data: Subset = dataset[1:4]`, |
| 983 | for more details, please check: https://pytorch.org/docs/stable/data.html#torch.utils.data.Subset |
| 984 | |
| 985 | For example, if we have 5 images: `[image1, image2, image3, image4, image5]`, and `cache_num=4`, `replace_rate=0.25`. |
| 986 | so the actual training images cached and replaced for every epoch are as below:: |
| 987 | |
| 988 | epoch 1: [image1, image2, image3, image4] |
| 989 | epoch 2: [image2, image3, image4, image5] |
| 990 | epoch 3: [image3, image4, image5, image1] |
| 991 | epoch 3: [image4, image5, image1, image2] |
| 992 | epoch N: [image[N % 5] ...] |
| 993 | |
| 994 | The usage of `SmartCacheDataset` contains 4 steps: |
| 995 | |
| 996 | 1. Initialize `SmartCacheDataset` object and cache for the first epoch. |
| 997 | 2. Call `start()` to run replacement thread in background. |
| 998 | 3. Call `update_cache()` before every epoch to replace training items. |
| 999 | 4. Call `shutdown()` when training ends. |
| 1000 | |
| 1001 | During training call `set_data()` to update input data and recompute cache content, note to call |
| 1002 | `shutdown()` to stop first, then update data and call `start()` to restart. |
| 1003 | |
| 1004 | Note: |
| 1005 | This replacement will not work for below cases: |
| 1006 | 1. Set the `multiprocessing_context` of DataLoader to `spawn`. |
| 1007 | 2. Launch distributed data parallel with `torch.multiprocessing.spawn`. |
| 1008 | 3. Run on windows(the default multiprocessing method is `spawn`) with `num_workers` greater than 0. |
| 1009 | 4. Set the `persistent_workers` of DataLoader to `True` with `num_workers` greater than 0. |
| 1010 | |
| 1011 | If using MONAI workflows, please add `SmartCacheHandler` to the handler list of trainer, |
| 1012 | otherwise, please make sure to call `start()`, `update_cache()`, `shutdown()` during training. |
| 1013 | |
| 1014 | Args: |
| 1015 | data: input data to load and transform to generate dataset for model. |
| 1016 | transform: transforms to execute operations on input data. |
| 1017 | replace_rate: percentage of the cached items to be replaced in every epoch (default to 0.1). |
| 1018 | cache_num: number of items to be cached. Default is `sys.maxsize`. |
| 1019 | will take the minimum of (cache_num, data_length x cache_rate, data_length). |
| 1020 | cache_rate: percentage of cached data in total, default is 1.0 (cache all). |
| 1021 | will take the minimum of (cache_num, data_length x cache_rate, data_length). |
| 1022 | num_init_workers: the number of worker threads to initialize the cache for first epoch. |
| 1023 | If num_init_workers is None then the number returned by os.cpu_count() is used. |
| 1024 | If a value less than 1 is specified, 1 will be used instead. |
| 1025 | num_replace_workers: the number of worker threads to prepare the replacement cache for every epoch. |
no outgoing calls
searching dependent graphs…