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/decoding.py from easylearning/FutureWorlds: direct link, hf CLI and curl.
- Browser
- Download file 4.11 kB
-
https://huggingface.co/easylearning/FutureWorlds/resolve/main/code/src/futureworlds/decoding.py
- Command line
-
hf download hf://easylearning/FutureWorlds/code/src/futureworlds/decoding.py
-
curl -L -o decoding.py https://huggingface.co/easylearning/FutureWorlds/resolve/main/code/src/futureworlds/decoding.py
4.11 kB
| """Fixed-length, constrained HF beam search and independent numerical checks.""" | |
| import torch | |
| from transformers import GenerationConfig, LogitsProcessor, LogitsProcessorList | |
| class VisualTokensOnly(LogitsProcessor): | |
| def __init__(self, valid_size): | |
| self.valid_size = valid_size | |
| def __call__(self, input_ids, scores): | |
| scores = scores.clone() | |
| scores[:, self.valid_size:] = -torch.inf | |
| return scores | |
| def beam_decode(model, prefix, width=4, steps=80, valid_size=4375): | |
| config = GenerationConfig( | |
| do_sample=False, num_beams=width, num_return_sequences=width, | |
| max_new_tokens=steps, min_new_tokens=steps, | |
| eos_token_id=None, bos_token_id=None, pad_token_id=0, | |
| length_penalty=0.0 if width > 1 else 1.0, early_stopping=False, renormalize_logits=True, | |
| repetition_penalty=1.0, no_repeat_ngram_size=0, | |
| use_cache=True, return_dict_in_generate=True, output_scores=True, | |
| ) | |
| result = model.generate( | |
| input_ids=prefix, attention_mask=torch.ones_like(prefix), | |
| generation_config=config, | |
| logits_processor=LogitsProcessorList([VisualTokensOnly(valid_size)]), | |
| eos_token_id=None, bos_token_id=None, | |
| forced_bos_token_id=None, forced_eos_token_id=None, | |
| ) | |
| candidates = result.sequences[:, prefix.shape[1]:] | |
| assert candidates.shape == (width,steps) | |
| assert int(candidates.min()) >= 0 and int(candidates.max()) < valid_size | |
| assert len({tuple(x) for x in candidates.tolist()}) == width | |
| transitions = model.compute_transition_scores( | |
| result.sequences, result.scores, getattr(result,'beam_indices',None), | |
| normalize_logits=False, | |
| ) | |
| assert transitions.shape == (width,steps) and torch.isfinite(transitions).all() | |
| sums = transitions.sum(-1) | |
| scores = result.sequences_scores if width > 1 else sums | |
| error = float((sums-scores).abs().max()) | |
| assert torch.allclose(sums,scores,rtol=0,atol=2e-4), error | |
| assert torch.all(scores[:-1] >= scores[1:]) | |
| return candidates, scores, {'beam_width':width,'tokens_per_frame':steps, | |
| 'selected_index':0,'candidate_scores':scores.tolist(), | |
| 'score_reconstruction_max_error':error, | |
| 'score_definition':'Sum of log probabilities renormalized over valid visual tokens only; no length penalty or GT/image reward.'} | |
| def independent_check(): | |
| from transformers import LlamaConfig, LlamaForCausalLM | |
| torch.manual_seed(3719) | |
| model = LlamaForCausalLM(LlamaConfig(vocab_size=8,hidden_size=32, | |
| intermediate_size=48,num_hidden_layers=2,num_attention_heads=4, | |
| num_key_value_heads=4,max_position_embeddings=128, | |
| eos_token_id=2,bos_token_id=1,pad_token_id=0, | |
| attention_dropout=0.0)).float().eval() | |
| prefix = torch.tensor([[6,1,3]],dtype=torch.long) | |
| reports=[] | |
| for width in [1,4]: | |
| beams=[([],0.0)] | |
| for _ in range(4): | |
| expanded=[] | |
| for seq,score in beams: | |
| x=torch.tensor([prefix[0].tolist()+seq],dtype=torch.long) | |
| probs=model(input_ids=x,use_cache=False).logits[0,-1,:5].log_softmax(-1) | |
| expanded.extend((seq+[token],score+float(probs[token])) for token in range(5)) | |
| beams=sorted(expanded,key=lambda item:item[1],reverse=True)[:width] | |
| ids,scores,meta=beam_decode(model,prefix,width=width,steps=4,valid_size=5) | |
| expected=torch.tensor([seq for seq,_ in beams],dtype=torch.long) | |
| expected_scores=torch.tensor([score for _,score in beams]) | |
| assert torch.equal(ids,expected),(width,ids,expected) | |
| assert torch.allclose(scores,expected_scores,rtol=0,atol=2e-5) | |
| reports.append({'width':width,'matches_independent_uncached_search':True, | |
| 'max_score_error':float((scores-expected_scores).abs().max())}) | |
| return {'tests':reports,'eos_disabled':True,'valid_token_constraint_checked':True,'complete':True} | |
| if __name__ == '__main__': | |
| import json, transformers | |
| print(json.dumps({'transformers':transformers.__version__,**independent_check()})) | |