Instructions to use diffusion-gif/any2ego with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Diffusers
How to use diffusion-gif/any2ego with Diffusers:
pip install -U diffusers transformers accelerate
import torch from diffusers import DiffusionPipeline # switch to "mps" for apple devices pipe = DiffusionPipeline.from_pretrained("fill-in-base-model", dtype=torch.bfloat16, device_map="cuda") pipe.load_lora_weights("diffusion-gif/any2ego") prompt = "Astronaut in a jungle, cold color palette, muted colors, detailed, 8k" image = pipe(prompt).images[0] - Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- Draw Things
File size: 5,005 Bytes
c28ffff | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 | """"""
from pathlib import Path as _Path
import sys as _sys
_bundle_root = _Path(__file__).resolve().parents[1]
_sys.path.insert(0, str(_bundle_root))
from project_paths import project_path as _project_path, env as _env, initialize as _initialize
_initialize(__name__ == '__main__')
from project_paths import seg_mask_root, seg_mask_dir
import os
import sys
import json
import argparse
import numpy as np
import torch
from PIL import Image
HERE = os.path.dirname(os.path.abspath(__file__))
from model_resources import wan_base_root, wan_model_paths, wan_tokenizer_path
VACE = wan_base_root()
DS = _project_path('third_party/DiffSynth-Studio')
EVAL_MANIFEST = _project_path('manifests/eval.json')
MASK_ROOT = seg_mask_root()
PALETTE = np.array([[0, 0, 0], [220, 40, 40], [40, 200, 80]], dtype=np.uint8)
NEG = '色调艳丽,过曝,静态,细节模糊不清,字幕,风格,作品,画作,画面,静止,整体发灰,最差质量,低质量,JPEG压缩残留,丑陋的,残缺的,多余的手指,画得不好的手部,画得不好的脸部,畸形的,毁容的,形态畸形的肢体,手指融合,静止不动的画面,杂乱的背景'
def build_pipe(device, lora_path):
sys.path.insert(0, DS)
sys.path.insert(0, HERE)
from diffsynth.pipelines.wan_video import WanVideoPipeline, ModelConfig
pipe = WanVideoPipeline.from_pretrained(torch_dtype=torch.bfloat16, device=device, model_configs=[ModelConfig(path=path) for path in wan_model_paths(VACE, strict=True)], tokenizer_config=ModelConfig(path=wan_tokenizer_path(VACE, strict=True)))
if lora_path:
pipe.load_lora(pipe.vace, lora_path, alpha=1.0)
print(f'已加载 LoRA: {lora_path}')
return pipe
def load_mask_video(mask_dir, size):
""""""
fs = sorted((f for f in os.listdir(mask_dir) if f.endswith('.png')))
out = []
for f in fs:
m = np.asarray(Image.open(os.path.join(mask_dir, f)))
if m.ndim == 3:
m = m[..., 0]
col = PALETTE[np.clip(m, 0, 2)]
out.append(Image.fromarray(col).resize(size))
return out
def main():
ap = argparse.ArgumentParser()
ap.add_argument('--lora', default=_project_path('checkpoints/generator_hoi/ckpt.safetensors'))
ap.add_argument('--out', default=_project_path('outputs/pred_hoi'))
ap.add_argument('--height', type=int, default=480)
ap.add_argument('--width', type=int, default=480)
ap.add_argument('--steps', type=int, default=50)
ap.add_argument('--cfg_scale', type=float, default=5.0)
ap.add_argument('--vace_scale', type=float, default=1.0)
ap.add_argument('--fps', type=float, default=8.0)
ap.add_argument('--seed', type=int, default=0)
ap.add_argument('--limit', type=int, default=-1)
ap.add_argument('--manifest', default=EVAL_MANIFEST)
ap.add_argument('--mask_root', default=MASK_ROOT, help='外部 seg 预测 mask 根目录:<root>/<clip_id>/ego/*.png')
ap.add_argument('--device', default='cuda')
args = ap.parse_args()
manifest = json.load(open(args.manifest))
if args.limit > 0:
manifest = manifest[:args.limit]
out = os.path.abspath(args.out)
os.makedirs(out, exist_ok=True)
pipe = build_pipe(args.device, args.lora)
size = (args.width, args.height)
print(f'开始 M2 推理, {len(manifest)} 条')
for k, s in enumerate(manifest):
if os.path.isfile(os.path.join(out, s['take_uid'], 'pred.mp4')):
print(f' [skip] 已存在: {s['take_uid']}')
continue
mask_dir = os.path.join(args.mask_root, s['take_uid'], 'ego')
if not os.path.isdir(mask_dir):
print(f' [skip] 无mask: {s['take_name']}')
continue
mask_vid = load_mask_video(mask_dir, size)
nf = len(mask_vid)
ref = Image.open(s['first_frame']).convert('RGB').resize(size)
print(f"[{k + 1}/{len(manifest)}] {s['take_name']} | {nf}帧 | '{s['prompt'][:40]}'")
video = pipe(prompt=s['prompt'], negative_prompt=NEG, vace_video=mask_vid, vace_reference_image=ref, vace_scale=args.vace_scale, height=args.height, width=args.width, num_frames=nf, num_inference_steps=args.steps, cfg_scale=args.cfg_scale, seed=args.seed, tiled=True)
sd = os.path.join(out, s['take_uid'])
os.makedirs(sd, exist_ok=True)
for i, fr in enumerate(video):
Image.fromarray(np.asarray(fr)).save(os.path.join(sd, f'{i:03d}.png'))
try:
from diffsynth.utils.data import save_video
save_video(video, os.path.join(sd, 'pred.mp4'), fps=args.fps, quality=5)
except Exception:
pass
print(f' -> {sd}')
json.dump({'model': 'Wan2.1-VACE-1.3B + HOI-LoRA', 'lora': args.lora, 'height': args.height, 'width': args.width, 'rotate': False, 'vace_scale': args.vace_scale, 'note': 'seg 预测的 ego HOI mask 引导生成'}, open(os.path.join(out, 'infer_config.json'), 'w'), indent=2)
print('完成 ->', out)
if __name__ == '__main__':
main()
|