Files
hao-ai-lab-FastVideo/opensora/utils/imagebase_extract_image_feature.py
T
LinB203 b0a9e72008 extract script
Former-commit-id: 4139f2f68ae09695302ce49afdb7318df83cabfd
2024-03-09 01:03:05 +08:00

139 lines
4.3 KiB
Python

# Copyright (c) Meta Platforms, Inc. and affiliates.
# All rights reserved.
# This source code is licensed under the license found in the
# LICENSE file in the root directory of this source tree.
"""
A minimal training script for DiT using PyTorch DDP.
"""
import sys
import imageio
import torch
# the first flag below was False when we tested this script but True makes A100 training a lot faster:
from einops import rearrange
from torchvision.transforms import Compose, Lambda
from tqdm import tqdm
from torch.utils.data.distributed import DistributedSampler
from opensora.dataset import ToTensorVideo, ae_norm, ae_denorm, CenterCropResizeVideo
from opensora.dataset.extract_feature_dataset import ExtractImage2Feature
from opensora.models.ae import getae
torch.backends.cuda.matmul.allow_tf32 = True
torch.backends.cudnn.allow_tf32 = True
from torch.utils.data import DataLoader
import numpy as np
import argparse
import os
import torch.distributed as dist
def main(args):
"""
Trains a new DiT model.
"""
assert torch.cuda.is_available(), "Training currently requires at least one GPU."
# Setup DDP:
dist.init_process_group("nccl")
rank = dist.get_rank()
device = rank % torch.cuda.device_count()
seed = args.global_seed * dist.get_world_size() + rank
torch.manual_seed(seed)
torch.cuda.set_device(device)
print(f"Starting rank={rank}, seed={seed}, world_size={dist.get_world_size()}.")
# Setup a feature folder:
if rank == 0:
os.makedirs(f'{args.vis_path}/{args.features_name}', exist_ok=True)
# Create model:
ae = getae(args).to(device)
# Setup data:
norm_fun = ae_norm[args.ae]
transform = Compose(
[
ToTensorVideo(), # TCHW
CenterCropResizeVideo(args.image_size),
norm_fun,
]
)
dataset = ExtractImage2Feature(args, transform=transform)
sampler = DistributedSampler(
dataset,
num_replicas=dist.get_world_size(),
rank=rank,
shuffle=False,
seed=args.global_seed
)
loader = DataLoader(
dataset,
batch_size=1,
shuffle=False,
sampler=sampler,
num_workers=args.num_workers,
pin_memory=True,
drop_last=True
)
train_steps = 0
for x, path in tqdm(loader):
# x = x
p = path[0].split('.')
p = '.'.join(p[:-1]) + f'_{args.features_name}.npy'
if os.path.exists(p):
continue
with torch.no_grad():
b, _, _, _, _ = x.shape # b t c h w
assert b == 1
x = x.to(device, non_blocking=True)
x = x.transpose(1, 2).contiguous() # B T C H W -> # B C T H W
x = ae.encode(x).cpu() # b t c h w
if train_steps == 0:
b, t, c, h, w = x.shape
samples = rearrange(x, 'b t c h w -> (b t) c h w')
samples_dec = []
samples_ = ae.decode(samples.to(device, non_blocking=True))
samples_dec.append(samples_.cpu())
samples = torch.cat(samples_dec, dim=0)
samples = rearrange(samples, '(b t) c h w -> b t c h w', b=b)
video_ = (ae_denorm[args.ae](samples[0]) * 255).add_(0.5).clamp_(0, 255).to(dtype=torch.uint8).permute(0, 2, 3, 1).contiguous()
imageio.mimwrite(f'{args.vis_path}/{args.features_name}/{train_steps}.mp4', video_, fps=30, quality=9)
x = x.detach().cpu().numpy()[0][0] # (1, 4, 32, 32)
print(3333333, x.shape)
sys.exit()
np.save(p, x)
# y = y.detach().cpu().numpy() # (1,)
# np.save(f'{args.features_path}/{args.features_name}/{train_steps}.npy', y)
train_steps += 1
# print(train_steps)
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("--data-path", type=str, required=True)
parser.add_argument("--ae", type=str, default="stabilityai/sd-vae-ft-mse")
parser.add_argument("--features-name", type=str, default="sky")
parser.add_argument("--vis-path", type=str, default="extract_vis")
parser.add_argument("--global-seed", type=int, default=0)
parser.add_argument("--image-size", type=int, default=512)
parser.add_argument("--num-workers", type=int, default=2)
parser.add_argument("--n-sample", type=int, default=4)
args = parser.parse_args()
main(args)