Instructions to use ProCreations/Image-2.1-Turbo-Calibrated-FP8 with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Diffusers
How to use ProCreations/Image-2.1-Turbo-Calibrated-FP8 with Diffusers:
pip install -U diffusers transformers accelerate
import torch from diffusers import DiffusionPipeline # switch to "mps" for apple devices pipe = DiffusionPipeline.from_pretrained("ProCreations/Image-2.1-Turbo-Calibrated-FP8", 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
- Local Apps Settings
- Draw Things
- DiffusionBee
File size: 4,938 Bytes
ffc54ec | 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 99 100 101 102 103 104 105 106 107 108 109 | """Avoid rebuilding immutable prefix layout during cached image decode."""
import math
import types
import torch
from diffusers.models.modeling_outputs import Transformer2DModelOutput
from diffusers.models.transformers.transformer_qwenimage21 import QwenImage21KVCache
def metadata(model, kw):
cache = kw['kv_cache']
if not hasattr(cache, '_fast_layout'):
mask = kw['img_mask']
repeats = torch.where(mask, 4, 1)[0]
image_pad_mask = torch.repeat_interleave(mask[0], repeats)
shapes = kw['img_shapes']
rope = model.pos_embed(shapes[0], image_pad_mask, device=mask.device)
_, target_mask = model.build_token_metadata(image_pad_mask, shapes[0])
target_tokens = math.prod(shapes[0][-1])
prefix = rope.shape[0] - target_tokens
valid = None
enc_mask = kw.get('encoder_hidden_states_mask')
if enc_mask is not None:
valid = torch.ones(kw['hidden_states'].shape[0], image_pad_mask.shape[0], dtype=torch.bool, device=mask.device)
valid[:, (~image_pad_mask).nonzero(as_tuple=True)[0]] = enc_mask.bool()[:, ~mask[0][:enc_mask.shape[1]]]
valid = valid[:, None, None, :]
cache._fast_layout = (rope[prefix:], target_mask[prefix:], valid, target_tokens)
return cache._fast_layout
def core(model, hidden_states, timestep, cache, layout):
rope, target_mask, attention_mask, target_tokens = layout
# Keep the original img_in shape, including condition-image tokens for edits.
image = model.img_in(hidden_states)
hidden = image[:, -target_tokens:]
timestep = timestep.to(image.dtype)
timestep = torch.cat([timestep, timestep.new_zeros(1)], dim=0)
temb = model.time_text_embed(timestep, image)
modulation = model.modulation(temb)
for i, block in enumerate(model.transformer_blocks):
hidden = block(hidden_states=hidden, modulation=modulation, rotary_emb=rope,
attention_mask=attention_mask, target_token_mask=target_mask,
layer_cache=cache.get_layer(i), kv_cache_mode='cached',
cache_write_slice=None, segments=None, key_valid=None)
hidden = model.norm_out(hidden, temb, target_mask)
return model.proj_out(hidden)
class Graph:
def __init__(self, model, hidden, timestep, cache, layout):
self.hidden = hidden.clone()
self.timestep = timestep.clone()
self.cache = QwenImage21KVCache(len(cache.layer_caches))
for dst, src in zip(self.cache.layer_caches, cache.layer_caches):
dst.store(src.k.clone(), src.v.clone())
self.layout = tuple(x.clone() if isinstance(x, torch.Tensor) else x for x in layout)
stream = torch.cuda.Stream()
stream.wait_stream(torch.cuda.current_stream())
with torch.cuda.stream(stream):
for _ in range(2):
core(model, self.hidden, self.timestep, self.cache, self.layout)
torch.cuda.current_stream().wait_stream(stream)
self.graph = torch.cuda.CUDAGraph()
with torch.cuda.graph(self.graph, stream=stream):
self.output = core(model, self.hidden, self.timestep, self.cache, self.layout)
self.owner = cache
def run(self, hidden, timestep, cache, layout):
self.hidden.copy_(hidden)
self.timestep.copy_(timestep)
if self.owner is not cache:
for dst, src in zip(self.cache.layer_caches, cache.layer_caches):
dst.k.copy_(src.k)
dst.v.copy_(src.v)
for dst, src in zip(self.layout, layout):
if isinstance(dst, torch.Tensor):
dst.copy_(src)
self.owner = cache
self.graph.replay()
return self.output
def dispatch(self, **kw):
if kw.get('kv_cache_mode') != 'cached' or kw.get('attention_kwargs'):
return self._original_forward(**kw)
cache = kw['kv_cache']
layout = metadata(self, kw)
hidden, timestep = kw['hidden_states'], kw['timestep']
if self._fast_use_graph:
key = (tuple(hidden.shape), tuple(cache.get_layer(0).k.shape),
tuple(kw['img_shapes'][0]), layout[2] is not None)
if key not in self._fast_graphs:
if len(self._fast_graphs) >= 2:
self._fast_graphs.pop(next(iter(self._fast_graphs)))
self._fast_graphs[key] = Graph(self, hidden, timestep, cache, layout)
result = self._fast_graphs[key].run(hidden, timestep, cache, layout)
else:
result = core(self, hidden, timestep, cache, layout)
return (result,) if not kw.get('return_dict', True) else Transformer2DModelOutput(sample=result)
def enable(pipe, graph=False):
m = pipe.transformer
if not hasattr(m, '_original_forward'):
m._original_forward = m.forward
m.forward = types.MethodType(dispatch, m)
m._fast_graphs = {}
m._fast_use_graph = graph
return pipe
|