Download utils/create_lmdb_iterative.py from Cccccz/Causal-Forcing: direct link, hf CLI and curl.
- Browser
- Download file 3.69 kB
-
https://huggingface.co/Cccccz/Causal-Forcing/resolve/main/utils/create_lmdb_iterative.py
- Command line
-
hf download hf://Cccccz/Causal-Forcing/utils/create_lmdb_iterative.py
-
curl -L -o create_lmdb_iterative.py https://huggingface.co/Cccccz/Causal-Forcing/resolve/main/utils/create_lmdb_iterative.py
3.69 kB
| from tqdm import tqdm | |
| import numpy as np | |
| import argparse | |
| import torch | |
| import lmdb | |
| import glob | |
| import os | |
| def store_arrays_to_lmdb(env, arrays_dict, start_index=0): | |
| """ | |
| Store rows of multiple numpy arrays in a single LMDB. | |
| Each row is stored separately with a naming convention. | |
| """ | |
| with env.begin(write=True) as txn: | |
| for array_name, array in arrays_dict.items(): | |
| for i, row in enumerate(array): | |
| # Convert row to bytes | |
| if isinstance(row, str): | |
| row_bytes = row.encode() | |
| else: | |
| row_bytes = row.tobytes() | |
| data_key = f'{array_name}_{start_index + i}_data'.encode() | |
| txn.put(data_key, row_bytes) | |
| def get_array_shape_from_lmdb(env, array_name): | |
| with env.begin() as txn: | |
| image_shape = txn.get(f"{array_name}_shape".encode()).decode() | |
| image_shape = tuple(map(int, image_shape.split())) | |
| return image_shape | |
| def process_data_dict(data_dict, seen_prompts): | |
| output_dict = {} | |
| all_videos = [] | |
| all_prompts = [] | |
| for prompt, video in data_dict.items(): | |
| if prompt in seen_prompts: | |
| continue | |
| else: | |
| seen_prompts.add(prompt) | |
| video = video.half().numpy() | |
| all_videos.append(video) | |
| all_prompts.append(prompt) | |
| if len(all_videos) == 0: | |
| return {"latents": np.array([]), "prompts": np.array([])} | |
| all_videos = np.concatenate(all_videos, axis=0) | |
| output_dict['latents'] = all_videos | |
| output_dict['prompts'] = np.array(all_prompts) | |
| return output_dict | |
| def retrieve_row_from_lmdb(lmdb_env, array_name, dtype, row_index, shape=None): | |
| """ | |
| Retrieve a specific row from a specific array in the LMDB. | |
| """ | |
| data_key = f'{array_name}_{row_index}_data'.encode() | |
| with lmdb_env.begin() as txn: | |
| row_bytes = txn.get(data_key) | |
| if dtype == str: | |
| array = row_bytes.decode() | |
| else: | |
| array = np.frombuffer(row_bytes, dtype=dtype) | |
| if shape is not None and len(shape) > 0: | |
| array = array.reshape(shape) | |
| return array | |
| def main(): | |
| """ | |
| Aggregate all ode pairs inside a folder into a lmdb dataset. | |
| Each pt file should contain a (key, value) pair representing a | |
| video's ODE trajectories. | |
| """ | |
| parser = argparse.ArgumentParser() | |
| parser.add_argument("--data_path", type=str, | |
| required=True, help="path to ode pairs") | |
| parser.add_argument("--lmdb_path", type=str, | |
| required=True, help="path to lmdb") | |
| args = parser.parse_args() | |
| all_files = sorted(glob.glob(os.path.join(args.data_path, "*.pt"))) | |
| # figure out the maximum map size needed | |
| total_array_size = 5000000000000 # adapt to your need, set to 5TB by default | |
| env = lmdb.open(args.lmdb_path, map_size=total_array_size * 2) | |
| counter = 0 | |
| seen_prompts = set() # for deduplication | |
| for index, file in tqdm(enumerate(all_files)): | |
| # read from disk | |
| data_dict = torch.load(file) | |
| data_dict = process_data_dict(data_dict, seen_prompts) | |
| # write to lmdb file | |
| store_arrays_to_lmdb(env, data_dict, start_index=counter) | |
| counter += len(data_dict['prompts']) | |
| # save each entry's shape to lmdb | |
| with env.begin(write=True) as txn: | |
| for key, val in data_dict.items(): | |
| print(key, val) | |
| array_shape = np.array(val.shape) | |
| array_shape[0] = counter | |
| shape_key = f"{key}_shape".encode() | |
| shape_str = " ".join(map(str, array_shape)) | |
| txn.put(shape_key, shape_str.encode()) | |
| if __name__ == "__main__": | |
| main() | |