Instructions to use easylearning/FutureWorlds with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Diffusers
How to use easylearning/FutureWorlds with Diffusers:
pip install -U diffusers transformers accelerate
import torch from diffusers import DiffusionPipeline # switch to "mps" for apple devices pipe = DiffusionPipeline.from_pretrained("easylearning/FutureWorlds", dtype=torch.bfloat16, device_map="cuda") prompt = "Astronaut in a jungle, cold color palette, muted colors, detailed, 8k" image = pipe(prompt).images[0] - Notebooks
- Google Colab
- Kaggle
File size: 3,660 Bytes
64b9802 | 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 | """GT motion-proxy ROI and GT-referenced dynamics. No actor/search sees future GT."""
import torch
import torch.nn.functional as F
from .rewards import CodecWorker
from .batch import TensorBatch
@torch.no_grad()
def motion_regions(truth,previous):
"""Shared across candidates: GT-derived, never shrinks after predicted disappearance."""
prev=torch.cat([previous[None],truth[:-1]],0)
motion=(truth-prev).abs().mean(1,keepdim=True)
thresholds=motion.flatten(1).quantile(.90,dim=1).clamp_min(.02)
masks=(motion>thresholds[:,None,None,None]).float()
masks=F.max_pool2d(masks,11,stride=1,padding=5)
fallback=masks.mean((1,2,3))<.01
masks[fallback]=1
crops=[];height,width=truth.shape[-2:]
for mask in masks:
y,x=torch.where(mask[0]>0)
y0,y1=int(y.min()),int(y.max())+1;x0,x1=int(x.min()),int(x.max())+1
cy=(y0+y1)//2;cx=(x0+x1)//2
h=max(64,y1-y0);w=max(64,x1-x0)
y0=max(0,min(cy-h//2,height-h));x0=max(0,min(cx-w//2,width-w))
crops.append((y0,min(height,y0+h),x0,min(width,x0+w)))
return masks,crops,fallback
class MotionReward:
def __init__(self,codec,perceptual,scales=None,alpha=.5,beta=.25):
self.worker=CodecWorker(codec,perceptual);self.perceptual=perceptual
self.scales=scales or dict(global_scale=1.,roi_scale=1.,delta_scale=1.)
self.alpha=alpha;self.beta=beta
@torch.no_grad()
def components(self,pred,pixels):
truth=pixels[0,2:];previous=pixels[0,1]
n,h=pred.shape[:2];real=truth[None].expand(n,-1,-1,-1,-1)
mae=(pred-real).abs().mean((2,3,4))
percept=self.worker.perceptual_loss(TensorBatch(dict(real=real,pred=pred))).batch['perceptual_loss']
masks,crops,fallback=motion_regions(truth,previous)
roi_mae=((pred-real).abs()*masks).sum((2,3,4))/(3*masks.sum((1,2,3)))[None]
roi_percept=torch.empty((n,h),device=pred.device)
for t,(y0,y1,x0,x1) in enumerate(crops):
r=truth[t:t+1,:,y0:y1,x0:x1]
for start in range(0,n,2):
pp=pred[start:start+2,t,:,y0:y1,x0:x1]
roi_percept[start:start+len(pp),t]=self.perceptual(pp*2-1,r.expand(len(pp),-1,-1,-1)*2-1).flatten()
pred_prev=torch.cat([previous[None,None].expand(n,1,-1,-1,-1),pred[:,:-1]],1)
true_prev=torch.cat([previous[None],truth[:-1]],0)
delta=((pred-pred_prev)-(truth-true_prev)[None]).abs().mean((2,3,4))
return dict(mae=mae,lpips=percept,global_loss=mae+percept,
roi_loss=roi_mae+roi_percept,roi_mae=roi_mae,roi_lpips=roi_percept,
delta_loss=delta,roi_fallback=fallback,roi_area=masks.mean((1,2,3)))
def combine(self,c):
s=self.scales
return -(c['global_loss']+self.alpha*s['global_scale']/s['roi_scale']*c['roi_loss']+
self.beta*s['global_scale']/s['delta_scale']*c['delta_loss']).mean(-1)
@torch.no_grad()
def decode(self,frames,context):
codes=torch.stack([f['response'] for f in frames],1)
assert codes.min()>=0 and codes.max()<4375
return self.worker.detokenize(TensorBatch(dict(tokens=codes,ctx_tokens=context.expand(len(codes),-1,-1))),None).batch['pixels'][:,1:]
@torch.no_grad()
def __call__(self,frames,context,actions,pixels):
c=self.components(self.decode(frames,context),pixels)
reward=self.combine(c)
assert torch.isfinite(reward).all()
metrics={'critic/recon_loss/mean':float(c['mae'].mean()),'critic/perceptual_loss/mean':float(c['lpips'].mean())}
metrics.update({k:float(v.float().mean()) for k,v in c.items()})
return reward,metrics
|