(datasets, queue, preprocess_media_file_fn, num_text_encoders, regenerate_cache, trust_cache, caching_batch_size)
| 1045 | |
| 1046 | |
| 1047 | def _cache_fn(datasets, queue, preprocess_media_file_fn, num_text_encoders, regenerate_cache, trust_cache, caching_batch_size): |
| 1048 | # Dataset map() starts a bunch of processes. Make sure torch uses a limited number of threads |
| 1049 | # to avoid CPU contention. |
| 1050 | # TODO: if we ever change Datasets map to use spawn instead of fork, this might not work. |
| 1051 | #torch.set_num_threads(os.cpu_count() // NUM_PROC) |
| 1052 | # HF Datasets map can randomly hang if this is greater than one (???) |
| 1053 | # See https://github.com/pytorch/pytorch/issues/10996 |
| 1054 | # Alternatively, we could try fixing this by using spawn instead of fork. |
| 1055 | torch.set_num_threads(1) |
| 1056 | |
| 1057 | for ds in datasets: |
| 1058 | ds.cache_metadata(regenerate_cache=regenerate_cache, trust_cache=trust_cache) |
| 1059 | |
| 1060 | pipes = {} |
| 1061 | |
| 1062 | def latents_map_fn(example, rank): |
| 1063 | is_edit_dataset = ('control_file' in example) |
| 1064 | first_size_bucket = example['size_bucket'][0] |
| 1065 | tensors_and_masks = [] |
| 1066 | image_specs = [] |
| 1067 | captions = [] |
| 1068 | control_tensors_and_masks = [] |
| 1069 | for i, (image_spec, mask_path, size_bucket, caption) in enumerate( |
| 1070 | zip(example['image_spec'], example['mask_file'], example['size_bucket'], example['caption']) |
| 1071 | ): |
| 1072 | assert size_bucket == first_size_bucket |
| 1073 | items = preprocess_media_file_fn(image_spec, mask_path, size_bucket) |
| 1074 | tensors_and_masks.extend(items) |
| 1075 | image_specs.extend([image_spec] * len(items)) |
| 1076 | captions.extend([caption] * len(items)) |
| 1077 | if is_edit_dataset: |
| 1078 | control_file = example['control_file'][i] |
| 1079 | control_items = preprocess_media_file_fn((None, control_file), None, size_bucket) |
| 1080 | assert len(control_items) == 1 |
| 1081 | assert len(items) == 1 |
| 1082 | control_tensors_and_masks.append(control_items[0]) |
| 1083 | else: |
| 1084 | control_tensors_and_masks.append(None) |
| 1085 | |
| 1086 | if len(tensors_and_masks) == 0: |
| 1087 | assert not is_edit_dataset |
| 1088 | return {'latents': [], 'mask': [], 'image_spec': [], 'caption': []} |
| 1089 | |
| 1090 | caching_batch_size = len(example['image_spec']) |
| 1091 | results = defaultdict(list) |
| 1092 | for i in range(0, len(tensors_and_masks), caching_batch_size): |
| 1093 | tensor = torch.stack([t[0] for t in tensors_and_masks[i:i+caching_batch_size]]) |
| 1094 | c_tensor = torch.stack([t[0] for t in control_tensors_and_masks[i:i+caching_batch_size]]) if is_edit_dataset else None |
| 1095 | if rank not in pipes: |
| 1096 | pipes[rank] = mp.Pipe(duplex=False) |
| 1097 | parent_conn, child_conn = pipes[rank] |
| 1098 | queue.put((0, tensor, c_tensor, child_conn)) |
| 1099 | result = parent_conn.recv() # dict |
| 1100 | for k, v in result.items(): |
| 1101 | results[k].append(v) |
| 1102 | # concatenate the list of tensors at each key into one batched tensor |
| 1103 | for k, v in results.items(): |
| 1104 | results[k] = torch.cat(v) |
nothing calls this directly
no test coverage detected