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
Download code/src/futureworlds/motion_reward.py from easylearning/FutureWorlds: direct link, hf CLI and curl.
- Browser
- Download file 3.66 kB
-
https://huggingface.co/easylearning/FutureWorlds/resolve/main/code/src/futureworlds/motion_reward.py
- Command line
-
hf download hf://easylearning/FutureWorlds/code/src/futureworlds/motion_reward.py
-
curl -L -o motion_reward.py https://huggingface.co/easylearning/FutureWorlds/resolve/main/code/src/futureworlds/motion_reward.py
3.66 kB
| """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 | |
| 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 | |
| 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) | |
| 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:] | |
| 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 | |