mirror of
https://github.com/hpcaitech/Open-Sora.git
synced 2026-05-21 11:59:01 +02:00
save
This commit is contained in:
commit
b9094ece10
|
|
@ -20,7 +20,7 @@ Open-Sora not only democratizes access to advanced video generation techniques,
|
|||
streamlined and user-friendly platform that simplifies the complexities of video generation.
|
||||
With Open-Sora, our goal is to foster innovation, creativity, and inclusivity within the field of content creation.
|
||||
|
||||
[[中文文档]](/docs/zh_CN/README.md) [[潞晨云部署视频教程]](https://www.bilibili.com/video/BV141421R7Ag)
|
||||
[[中文文档](/docs/zh_CN/README.md)] [[潞晨云](https://cloud.luchentech.com/)|[OpenSora镜像](https://cloud.luchentech.com/doc/docs/image/open-sora/)|[视频教程](https://www.bilibili.com/video/BV1ow4m1e7PX/?vd_source=c6b752764cd36ff0e535a768e35d98d2)]
|
||||
|
||||
## 📰 News
|
||||
|
||||
|
|
@ -38,8 +38,7 @@ With Open-Sora, our goal is to foster innovation, creativity, and inclusivity wi
|
|||
|
||||
## 🎥 Latest Demo
|
||||
|
||||
🔥 You can experience Open-Sora on our [🤗 Gradio application on Hugging Face](https://huggingface.co/spaces/hpcai-tech/open-sora). More samples are available in our [Gallery](https://hpcaitech.github.io/Open-Sora/).
|
||||
|
||||
🔥 You can experience Open-Sora on our [🤗 Gradio application on Hugging Face](https://huggingface.co/spaces/hpcai-tech/open-sora). More samples and corresponding prompts are available in our [Gallery](https://hpcaitech.github.io/Open-Sora/).
|
||||
|
||||
| **4s 720×1280** | **4s 720×1280** | **4s 720×1280** |
|
||||
| ---------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
|
|
@ -47,7 +46,6 @@ With Open-Sora, our goal is to foster innovation, creativity, and inclusivity wi
|
|||
| [<img src="assets/demo/v1.2/sample_0052.gif" width="">](https://github.com/hpcaitech/Open-Sora/assets/99191637/644bf938-96ce-44aa-b797-b3c0b513d64c) | [<img src="assets/demo/v1.2/sample_1719.gif" width="">](https://github.com/hpcaitech/Open-Sora/assets/99191637/272d88ac-4b4a-484d-a665-8d07431671d0) | [<img src="assets/demo/v1.2/sample_0002.gif" width="">](https://github.com/hpcaitech/Open-Sora/assets/99191637/ebbac621-c34e-4bb4-9543-1c34f8989764) |
|
||||
| [<img src="assets/demo/v1.2/sample_0011.gif" width="">](https://github.com/hpcaitech/Open-Sora/assets/99191637/a1e3a1a3-4abd-45f5-8df2-6cced69da4ca) | [<img src="assets/demo/v1.2/sample_0004.gif" width="">](https://github.com/hpcaitech/Open-Sora/assets/99191637/d6ce9c13-28e1-4dff-9644-cc01f5f11926) | [<img src="assets/demo/v1.2/sample_0061.gif" width="">](https://github.com/hpcaitech/Open-Sora/assets/99191637/561978f8-f1b0-4f4d-ae7b-45bec9001b4a) |
|
||||
|
||||
|
||||
<details>
|
||||
<summary>OpenSora 1.1 Demo</summary>
|
||||
|
||||
|
|
|
|||
|
|
@ -19,14 +19,12 @@ model = dict(
|
|||
qk_norm=True,
|
||||
enable_flash_attn=True,
|
||||
enable_layernorm_kernel=True,
|
||||
force_huggingface=True,
|
||||
)
|
||||
vae = dict(
|
||||
type="OpenSoraVAE_V1_2",
|
||||
from_pretrained="hpcai-tech/OpenSora-VAE-v1.2",
|
||||
micro_frame_size=17,
|
||||
micro_batch_size=4,
|
||||
force_huggingface=True,
|
||||
)
|
||||
text_encoder = dict(
|
||||
type="t5",
|
||||
|
|
|
|||
44
configs/opensora-v1-2/inference/sample_hf.py
Normal file
44
configs/opensora-v1-2/inference/sample_hf.py
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
resolution = "240p"
|
||||
aspect_ratio = "9:16"
|
||||
num_frames = 51
|
||||
fps = 24
|
||||
frame_interval = 1
|
||||
save_fps = 24
|
||||
|
||||
save_dir = "./samples/samples/"
|
||||
seed = 42
|
||||
batch_size = 1
|
||||
multi_resolution = "STDiT2"
|
||||
dtype = "bf16"
|
||||
condition_frame_length = 5
|
||||
align = 5
|
||||
|
||||
model = dict(
|
||||
type="STDiT3-XL/2",
|
||||
from_pretrained="hpcai-tech/OpenSora-STDiT-v3",
|
||||
qk_norm=True,
|
||||
enable_flash_attn=True,
|
||||
enable_layernorm_kernel=True,
|
||||
force_huggingface=True,
|
||||
)
|
||||
vae = dict(
|
||||
type="OpenSoraVAE_V1_2",
|
||||
from_pretrained="hpcai-tech/OpenSora-VAE-v1.2",
|
||||
micro_frame_size=17,
|
||||
micro_batch_size=4,
|
||||
force_huggingface=True,
|
||||
)
|
||||
text_encoder = dict(
|
||||
type="t5",
|
||||
from_pretrained="DeepFloyd/t5-v1_1-xxl",
|
||||
model_max_length=300,
|
||||
)
|
||||
scheduler = dict(
|
||||
type="rflow",
|
||||
use_timestep_transform=True,
|
||||
num_sampling_steps=30,
|
||||
cfg_scale=7.0,
|
||||
)
|
||||
|
||||
aes = 6.5
|
||||
flow = None
|
||||
|
|
@ -43,7 +43,7 @@ DEFAULT_BS=1
|
|||
# called inside run_video_b
|
||||
function run_image() { # 14min
|
||||
# 1.1 1024x1024
|
||||
eval $CMD --ckpt-path $CKPT --prompt-path assets/texts/t2i_samples.txt --save-dir $OUTPUT --num-frames 1 --resolution 1024 --aspect_ratio 1:1 --sample-name image_1024_1_1 --batch-size $DEFAULT_BS
|
||||
eval $CMD --ckpt-path $CKPT --prompt-path assets/texts/t2i_samples.txt --save-dir $OUTPUT --num-frames 1 --resolution 1024 --aspect-ratio 1:1 --sample-name image_1024_1_1 --batch-size $DEFAULT_BS
|
||||
|
||||
# 1.2 240x426
|
||||
eval $CMD --ckpt-path $CKPT --prompt-path assets/texts/t2i_samples.txt --save-dir $OUTPUT --num-frames 1 --resolution 240p --aspect-ratio 9:16 --sample-name image_240p_9_16 --end-index 3 --batch-size $DEFAULT_BS
|
||||
|
|
|
|||
|
|
@ -89,18 +89,22 @@ def read_video_av(
|
|||
video_frames = np.zeros((total_frames, height, width, 3), dtype=np.uint8)
|
||||
|
||||
# == read ==
|
||||
# TODO: The reading has memory leak (4G for 8 workers 1 GPU)
|
||||
container = av.open(filename, metadata_errors="ignore")
|
||||
assert container.streams.video is not None
|
||||
video_frames = _read_from_stream(
|
||||
video_frames,
|
||||
container,
|
||||
start_pts,
|
||||
end_pts,
|
||||
pts_unit,
|
||||
container.streams.video[0],
|
||||
{"video": 0},
|
||||
)
|
||||
try:
|
||||
# TODO: The reading has memory leak (4G for 8 workers 1 GPU)
|
||||
container = av.open(filename, metadata_errors="ignore")
|
||||
assert container.streams.video is not None
|
||||
video_frames = _read_from_stream(
|
||||
video_frames,
|
||||
container,
|
||||
start_pts,
|
||||
end_pts,
|
||||
pts_unit,
|
||||
container.streams.video[0],
|
||||
{"video": 0},
|
||||
filename=filename,
|
||||
)
|
||||
except av.AVError as e:
|
||||
print(f"[Warning] Error while reading video {filename}: {e}")
|
||||
|
||||
vframes = torch.from_numpy(video_frames).clone()
|
||||
del video_frames
|
||||
|
|
@ -120,6 +124,7 @@ def _read_from_stream(
|
|||
pts_unit: str,
|
||||
stream: "av.stream.Stream",
|
||||
stream_name: Dict[str, Optional[Union[int, Tuple[int, ...], List[int]]]],
|
||||
filename: Optional[str] = None,
|
||||
) -> List["av.frame.Frame"]:
|
||||
|
||||
if pts_unit == "sec":
|
||||
|
|
@ -159,26 +164,28 @@ def _read_from_stream(
|
|||
try:
|
||||
# TODO check if stream needs to always be the video stream here or not
|
||||
container.seek(seek_offset, any_frame=False, backward=True, stream=stream)
|
||||
except av.AVError:
|
||||
# TODO add some warnings in this case
|
||||
# print("Corrupted file?", container.name)
|
||||
except av.AVError as e:
|
||||
print(f"[Warning] Error while seeking video {filename}: {e}")
|
||||
return []
|
||||
|
||||
# == main ==
|
||||
buffer_count = 0
|
||||
frames_pts = []
|
||||
cnt = 0
|
||||
for _idx, frame in enumerate(container.decode(**stream_name)):
|
||||
frames_pts.append(frame.pts)
|
||||
video_frames[cnt] = frame.to_rgb().to_ndarray()
|
||||
cnt += 1
|
||||
if cnt >= len(video_frames):
|
||||
break
|
||||
if frame.pts >= end_offset:
|
||||
if should_buffer and buffer_count < max_buffer_size:
|
||||
buffer_count += 1
|
||||
continue
|
||||
break
|
||||
try:
|
||||
for _idx, frame in enumerate(container.decode(**stream_name)):
|
||||
frames_pts.append(frame.pts)
|
||||
video_frames[cnt] = frame.to_rgb().to_ndarray()
|
||||
cnt += 1
|
||||
if cnt >= len(video_frames):
|
||||
break
|
||||
if frame.pts >= end_offset:
|
||||
if should_buffer and buffer_count < max_buffer_size:
|
||||
buffer_count += 1
|
||||
continue
|
||||
break
|
||||
except av.AVError as e:
|
||||
print(f"[Warning] Error while reading video {filename}: {e}")
|
||||
|
||||
# garbage collection for thread leakage
|
||||
container.close()
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import numpy as np
|
|||
import torch
|
||||
import torch.distributed as dist
|
||||
import torch.nn as nn
|
||||
import torch.nn.functional as F
|
||||
from einops import rearrange
|
||||
from rotary_embedding_torch import RotaryEmbedding
|
||||
from timm.models.layers import DropPath
|
||||
|
|
@ -361,6 +362,19 @@ class STDiT3(PreTrainedModel):
|
|||
# === get pos embed ===
|
||||
_, _, Tx, Hx, Wx = x.size()
|
||||
T, H, W = self.get_dynamic_size(x)
|
||||
|
||||
# adjust for sequence parallelism
|
||||
# we need to ensure H * W is divisible by sequence parallel size
|
||||
# for simplicity, we can adjust the height to make it divisible
|
||||
if self.enable_sequence_parallelism:
|
||||
sp_size = dist.get_world_size(get_sequence_parallel_group())
|
||||
h_pad_size = sp_size - H % sp_size
|
||||
hx_pad_size = h_pad_size * self.patch_size[1]
|
||||
|
||||
# pad x along the H dimension
|
||||
H += h_pad_size
|
||||
x = F.pad(x, (0, 0, 0, hx_pad_size))
|
||||
|
||||
S = H * W
|
||||
base_size = round(S**0.5)
|
||||
resolution_sq = (height[0].item() * width[0].item()) ** 0.5
|
||||
|
|
@ -448,7 +462,7 @@ class STDiT3(PreTrainedModel):
|
|||
@MODELS.register_module("STDiT3-XL/2")
|
||||
def STDiT3_XL_2(from_pretrained=None, **kwargs):
|
||||
force_huggingface = kwargs.pop("force_huggingface", False)
|
||||
if force_huggingface or from_pretrained is not None and not os.path.isdir(from_pretrained):
|
||||
if force_huggingface or from_pretrained is not None and not os.path.exists(from_pretrained):
|
||||
model = STDiT3.from_pretrained(from_pretrained, **kwargs)
|
||||
else:
|
||||
config = STDiT3Config(depth=28, hidden_size=1152, patch_size=(1, 2, 2), num_heads=16, **kwargs)
|
||||
|
|
@ -460,7 +474,8 @@ def STDiT3_XL_2(from_pretrained=None, **kwargs):
|
|||
|
||||
@MODELS.register_module("STDiT3-3B/2")
|
||||
def STDiT3_3B_2(from_pretrained=None, **kwargs):
|
||||
if from_pretrained is not None and not os.path.isdir(from_pretrained):
|
||||
force_huggingface = kwargs.pop("force_huggingface", False)
|
||||
if force_huggingface or from_pretrained is not None and not os.path.exists(from_pretrained):
|
||||
model = STDiT3.from_pretrained(from_pretrained, **kwargs)
|
||||
else:
|
||||
config = STDiT3Config(depth=28, hidden_size=1872, patch_size=(1, 2, 2), num_heads=26, **kwargs)
|
||||
|
|
|
|||
|
|
@ -277,7 +277,7 @@ def OpenSoraVAE_V1_2(
|
|||
scale=scale,
|
||||
)
|
||||
|
||||
if force_huggingface or (from_pretrained is not None and not os.path.isdir(from_pretrained)):
|
||||
if force_huggingface or (from_pretrained is not None and not os.path.exists(from_pretrained)):
|
||||
model = VideoAutoencoderPipeline.from_pretrained(from_pretrained, **kwargs)
|
||||
else:
|
||||
config = VideoAutoencoderPipelineConfig(**kwargs)
|
||||
|
|
|
|||
Loading…
Reference in a new issue